diff --git a/config.tests/unix/doubleformat.test b/config.tests/unix/doubleformat.test
deleted file mode 100755
index 996855372bc..00000000000
--- a/config.tests/unix/doubleformat.test
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-QMKSPEC=$1
-VERBOSE=$2
-SRCDIR=$3
-OUTDIR=$4
-
-# debuggery
-[ "$VERBOSE" = "yes" ] && echo "Determining floating point word-order... ($*)"
-
-# build and run a test program
-test -d "$OUTDIR/config.tests/unix/doubleformat" || mkdir -p "$OUTDIR/config.tests/unix/doubleformat"
-"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" "$SRCDIR/config.tests/unix/doubleformat/doubleformattest.pro" -o "$OUTDIR/config.tests/unix/doubleformat/Makefile" >/dev/null 2>&1
-cd "$OUTDIR/config.tests/unix/doubleformat"
-
-DOUBLEFORMAT="UNKNOWN"
-[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1
-
-if [ -f ./doubleformattest ]; then
- : # nop
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown floating point format!"
- exit 2
-fi
-
-# LE: strings | grep 0123ABCD0123ABCD
-# BE: strings | grep DCBA3210DCBA3210
-#
-# LE arm-swapped-dword-order: strings | grep ABCD0123ABCD0123
-# BE arm-swapped-dword-order: strings | grep 3210DCBA3210DCBA (untested)
-
-
-if strings ./doubleformattest | grep "0123ABCD0123ABCD" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Normal little endian format"
- DOUBLEFORMAT="LITTLE"
-elif strings ./doubleformattest | grep "ABCD0123ABCD0123" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Swapped little endian format"
- DOUBLEFORMAT="LITTLESWAPPED"
-elif strings ./doubleformattest | grep "DCBA3210DCBA3210" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Normal big endian format"
- DOUBLEFORMAT="BIG"
-elif strings ./doubleformattest | grep "3210DCBA3210DCBA" >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Swapped big endian format"
- DOUBLEFORMAT="BIGSWAPPED"
-fi
-
-# done
-if [ "$DOUBLEFORMAT" = "LITTLE" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using little endian."
- exit 10
-elif [ "$DOUBLEFORMAT" = "BIG" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using big endian."
- exit 11
-elif [ "$DOUBLEFORMAT" = "LITTLESWAPPED" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using swapped little endian."
- exit 12
-elif [ "$DOUBLEFORMAT" = "BIGSWAPPED" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using swapped big endian."
- exit 13
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown floating point format!"
- exit 99
-fi
diff --git a/config.tests/unix/doubleformat/doubleformattest.pro b/config.tests/unix/doubleformat/doubleformattest.pro
deleted file mode 100644
index 7e51deade5b..00000000000
--- a/config.tests/unix/doubleformat/doubleformattest.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES = doubleformattest.cpp
-CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/endian.test b/config.tests/unix/endian.test
deleted file mode 100755
index a662011a27e..00000000000
--- a/config.tests/unix/endian.test
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-QMKSPEC=$1
-VERBOSE=$2
-SRCDIR=$3
-OUTDIR=$4
-QMFLAGS=$5
-
-# debuggery
-[ "$VERBOSE" = "yes" ] && echo "Determining machine byte-order... ($*)"
-
-# build and run a test program
-test -d "$OUTDIR/config.tests/unix/endian" || mkdir -p "$OUTDIR/config.tests/unix/endian"
-"$OUTDIR/bin/qmake" -nocache -spec "$QMKSPEC" "QT_BUILD_TREE=$OUTDIR" $QMFLAGS "$SRCDIR/config.tests/unix/endian/endiantest.pro" -o "$OUTDIR/config.tests/unix/endian/Makefile" >/dev/null 2>&1
-cd "$OUTDIR/config.tests/unix/endian"
-
-
-ENDIAN="UNKNOWN"
-[ "$VERBOSE" = "yes" ] && $MAKE || $MAKE >/dev/null 2>&1
-
-if [ -f ./endiantest.exe ]; then
- binary=./endiantest.exe
-else
- binary=./endiantest
-fi
-
-
-if [ -f $binary ]; then
- : # nop
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown byte order!"
- exit 2
-fi
-
-if strings - $binary | grep LeastSignificantByteFirst >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Found 'LeastSignificantByteFirst' in binary"
- ENDIAN="LITTLE"
-elif strings - $binary | grep MostSignificantByteFirst >/dev/null 2>&1; then
- [ "$VERBOSE" = "yes" ] && echo " Found 'MostSignificantByteFirst' in binary"
- ENDIAN="BIG"
-fi
-
-# make clean as this tests is compiled for both the host and the target
-if [ "$VERBOSE" = "yes" ]; then
- $MAKE distclean
-else
- $MAKE distclean >/dev/null 2>&1
-fi
-
-# done
-if [ "$ENDIAN" = "LITTLE" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using little endian."
- exit 0
-elif [ "$ENDIAN" = "BIG" ]; then
- [ "$VERBOSE" = "yes" ] && echo "Using big endian."
- exit 1
-else
- [ "$VERBOSE" = "yes" ] && echo "Unknown byte order!"
- exit 2
-fi
diff --git a/config.tests/unix/endian/endiantest.pro b/config.tests/unix/endian/endiantest.pro
deleted file mode 100644
index 7b739eb3f2c..00000000000
--- a/config.tests/unix/endian/endiantest.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-SOURCES = endiantest.cpp
-CONFIG -= qt dylib
-mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/iconv/iconv.pro b/config.tests/unix/iconv/iconv.pro
index ec573ce5900..876c6f3589e 100644
--- a/config.tests/unix/iconv/iconv.pro
+++ b/config.tests/unix/iconv/iconv.pro
@@ -1,3 +1,3 @@
SOURCES = iconv.cpp
CONFIG -= qt dylib app_bundle
-mac|win32-g++*|blackberry-*-qcc:LIBS += -liconv
+mac|win32-g++*|qnx-*-qcc:LIBS += -liconv
diff --git a/config.tests/unix/libudev/libudev.pro b/config.tests/unix/libudev/libudev.pro
index 7f571b5a6d6..28b8980e2e3 100644
--- a/config.tests/unix/libudev/libudev.pro
+++ b/config.tests/unix/libudev/libudev.pro
@@ -1,3 +1,4 @@
SOURCES = libudev.cpp
CONFIG -= qt
-LIBS += -ludev
+LIBS += $$QMAKE_LIBS_LIBUDEV
+INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
diff --git a/config.tests/unix/padstring b/config.tests/unix/padstring
deleted file mode 100755
index 283475d0711..00000000000
--- a/config.tests/unix/padstring
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-LEN="$1"
-STR="$2"
-PAD='\0'
-STRLEN=`echo $STR | wc -c`
-RES="$STR"
-
-EXTRALEN=`expr $LEN - $STRLEN`
-while [ "$EXTRALEN" -gt 32 ]; do
- RES="$RES$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD$PAD"
- EXTRALEN=`expr $EXTRALEN - 32`
-done
-while [ "$EXTRALEN" -gt 0 ]; do
- RES="$RES$PAD"
- EXTRALEN=`expr $EXTRALEN - 1`
-done
-cat <] [-prefix-install] [-bindir ] [-libdir
[-iconv] [-no-pch] [-pch] [-no-dbus] [-dbus] [-dbus-linked] [-no-gui]
[-no-separate-debug-info] [-no-mmx] [-no-3dnow] [-no-sse] [-no-sse2]
[-no-sse3] [-no-ssse3] [-no-sse4.1] [-no-sse4.2] [-no-avx] [-no-neon]
- [-qtnamespace ] [-qtlibinfix ] [-separate-debug-info] [-armfpa]
+ [-qtnamespace ] [-qtlibinfix ] [-separate-debug-info]
[-no-phonon-backend] [-phonon-backend] [-no-media-backend] [-media-backend]
[-no-audio-backend] [-audio-backend]
[-no-javascript-jit] [-javascript-jit] [-no-declarative-debug] [-declarative-debug]
@@ -3233,6 +3237,7 @@ cat < ....... Tests will be installed to
(default PREFIX/tests)
+EOF
+if [ "$PLATFORM_QWS" = "yes" -o "$PLATFORM_QPA" = "yes" ]; then
+cat < .. Host executables will be installed to
+ (default HOSTPREFIX/bin)
+ -hostdatadir . Data used by qmake will be installed to
+ (default HOSTPREFIX)
+EOF
+fi
+cat < .. Compile in . The available features
are described in src/corelib/global/qfeatures.txt
- -armfpa ............. Target platform uses the ARM-FPA floating point format.
- -no-armfpa .......... Target platform does not use the ARM-FPA floating point format.
-
- The floating point format is usually autodetected by configure. Use this
- to override the detected value.
-
- -little-endian ...... Target platform is little endian (LSB first).
- -big-endian ......... Target platform is big endian (MSB first).
-
- -host-little-endian . Host platform is little endian (LSB first).
- -host-big-endian .... Host platform is big endian (MSB first).
-
- You only need to specify the endianness when
- cross-compiling, otherwise the host
- endianness will be used.
-
-no-freetype ........ Do not compile in Freetype2 support.
-qt-freetype ........ Use the libfreetype bundled with Qt.
* -system-freetype .... Use libfreetype from the operating system.
@@ -3980,105 +3980,44 @@ esac
#-------------------------------------------------------------------------------
[ -d "$outpath/src/corelib/global" ] || mkdir -p "$outpath/src/corelib/global"
-LICENSE_USER_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_lcnsuser=$Licensee"`
-LICENSE_PRODUCTS_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_lcnsprod=$Edition"`
-PREFIX_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_prfxpath=$QT_INSTALL_PREFIX"`
-DOCUMENTATION_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_docspath=$QT_INSTALL_DOCS"`
-HEADERS_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_hdrspath=$QT_INSTALL_HEADERS"`
-LIBRARIES_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_libspath=$QT_INSTALL_LIBS"`
-BINARIES_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_binspath=$QT_INSTALL_BINS"`
-PLUGINS_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_plugpath=$QT_INSTALL_PLUGINS"`
-IMPORTS_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_impspath=$QT_INSTALL_IMPORTS"`
-DATA_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_datapath=$QT_INSTALL_DATA"`
-TRANSLATIONS_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_trnspath=$QT_INSTALL_TRANSLATIONS"`
-SETTINGS_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_stngpath=$QT_INSTALL_SETTINGS"`
-EXAMPLES_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_xmplpath=$QT_INSTALL_EXAMPLES"`
-TESTS_PATH_STR=`"$relpath/config.tests/unix/padstring" 268 "qt_tstspath=$QT_INSTALL_TESTS"`
-
-TODAY=`date +%Y-%m-%d`
cat > "$outpath/src/corelib/global/qconfig.cpp.new" <> "$outpath/src/corelib/global/qconfig.cpp.new" <> "$outpath/src/corelib/global/qconfig.cpp.new" <> "$outpath/src/corelib/global/qconfig.cpp.new" <> "$outpath/src/corelib/global/qconfig.cpp.new" </dev/null 2>&1; then
- EVALKEY=`"$relpath/config.tests/unix/padstring" 524 "qt_qevalkey="`
+ EVALKEY=qt_qevalkey=
fi
if [ -n "$EVALKEY" ]; then
@@ -5355,7 +5294,13 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
fi
if [ "$CFG_LIBUDEV" != "no" ]; then
- if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/libudev "libudev" $L_FLAGS $I_FLAGS $l_FLAGS; then
+ if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists libudev 2>/dev/null; then
+ QMAKE_INCDIR_LIBUDEV=`$PKG_CONFIG --cflags-only-I libudev 2>/dev/null | sed -e 's,^-I,,g' -e 's, -I, ,g'`
+ QMAKE_LIBS_LIBUDEV=`$PKG_CONFIG --libs libudev 2>/dev/null`
+ QMakeVar set QMAKE_INCDIR_LIBUDEV "$QMAKE_INCDIR_LIBUDEV"
+ QMakeVar set QMAKE_LIBS_LIBUDEV "$QMAKE_LIBS_LIBUDEV"
+ fi
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/libudev "libudev" $L_FLAGS $I_FLAGS $l_FLAGS $QMAKE_INCDIR_LIBUDEV $QMAKE_LIBS_LIBUDEV; then
CFG_LIBUDEV=yes
QT_CONFIG="$QT_CONFIG libudev"
elif [ "$CFG_LIBUDEV" = "yes" ]; then
@@ -5499,6 +5444,8 @@ if [ "$PLATFORM_QPA" = "yes" ]; then
echo " If you really want to build without a QPA platform plugin you must pass"
echo " -no-xcb and -no-wayland to configure. Doing this will produce a Qt that"
echo " cannot run GUI applications."
+ echo " The dependencies needed for xcb to build are listed in"
+ echo " src/plugins/platforms/xcb/README"
exit 1
fi
fi
@@ -5547,93 +5494,6 @@ if [ "$CFG_LIBFREETYPE" = "auto" ]; then
fi
fi
-if [ "$CFG_ENDIAN" = "auto" ]; then
- if [ "$XPLATFORM_MINGW" = "yes" ]; then
- CFG_ENDIAN="Q_LITTLE_ENDIAN"
- else
- "$unixtests/endian.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "QMAKE_LFLAGS+=$SYSROOT_FLAG"
- F="$?"
- if [ "$F" -eq 0 ]; then
- CFG_ENDIAN="Q_LITTLE_ENDIAN"
- elif [ "$F" -eq 1 ]; then
- CFG_ENDIAN="Q_BIG_ENDIAN"
- else
- echo
- echo "The target system byte order could not be detected!"
- echo "Turn on verbose messaging (-v) to see the final report."
- echo "You can use the -little-endian or -big-endian switch to"
- echo "$0 to continue."
- exit 101
- fi
- fi
-fi
-
-if [ "$CFG_HOST_ENDIAN" = "auto" ]; then
- if [ "$BUILD_ON_MAC" = "yes" ]; then
- true #leave as auto
- else
- "$unixtests/endian.test" "$QMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath"
- F="$?"
- if [ "$F" -eq 0 ]; then
- CFG_HOST_ENDIAN="Q_LITTLE_ENDIAN"
- elif [ "$F" -eq 1 ]; then
- CFG_HOST_ENDIAN="Q_BIG_ENDIAN"
- else
- echo
- echo "The host system byte order could not be detected!"
- echo "Turn on verbose messaging (-v) to see the final report."
- echo "You can use the -host-little-endian or -host-big-endian switch to"
- echo "$0 to continue."
- exit 101
- fi
- fi
-fi
-
-if [ "$CFG_ARMFPA" != "auto" ]; then
- if [ "$CFG_ARMFPA" = "yes" ]; then
- if [ "$CFG_ENDIAN" = "Q_LITTLE_ENDIAN" ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_LITTLE_SWAPPED"
- else
- CFG_DOUBLEFORMAT="Q_DOUBLE_BIG_SWAPPED"
- fi
- else
- CFG_DOUBLEFORMAT="normal"
- fi
-fi
-
-
-if [ "$CFG_DOUBLEFORMAT" = "auto" ]; then
- if [ "$PLATFORM_QPA" = "yes" ]; then
- CFG_DOUBLEFORMAT=normal
- else
- "$unixtests/doubleformat.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath"
- F="$?"
- if [ "$F" -eq 10 ] && [ "$CFG_ENDIAN" = "Q_LITTLE_ENDIAN" ]; then
- CFG_DOUBLEFORMAT=normal
- elif [ "$F" -eq 11 ] && [ "$CFG_ENDIAN" = "Q_BIG_ENDIAN" ]; then
- CFG_DOUBLEFORMAT=normal
- elif [ "$F" -eq 10 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_LITTLE"
- elif [ "$F" -eq 11 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_BIG"
- elif [ "$F" -eq 12 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_LITTLE_SWAPPED"
- CFG_ARMFPA="yes"
- elif [ "$F" -eq 13 ]; then
- CFG_DOUBLEFORMAT="Q_DOUBLE_BIG_SWAPPED"
- CFG_ARMFPA="yes"
- else
- echo
- echo "The system floating point format could not be detected."
- echo "This may cause data to be generated in a wrong format"
- echo "Turn on verbose messaging (-v) to see the final report."
- # we do not fail on this since this is a new test, and if it fails,
- # the old behavior should be correct in most cases
- CFG_DOUBLEFORMAT=normal
- fi
- fi
-fi
-
HAVE_STL=no
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stl "STL" $L_FLAGS $I_FLAGS $l_FLAGS; then
HAVE_STL=yes
@@ -6507,64 +6367,8 @@ cat >>"$outpath/src/corelib/global/qconfig.h.new" <>"$outpath/src/corelib/global/qconfig.h.new"
-if [ "$CFG_HOST_ENDIAN" = "auto" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <>"$outpath/src/corelib/global/qconfig.h.new"
-fi
-echo "#else" >>"$outpath/src/corelib/global/qconfig.h.new"
-if [ "$CFG_ENDIAN" = "auto" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <>"$outpath/src/corelib/global/qconfig.h.new"
-fi
-echo "#endif" >>"$outpath/src/corelib/global/qconfig.h.new"
-
-if [ "$CFG_DOUBLEFORMAT" != "normal" ]; then
- cat >>"$outpath/src/corelib/global/qconfig.h.new" <>"$outpath/src/corelib/global/qconfig.h.new" <>"$outpath/src/corelib/global/qconfig.h.new"
- fi
-fi
-
CFG_ARCH_STR=`echo $CFG_ARCH | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
CFG_HOST_ARCH_STR=`echo $CFG_HOST_ARCH | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
cat >>"$outpath/src/corelib/global/qconfig.h.new" <>"$QTCONFIG.tmp"
echo `basename "$XQMAKESPEC"` \{ >>"$QTCONFIG.tmp"
- echo " QT_SYSROOT += \$\$quote($CFG_SYSROOT)" >>"$QTCONFIG.tmp"
- echo " QMAKE_CFLAGS += --sysroot=\$\$QT_SYSROOT" >>"$QTCONFIG.tmp"
- echo " QMAKE_CXXFLAGS += --sysroot=\$\$QT_SYSROOT" >>"$QTCONFIG.tmp"
- echo " QMAKE_LFLAGS += --sysroot=\$\$QT_SYSROOT" >>"$QTCONFIG.tmp"
+ echo " QMAKE_CFLAGS += --sysroot=\$\$[QT_SYSROOT]" >>"$QTCONFIG.tmp"
+ echo " QMAKE_CXXFLAGS += --sysroot=\$\$[QT_SYSROOT]" >>"$QTCONFIG.tmp"
+ echo " QMAKE_LFLAGS += --sysroot=\$\$[QT_SYSROOT]" >>"$QTCONFIG.tmp"
echo "}" >> "$QTCONFIG.tmp"
echo >> "$QTCONFIG.tmp"
fi
@@ -7093,6 +6896,7 @@ else
fi
echo "zlib support ........... $CFG_ZLIB"
echo "Session management ..... $CFG_SM"
+echo "libudev support ........ $CFG_LIBUDEV"
if [ "$CFG_OPENGL" = "desktop" ]; then
echo "OpenGL support ......... yes (Desktop OpenGL)"
diff --git a/configure.bat b/configure.bat
index e872de27972..b5ffb14731e 100644
--- a/configure.bat
+++ b/configure.bat
@@ -67,9 +67,7 @@ if not exist src\corelib\global\qconfig.h (
md src\corelib\global
if errorlevel 1 goto exit
)
- echo #define Q_BIG_ENDIAN 4321 > src\corelib\global\qconfig.h
- echo #define Q_LITTLE_ENDIAN 1234 >> src\corelib\global\qconfig.h
- echo #define Q_BYTE_ORDER Q_LITTLE_ENDIAN >> src\corelib\global\qconfig.h
+ echo /* Generated by configure.bat - DO NOT EDIT! */ > src\corelib\global\qconfig.h
)
if not exist tools\configure (
@@ -117,5 +115,5 @@ if errorlevel 1 (cd ..\.. & exit /b 1)
cd ..\..
:conf
-configure.exe -srcdir %QTSRC% %nosyncqt% %*
+configure.exe -srcdir %QTSRC% %* %nosyncqt%
:exit
diff --git a/dist/README b/dist/README
index 815e12be9e3..12062802655 100644
--- a/dist/README
+++ b/dist/README
@@ -74,7 +74,7 @@ HOW TO REPORT A BUG
If you think you have found a bug in Qt, we would like to hear about
it so that we can fix it. The Qt bug tracking system is open to the
-public at http://bugreports.qt.nokia.com/.
+public at http://bugreports.qt-project.org/.
Before reporting a bug, please use the bug-tracker's search functions
and consult http://qt.nokia.com/developer/faqs/ to see if the issue is
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index 95dbe0b1d77..7b8d1fa0bdf 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -1,7 +1,7 @@
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
- http://bugreports.qt.nokia.com/
+ http://bugreports.qt-project.org/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
@@ -52,6 +52,8 @@ information about a particular change.
in Qt4, so these methods return a bool now. If your code used the undocumented
QBool, simply replace it with bool.
+- qIsDetached<> has been removed without replacement.
+
- QMetaType:
* QMetaType::construct() has been renamed to QMetaType::create().
* QMetaType::unregisterType() has been removed.
@@ -212,7 +214,14 @@ information about a particular change.
- qmake
* Projects which explicitly set an empty TARGET are considered broken now.
- * several functions and built-in variables were modified to return normalized paths.
+ * The makespec and .qmake.cache do not see build pass specific variables any more.
+ * load()/include() with a target namespace and infile()/$$fromfile() now start with
+ an entirely pristine context.
+ * Configure's -sysroot and -hostprefix are now handled slightly differently.
+ The QT_INSTALL_... properties are now automatically prefixed with the sysroot;
+ the raw values are available as QT_RAW_INSTALL_... and the sysroot as QT_SYSROOT.
+ The new QT_HOST_... properties can be used to refer to the Qt host tools.
+ * Several functions and built-in variables were modified to return normalized paths.
- QTextCodecPlugin has been removed since it is no longer used. All text codecs
are now built into QtCore.
@@ -313,9 +322,18 @@ QtCore
libraries, creating uncertainty/bugs in using QString easily, and (to a lesser
extent) performance issues.
+* QTextCodec::codecForTr() and QTextCodec::setCodecForTr() have been removed,
+ QCoreApplication::Encoding value CodecForTr is now obsolete, use
+ DefaultCodec instead. For reasoning, see the codecForCStrings() removal above.
+
* QIntValidator and QDoubleValidator no longer fall back to using the C locale if
the requested locale fails to validate the input.
+* A new set of classes for doing pattern matching with Perl-compatible regular
+ expressions has been added: QRegularExpression, QRegularExpressionMatch and
+ QRegularExpressionMatchIterator. They aim to replace QRegExp with a more
+ powerful and flexible regular expression engine.
+
QtGui
-----
* Accessibility has been refactored. The hierachy of accessible objects is implemented via
@@ -400,6 +418,17 @@ ignore the rest of the range.
QSqlTableModel::indexInQuery() as example of how to implement in a
subclass.
+* QSqlTableModel::selectRow(): This is a new method that refreshes a single
+row in the model from the database.
+
+* QSqlTableModel edit strategies OnFieldChange/OnRowChange QTBUG-2875
+Previously, after changes were submitted in these edit strategies, select()
+was called which removed and inserted all rows. This ruined navigation
+in QTableView. Now, with these edit strategies, there is no implicit select()
+done after committing. This includes deleted rows which remain in
+the model as blank rows until the application calls select(). Instead,
+selectRow() is called to refresh only the affected row.
+
****************************************************************************
* Database Drivers *
****************************************************************************
diff --git a/doc/src/corelib/containers.qdoc b/doc/src/corelib/containers.qdoc
index e28c3bdbfed..b63cc9df28b 100644
--- a/doc/src/corelib/containers.qdoc
+++ b/doc/src/corelib/containers.qdoc
@@ -104,10 +104,10 @@
efficient hash-lookup of objects in a limited cache storage.
\table
- \header \o Class \o Summary
+ \header \li Class \li Summary
- \row \o \l{QList}
- \o This is by far the most commonly used container class. It
+ \row \li \l{QList}
+ \li This is by far the most commonly used container class. It
stores a list of values of a given type (T) that can be accessed
by index. Internally, the QList is implemented using an array,
ensuring that index-based access is very fast.
@@ -119,8 +119,8 @@
possible in the executable. QStringList inherits from
QList.
- \row \o \l{QLinkedList}
- \o This is similar to QList, except that it uses
+ \row \li \l{QLinkedList}
+ \li This is similar to QList, except that it uses
iterators rather than integer indexes to access items. It also
provides better performance than QList when inserting in the
middle of a huge list, and it has nicer iterator semantics.
@@ -128,48 +128,48 @@
long as the item exists, whereas iterators to a QList can become
invalid after any insertion or removal.)
- \row \o \l{QVector}
- \o This stores an array of values of a given type at adjacent
+ \row \li \l{QVector}
+ \li This stores an array of values of a given type at adjacent
positions in memory. Inserting at the front or in the middle of
a vector can be quite slow, because it can lead to large numbers
of items having to be moved by one position in memory.
- \row \o \l{QStack}
- \o This is a convenience subclass of QVector that provides
+ \row \li \l{QStack}
+ \li This is a convenience subclass of QVector that provides
"last in, first out" (LIFO) semantics. It adds the following
functions to those already present in QVector:
\l{QStack::push()}{push()}, \l{QStack::pop()}{pop()},
and \l{QStack::top()}{top()}.
- \row \o \l{QQueue}
- \o This is a convenience subclass of QList that provides
+ \row \li \l{QQueue}
+ \li This is a convenience subclass of QList that provides
"first in, first out" (FIFO) semantics. It adds the following
functions to those already present in QList:
\l{QQueue::enqueue()}{enqueue()},
\l{QQueue::dequeue()}{dequeue()}, and \l{QQueue::head()}{head()}.
- \row \o \l{QSet}
- \o This provides a single-valued mathematical set with fast
+ \row \li \l{QSet}
+ \li This provides a single-valued mathematical set with fast
lookups.
- \row \o \l{QMap}
- \o This provides a dictionary (associative array) that maps keys
+ \row \li \l{QMap}
+ \li This provides a dictionary (associative array) that maps keys
of type Key to values of type T. Normally each key is associated
with a single value. QMap stores its data in Key order; if order
doesn't matter QHash is a faster alternative.
- \row \o \l{QMultiMap}
- \o This is a convenience subclass of QMap that provides a nice
+ \row \li \l{QMultiMap}
+ \li This is a convenience subclass of QMap that provides a nice
interface for multi-valued maps, i.e. maps where one key can be
associated with multiple values.
- \row \o \l{QHash}
- \o This has almost the same API as QMap, but provides
+ \row \li \l{QHash}
+ \li This has almost the same API as QMap, but provides
significantly faster lookups. QHash stores its data in an
arbitrary order.
- \row \o \l{QMultiHash}
- \o This is a convenience subclass of QHash that
+ \row \li \l{QMultiHash}
+ \li This is a convenience subclass of QHash that
provides a nice interface for multi-valued hashes.
\endtable
@@ -271,20 +271,20 @@
read-write access.
\table
- \header \o Containers \o Read-only iterator
- \o Read-write iterator
- \row \o QList, QQueue \o QListIterator
- \o QMutableListIterator
- \row \o QLinkedList \o QLinkedListIterator
- \o QMutableLinkedListIterator
- \row \o QVector, QStack \o QVectorIterator
- \o QMutableVectorIterator
- \row \o QSet \o QSetIterator
- \o QMutableSetIterator
- \row \o QMap, QMultiMap \o QMapIterator
- \o QMutableMapIterator
- \row \o QHash, QMultiHash \o QHashIterator
- \o QMutableHashIterator
+ \header \li Containers \li Read-only iterator
+ \li Read-write iterator
+ \row \li QList, QQueue \li QListIterator
+ \li QMutableListIterator
+ \row \li QLinkedList \li QLinkedListIterator
+ \li QMutableLinkedListIterator
+ \row \li QVector, QStack \li QVectorIterator
+ \li QMutableVectorIterator
+ \row \li QSet \li QSetIterator
+ \li QMutableSetIterator
+ \row \li QMap, QMultiMap \li QMapIterator
+ \li QMutableMapIterator
+ \row \li QHash, QMultiHash \li QHashIterator
+ \li QMutableHashIterator
\endtable
In this discussion, we will concentrate on QList and QMap. The
@@ -334,23 +334,23 @@
The following table summarizes the QListIterator API:
\table
- \header \o Function \o Behavior
- \row \o \l{QListIterator::toFront()}{toFront()}
- \o Moves the iterator to the front of the list (before the first item)
- \row \o \l{QListIterator::toBack()}{toBack()}
- \o Moves the iterator to the back of the list (after the last item)
- \row \o \l{QListIterator::hasNext()}{hasNext()}
- \o Returns true if the iterator isn't at the back of the list
- \row \o \l{QListIterator::next()}{next()}
- \o Returns the next item and advances the iterator by one position
- \row \o \l{QListIterator::peekNext()}{peekNext()}
- \o Returns the next item without moving the iterator
- \row \o \l{QListIterator::hasPrevious()}{hasPrevious()}
- \o Returns true if the iterator isn't at the front of the list
- \row \o \l{QListIterator::previous()}{previous()}
- \o Returns the previous item and moves the iterator back by one position
- \row \o \l{QListIterator::peekPrevious()}{peekPrevious()}
- \o Returns the previous item without moving the iterator
+ \header \li Function \li Behavior
+ \row \li \l{QListIterator::toFront()}{toFront()}
+ \li Moves the iterator to the front of the list (before the first item)
+ \row \li \l{QListIterator::toBack()}{toBack()}
+ \li Moves the iterator to the back of the list (after the last item)
+ \row \li \l{QListIterator::hasNext()}{hasNext()}
+ \li Returns true if the iterator isn't at the back of the list
+ \row \li \l{QListIterator::next()}{next()}
+ \li Returns the next item and advances the iterator by one position
+ \row \li \l{QListIterator::peekNext()}{peekNext()}
+ \li Returns the next item without moving the iterator
+ \row \li \l{QListIterator::hasPrevious()}{hasPrevious()}
+ \li Returns true if the iterator isn't at the front of the list
+ \row \li \l{QListIterator::previous()}{previous()}
+ \li Returns the previous item and moves the iterator back by one position
+ \row \li \l{QListIterator::peekPrevious()}{peekPrevious()}
+ \li Returns the previous item without moving the iterator
\endtable
QListIterator provides no functions to insert or remove items
@@ -440,20 +440,20 @@
possible because they are faster than read-write iterators.
\table
- \header \o Containers \o Read-only iterator
- \o Read-write iterator
- \row \o QList, QQueue \o QList::const_iterator
- \o QList::iterator
- \row \o QLinkedList \o QLinkedList::const_iterator
- \o QLinkedList::iterator
- \row \o QVector, QStack \o QVector::const_iterator
- \o QVector::iterator
- \row \o QSet \o QSet::const_iterator
- \o QSet::iterator
- \row \o QMap, QMultiMap \o QMap::const_iterator
- \o QMap::iterator
- \row \o QHash, QMultiHash \o QHash::const_iterator
- \o QHash::iterator
+ \header \li Containers \li Read-only iterator
+ \li Read-write iterator
+ \row \li QList, QQueue \li QList::const_iterator
+ \li QList::iterator
+ \row \li QLinkedList \li QLinkedList::const_iterator
+ \li QLinkedList::iterator
+ \row \li QVector, QStack \li QVector::const_iterator
+ \li QVector::iterator
+ \row \li QSet \li QSet::const_iterator
+ \li QSet::iterator
+ \row \li QMap, QMultiMap \li QMap::const_iterator
+ \li QMap::iterator
+ \row \li QHash, QMultiHash \li QHash::const_iterator
+ \li QHash::iterator
\endtable
The API of the STL iterators is modelled on pointers in an array.
@@ -509,13 +509,13 @@
The following table summarizes the STL-style iterators' API:
\table
- \header \o Expression \o Behavior
- \row \o \c{*i} \o Returns the current item
- \row \o \c{++i} \o Advances the iterator to the next item
- \row \o \c{i += n} \o Advances the iterator by \c n items
- \row \o \c{--i} \o Moves the iterator back by one item
- \row \o \c{i -= n} \o Moves the iterator back by \c n items
- \row \o \c{i - j} \o Returns the number of items between iterators \c i and \c j
+ \header \li Expression \li Behavior
+ \row \li \c{*i} \li Returns the current item
+ \row \li \c{++i} \li Advances the iterator to the next item
+ \row \li \c{i += n} \li Advances the iterator by \c n items
+ \row \li \c{--i} \li Moves the iterator back by one item
+ \row \li \c{i -= n} \li Moves the iterator back by \c n items
+ \row \li \c{i - j} \li Returns the number of items between iterators \c i and \c j
\endtable
The \c{++} and \c{--} operators are available both as prefix
@@ -625,17 +625,17 @@
be used with the \c foreach keyword.
\list
- \o QVarLengthArray provides a low-level
+ \li QVarLengthArray provides a low-level
variable-length array. It can be used instead of QVector in
places where speed is particularly important.
- \o QCache provides a cache to store objects of a certain
+ \li QCache provides a cache to store objects of a certain
type T associated with keys of type Key.
- \o QContiguousCache provides an efficient way of caching data
+ \li QContiguousCache provides an efficient way of caching data
that is typically accessed in a contiguous way.
- \o QPair stores a pair of elements.
+ \li QPair stores a pair of elements.
\endlist
Additional non-template types that compete with Qt's template
@@ -662,27 +662,27 @@
\keyword quadratic time
\list
- \o \bold{Constant time:} O(1). A function is said to run in constant
+ \li \b{Constant time:} O(1). A function is said to run in constant
time if it requires the same amount of time no matter how many
items are present in the container. One example is
QLinkedList::insert().
- \o \bold{Logarithmic time:} O(log \e n). A function that runs in
+ \li \b{Logarithmic time:} O(log \e n). A function that runs in
logarithmic time is a function whose running time is
proportional to the logarithm of the number of items in the
container. One example is qBinaryFind().
- \o \bold{Linear time:} O(\e n). A function that runs in linear time
+ \li \b{Linear time:} O(\e n). A function that runs in linear time
will execute in a time directly proportional to the number of
items stored in the container. One example is
QVector::insert().
- \o \bold{Linear-logarithmic time:} O(\e{n} log \e n). A function
+ \li \b{Linear-logarithmic time:} O(\e{n} log \e n). A function
that runs in linear-logarithmic time is asymptotically slower
than a linear-time function, but faster than a quadratic-time
function.
- \o \bold{Quadratic time:} O(\e{n}\unicode{178}). A quadratic-time function
+ \li \b{Quadratic time:} O(\e{n}\unicode{178}). A quadratic-time function
executes in a time that is proportional to the square of the
number of items stored in the container.
\endlist
@@ -691,10 +691,10 @@
sequential container classes:
\table
- \header \o \o Index lookup \o Insertion \o Prepending \o Appending
- \row \o QLinkedList \o O(\e n) \o O(1) \o O(1) \o O(1)
- \row \o QList \o O(1) \o O(n) \o Amort. O(1) \o Amort. O(1)
- \row \o QVector \o O(1) \o O(n) \o O(n) \o Amort. O(1)
+ \header \li \li Index lookup \li Insertion \li Prepending \li Appending
+ \row \li QLinkedList \li O(\e n) \li O(1) \li O(1) \li O(1)
+ \row \li QList \li O(1) \li O(n) \li Amort. O(1) \li Amort. O(1)
+ \row \li QVector \li O(1) \li O(n) \li O(n) \li Amort. O(1)
\endtable
In the table, "Amort." stands for "amortized behavior". For
@@ -707,12 +707,12 @@
associative containers and sets:
\table
- \header \o{1,2} \o{2,1} Key lookup \o{2,1} Insertion
- \header \o Average \o Worst case \o Average \o Worst case
- \row \o QMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n)
- \row \o QMultiMap \o O(log \e n) \o O(log \e n) \o O(log \e n) \o O(log \e n)
- \row \o QHash \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n)
- \row \o QSet \o Amort. O(1) \o O(\e n) \o Amort. O(1) \o O(\e n)
+ \header \li{1,2} \li{2,1} Key lookup \li{2,1} Insertion
+ \header \li Average \li Worst case \li Average \li Worst case
+ \row \li QMap \li O(log \e n) \li O(log \e n) \li O(log \e n) \li O(log \e n)
+ \row \li QMultiMap \li O(log \e n) \li O(log \e n) \li O(log \e n) \li O(log \e n)
+ \row \li QHash \li Amort. O(1) \li O(\e n) \li Amort. O(1) \li O(\e n)
+ \row \li QSet \li Amort. O(1) \li O(\e n) \li Amort. O(1) \li O(\e n)
\endtable
With QVector, QHash, and QSet, the performance of appending items
@@ -749,13 +749,13 @@
The values above may seem a bit strange, but here are the guiding
principles:
\list
- \o QString allocates 4 characters at a time until it reaches size 20.
- \o From 20 to 4084, it advances by doubling the size each time.
+ \li QString allocates 4 characters at a time until it reaches size 20.
+ \li From 20 to 4084, it advances by doubling the size each time.
More precisely, it advances to the next power of two, minus
12. (Some memory allocators perform worst when requested exact
powers of two, because they use a few bytes per block for
book-keeping.)
- \o From 4084 on, it advances by blocks of 2048 characters (4096
+ \li From 4084 on, it advances by blocks of 2048 characters (4096
bytes). This makes sense because modern operating systems
don't copy the entire data when reallocating a buffer; the
physical memory pages are simply reordered, and only the data
@@ -787,12 +787,12 @@
use to store the items:
\list
- \o \l{QString::capacity()}{capacity()} returns the
+ \li \l{QString::capacity()}{capacity()} returns the
number of items for which memory is allocated (for QHash and
QSet, the number of buckets in the hash table).
- \o \l{QString::reserve()}{reserve}(\e size) explicitly
+ \li \l{QString::reserve()}{reserve}(\e size) explicitly
preallocates memory for \e size items.
- \o \l{QString::squeeze()}{squeeze()} frees any memory
+ \li \l{QString::squeeze()}{squeeze()} frees any memory
not required to store the items.
\endlist
diff --git a/doc/src/corelib/json.qdoc b/doc/src/corelib/json.qdoc
index 91a89761e3d..88b53770742 100644
--- a/doc/src/corelib/json.qdoc
+++ b/doc/src/corelib/json.qdoc
@@ -59,12 +59,12 @@
JSON is a format to store structured data. It has 6 basic data types:
\list
- \o bool
- \o double
- \o string
- \o array
- \o object
- \o null
+ \li bool
+ \li double
+ \li string
+ \li array
+ \li object
+ \li null
\endlist
Any value can be any of the above type. A boolean value is represented by the
diff --git a/doc/src/corelib/objectmodel/metaobjects.qdoc b/doc/src/corelib/objectmodel/metaobjects.qdoc
index 7edb376e257..c92f6f2f099 100644
--- a/doc/src/corelib/objectmodel/metaobjects.qdoc
+++ b/doc/src/corelib/objectmodel/metaobjects.qdoc
@@ -41,12 +41,12 @@
The meta-object system is based on three things:
\list 1
- \o The \l QObject class provides a base class for objects that can
+ \li The \l QObject class provides a base class for objects that can
take advantage of the meta-object system.
- \o The Q_OBJECT macro inside the private section of the class
+ \li The Q_OBJECT macro inside the private section of the class
declaration is used to enable meta-object features, such as
dynamic properties, signals, and slots.
- \o The \l{moc}{Meta-Object Compiler} (\c moc) supplies each
+ \li The \l{moc}{Meta-Object Compiler} (\c moc) supplies each
QObject subclass with the necessary code to implement
meta-object features.
\endlist
@@ -64,19 +64,19 @@
additional features:
\list
- \o QObject::metaObject() returns the associated
+ \li QObject::metaObject() returns the associated
\l{QMetaObject}{meta-object} for the class.
- \o QMetaObject::className() returns the class name as a
+ \li QMetaObject::className() returns the class name as a
string at run-time, without requiring native run-time type information
(RTTI) support through the C++ compiler.
- \o QObject::inherits() function returns whether an object is an
+ \li QObject::inherits() function returns whether an object is an
instance of a class that inherits a specified class within the
QObject inheritance tree.
- \o QObject::tr() and QObject::trUtf8() translate strings for
+ \li QObject::tr() and QObject::trUtf8() translate strings for
\l{Internationalization with Qt}{internationalization}.
- \o QObject::setProperty() and QObject::property()
+ \li QObject::setProperty() and QObject::property()
dynamically set and get properties by name.
- \o QMetaObject::newInstance() constructs a new instance of the class.
+ \li QMetaObject::newInstance() constructs a new instance of the class.
\endlist
\target qobjectcast
diff --git a/doc/src/corelib/objectmodel/object.qdoc b/doc/src/corelib/objectmodel/object.qdoc
index cf3ce4ef314..4e212b37dd1 100644
--- a/doc/src/corelib/objectmodel/object.qdoc
+++ b/doc/src/corelib/objectmodel/object.qdoc
@@ -41,20 +41,20 @@
Qt adds these features to C++:
\list
- \o a very powerful mechanism for seamless object
+ \li a very powerful mechanism for seamless object
communication called \l{signals and slots}
- \o queryable and designable \l{Qt's Property System}{object
+ \li queryable and designable \l{Qt's Property System}{object
properties}
- \o powerful \l{The Event System}{events and event filters}
- \o contextual \l{i18n}{string translation for internationalization}
- \o sophisticated interval driven \l timers that make it possible
+ \li powerful \l{The Event System}{events and event filters}
+ \li contextual \l{i18n}{string translation for internationalization}
+ \li sophisticated interval driven \l timers that make it possible
to elegantly integrate many tasks in an event-driven GUI
- \o hierarchical and queryable \l{Object Trees & Ownership}{object
+ \li hierarchical and queryable \l{Object Trees & Ownership}{object
trees} that organize object ownership in a natural way
- \o guarded pointers (QPointer) that are automatically
+ \li guarded pointers (QPointer) that are automatically
set to 0 when the referenced object is destroyed, unlike normal C++
pointers which become dangling pointers when their objects are destroyed
- \o a \l{metaobjects.html#qobjectcast}{dynamic cast} that works across
+ \li a \l{metaobjects.html#qobjectcast}{dynamic cast} that works across
library boundaries.
\endlist
@@ -92,22 +92,22 @@
or assigning a value. We can see what this means in the Qt Object
Model.
- \bold{A Qt Object...}
+ \b{A Qt Object...}
\list
- \o might have a unique \l{QObject::objectName()}. If we copy a Qt
+ \li might have a unique \l{QObject::objectName()}. If we copy a Qt
Object, what name should we give the copy?
- \o has a location in an \l{Object Trees & Ownership}
+ \li has a location in an \l{Object Trees & Ownership}
{object hierarchy}. If we copy a Qt Object, where should the copy
be located?
- \o can be connected to other Qt Objects to emit signals to them or
+ \li can be connected to other Qt Objects to emit signals to them or
to receive signals emitted by them. If we copy a Qt Object, how
should we transfer these connections to the copy?
- \o can have \l{Qt's Property System} {new properties} added to it
+ \li can have \l{Qt's Property System} {new properties} added to it
at runtime that are not declared in the C++ class. If we copy a Qt
Object, should the copy include the properties that were added to
the original?
diff --git a/doc/src/corelib/objectmodel/properties.qdoc b/doc/src/corelib/objectmodel/properties.qdoc
index 894efd017de..4d090af8fcf 100644
--- a/doc/src/corelib/objectmodel/properties.qdoc
+++ b/doc/src/corelib/objectmodel/properties.qdoc
@@ -58,20 +58,20 @@
\list
- \o A \c READ accessor function is required. It is for reading the
+ \li A \c READ accessor function is required. It is for reading the
property value. Ideally, a const function is used for this purpose,
and it must return either the property's type or a pointer or
reference to that type. e.g., QWidget::focus is a read-only property
with \c READ function, QWidget::hasFocus().
- \o A \c WRITE accessor function is optional. It is for setting the
+ \li A \c WRITE accessor function is optional. It is for setting the
property value. It must return void and must take exactly one
argument, either of the property's type or a pointer or reference
to that type. e.g., QWidget::enabled has the \c WRITE function
QWidget::setEnabled(). Read-only properties do not need \c WRITE
functions. e.g., QWidget::focus has no \c WRITE function.
- \o A \c RESET function is optional. It is for setting the property
+ \li A \c RESET function is optional. It is for setting the property
back to its context specific default value. e.g., QWidget::cursor
has the typical \c READ and \c WRITE functions, QWidget::cursor()
and QWidget::setCursor(), and it also has a \c RESET function,
@@ -79,26 +79,26 @@
mean \e {reset to the context specific cursor}. The \c RESET
function must return void and take no parameters.
- \o A \c NOTIFY signal is optional. If defined, it should specify one
+ \li A \c NOTIFY signal is optional. If defined, it should specify one
existing signal in that class that is emitted whenever the value
of the property changes.
- \o A \c REVISION number is optional. If included, it defines the
+ \li A \c REVISION number is optional. If included, it defines the
the property and its notifier signal to be used in a particular
revision of the API that is exposed to QML.
- \o The \c DESIGNABLE attribute indicates whether the property
+ \li The \c DESIGNABLE attribute indicates whether the property
should be visible in the property editor of GUI design tool (e.g.,
\l {Qt Designer}). Most properties are \c DESIGNABLE (default
true). Instead of true or false, you can specify a boolean
member function.
- \o The \c SCRIPTABLE attribute indicates whether this property
+ \li The \c SCRIPTABLE attribute indicates whether this property
should be accessible by a scripting engine (default true).
Instead of true or false, you can specify a boolean member
function.
- \o The \c STORED attribute indicates whether the property should
+ \li The \c STORED attribute indicates whether the property should
be thought of as existing on its own or as depending on other
values. It also indicates whether the property value must be saved
when storing the object's state. Most properties are \c STORED
@@ -106,20 +106,20 @@
false, because its value is just taken from the width component
of property QWidget::minimumSize(), which is a QSize.
- \o The \c USER attribute indicates whether the property is
+ \li The \c USER attribute indicates whether the property is
designated as the user-facing or user-editable property for the
class. Normally, there is only one \c USER property per class
(default false). e.g., QAbstractButton::checked is the user
editable property for (checkable) buttons. Note that QItemDelegate
gets and sets a widget's \c USER property.
- \o The presence of the \c CONSTANT attibute indicates that the property
+ \li The presence of the \c CONSTANT attibute indicates that the property
value is constant. For a given object instance, the READ method of a
constant property must return the same value every time it is called. This
constant value may be different for different instances of the object. A
constant property cannot have a WRITE method or a NOTIFY signal.
- \o The presence of the \c FINAL attribute indicates that the property
+ \li The presence of the \c FINAL attribute indicates that the property
will not be overridden by a derived class. This can be used for performance
optimizations in some cases, but is not enforced by moc. Care must be taken
never to override a \c FINAL property.
diff --git a/doc/src/corelib/threads-basics.qdoc b/doc/src/corelib/threads-basics.qdoc
index 44a39611778..e54f8a7ccbb 100644
--- a/doc/src/corelib/threads-basics.qdoc
+++ b/doc/src/corelib/threads-basics.qdoc
@@ -123,8 +123,8 @@
There are basically two use cases for threads:
\list
- \o Make processing faster by making use of multicore processors.
- \o Keep the GUI thread or other time critical threads responsive by
+ \li Make processing faster by making use of multicore processors.
+ \li Keep the GUI thread or other time critical threads responsive by
offloading long lasting processing or blocking calls to other threads.
\endlist
@@ -138,23 +138,23 @@
\table
\header
- \o Alternative
- \o Comment
+ \li Alternative
+ \li Comment
\row
- \o QEventLoop::processEvents()
- \o Calling QEventLoop::processEvents() repeatedly during a
+ \li QEventLoop::processEvents()
+ \li Calling QEventLoop::processEvents() repeatedly during a
time-consuming calculation prevents GUI blocking. However, this
solution doesn't scale well because the call to processEvents() may
occur too often, or not often enough, depending on hardware.
\row
- \o QTimer
- \o Background processing can sometimes be done conveniently using a
+ \li QTimer
+ \li Background processing can sometimes be done conveniently using a
timer to schedule execution of a slot at some point in the future.
A timer with an interval of 0 will time out as soon as there are no
more events to process.
\row
- \o QSocketNotifier QNetworkAccessManager QIODevice::readyRead()
- \o This is an alternative to having one or multiple threads, each with
+ \li QSocketNotifier QNetworkAccessManager QIODevice::readyRead()
+ \li This is an alternative to having one or multiple threads, each with
a blocking read on a slow network connection. As long as the
calculation in response to a chunk of network data can be executed
quickly, this reactive design is better than synchronous waiting in
@@ -183,55 +183,55 @@
\table
\header
- \o Lifetime of thread
- \o Development task
- \o Solution
+ \li Lifetime of thread
+ \li Development task
+ \li Solution
\row
- \o One call
- \o Run one method within another thread and quit the thread when the
+ \li One call
+ \li Run one method within another thread and quit the thread when the
method is finished.
- \o Qt provides different solutions:
+ \li Qt provides different solutions:
\list
- \o Write a function and run it with QtConcurrent::run()
- \o Derive a class from QRunnable and run it in the global thread
+ \li Write a function and run it with QtConcurrent::run()
+ \li Derive a class from QRunnable and run it in the global thread
pool with QThreadPool::globalInstance()->start()
- \o Derive a class from QThread, reimplement the QThread::run()
+ \li Derive a class from QThread, reimplement the QThread::run()
method and use QThread::start() to run it.
\endlist
\row
- \o One call
- \o Operations are to be performed on all items of a container.
+ \li One call
+ \li Operations are to be performed on all items of a container.
Processing should be performed using all available cores. A common
example is to produce thumbnails from a list of images.
- \o QtConcurrent provides the \l{QtConcurrent::}{map()} function for
+ \li QtConcurrent provides the \l{QtConcurrent::}{map()} function for
applying operations on every container element,
\l{QtConcurrent::}{filter()} for selecting container elements, and
the option of specifying a reduce function for combining the
remaining elements.
\row
- \o One call
- \o A long running operation has to be put in another thread. During the
+ \li One call
+ \li A long running operation has to be put in another thread. During the
course of processing, status information should be sent to the GUI
thread.
- \o Use QThread, reimplement run and emit signals as needed. Connect the
+ \li Use QThread, reimplement run and emit signals as needed. Connect the
signals to the GUI thread's slots using queued signal/slot
connections.
\row
- \o Permanent
- \o Have an object living in another thread and let it perform different
+ \li Permanent
+ \li Have an object living in another thread and let it perform different
tasks upon request.
This means communication to and from the worker thread is required.
- \o Derive a class from QObject and implement the necessary slots and
+ \li Derive a class from QObject and implement the necessary slots and
signals, move the object to a thread with a running event loop and
communicate with the object over queued signal/slot connections.
\row
- \o Permanent
- \o Have an object living in another thread, let the object perform
+ \li Permanent
+ \li Have an object living in another thread, let the object perform
repeated tasks such as polling a port and enable communication with
the GUI thread.
- \o Same as above but also use a timer in the worker thread to implement
+ \li Same as above but also use a timer in the worker thread to implement
polling. However, the best solution for polling is to avoid it
completely. Sometimes using QSocketNotifier is an alternative.
\endtable
@@ -304,18 +304,18 @@
The anatomy of QThread is quite interesting:
\list
- \o QThread does not live in the new thread where \l{QThread::}{run()} is
+ \li QThread does not live in the new thread where \l{QThread::}{run()} is
executed. It lives in the old thread.
- \o Most QThread methods are the thread's control interface and are meant to
+ \li Most QThread methods are the thread's control interface and are meant to
be called from the old thread. Do not move this interface to the newly
created thread using \l{QObject::}{moveToThread()}; i.e., calling
\l{QObject::moveToThread()}{moveToThread(this)} is regarded as bad
practice.
- \o \l{QThread::}{exec()} and the static methods
+ \li \l{QThread::}{exec()} and the static methods
\l{QThread::}{usleep()}, \l{QThread::}{msleep()},
\l{QThread::}{sleep()} are meant to be called from the newly created
thread.
- \o Additional members defined in the QThread subclass are
+ \li Additional members defined in the QThread subclass are
accessible by both threads. The developer is responsible for
coordinating access. A typical strategy is to set the members before
\l{QThread::}{start()} is called. Once the worker thread is running,
@@ -432,11 +432,11 @@
main thread.
\list
- \o Using QThread as shown \l{Qt thread basics}{above}
- \o \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
- \o \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
- \o \l{Example 3: Clock}{Communication with the GUI thread}
- \o \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
+ \li Using QThread as shown \l{Qt thread basics}{above}
+ \li \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
+ \li \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
+ \li \l{Example 3: Clock}{Communication with the GUI thread}
+ \li \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
provides service to the main thread}
\endlist
@@ -558,13 +558,13 @@
can help you go into the subject in more depth:
\list
- \o Good video tutorials about threads with Qt can be found in the material
+ \li Good video tutorials about threads with Qt can be found in the material
from the \l{Training Day at Qt Developer Days 2009}.
- \o The \l{Thread Support in Qt} document is a good starting point into
+ \li The \l{Thread Support in Qt} document is a good starting point into
the reference documentation.
- \o Qt comes with several additional examples for
+ \li Qt comes with several additional examples for
\l{Threading and Concurrent Programming Examples}{QThread and QtConcurrent}.
- \o Several good books describe how to work with Qt threads. The most
+ \li Several good books describe how to work with Qt threads. The most
extensive coverage can be found in \e{Advanced Qt Programming} by Mark
Summerfield, Prentice Hall - roughly 70 of 500 pages cover QThread and
QtConcurrent.
diff --git a/doc/src/corelib/threads.qdoc b/doc/src/corelib/threads.qdoc
index 3b4def41744..04a5379b2d0 100644
--- a/doc/src/corelib/threads.qdoc
+++ b/doc/src/corelib/threads.qdoc
@@ -54,14 +54,14 @@
\section1 Topics:
\list
- \o \l{Recommended Reading}
- \o \l{The Threading Classes}
- \o \l{Starting Threads with QThread}
- \o \l{Synchronizing Threads}
- \o \l{Reentrancy and Thread-Safety}
- \o \l{Threads and QObjects}
- \o \l{Concurrent Programming}
- \o \l{Thread-Support in Qt Modules}
+ \li \l{Recommended Reading}
+ \li \l{The Threading Classes}
+ \li \l{Starting Threads with QThread}
+ \li \l{Synchronizing Threads}
+ \li \l{Reentrancy and Thread-Safety}
+ \li \l{Threads and QObjects}
+ \li \l{Concurrent Programming}
+ \li \l{Thread-Support in Qt Modules}
\endlist
\section1 Recommended Reading
@@ -71,10 +71,10 @@
to threading see our Recommended Reading list:
\list
- \o \l{Threads Primer: A Guide to Multithreaded Programming}
- \o \l{Thread Time: The Multithreaded Programming Guide}
- \o \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
- \o \l{Win32 Multithreaded Programming}
+ \li \l{Threads Primer: A Guide to Multithreaded Programming}
+ \li \l{Thread Time: The Multithreaded Programming Guide}
+ \li \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
+ \li \l{Win32 Multithreaded Programming}
\endlist
\section1 The Threading Classes
@@ -85,21 +85,21 @@
\omit
\list
- \o QThread provides the means to start a new thread.
- \o QThreadStorage provides per-thread data storage.
- \o QThreadPool manages a pool of threads that run QRunnable objects.
- \o QRunnable is an abstract class representing a runnable object.
- \o QMutex provides a mutual exclusion lock, or mutex.
- \o QMutexLocker is a convenience class that automatically locks
+ \li QThread provides the means to start a new thread.
+ \li QThreadStorage provides per-thread data storage.
+ \li QThreadPool manages a pool of threads that run QRunnable objects.
+ \li QRunnable is an abstract class representing a runnable object.
+ \li QMutex provides a mutual exclusion lock, or mutex.
+ \li QMutexLocker is a convenience class that automatically locks
and unlocks a QMutex.
- \o QReadWriteLock provides a lock that allows simultaneous read access.
- \o QReadLocker and QWriteLocker are convenience classes that automatically
+ \li QReadWriteLock provides a lock that allows simultaneous read access.
+ \li QReadLocker and QWriteLocker are convenience classes that automatically
lock and unlock a QReadWriteLock.
- \o QSemaphore provides an integer semaphore (a generalization of a mutex).
- \o QWaitCondition provides a way for threads to go to sleep until
+ \li QSemaphore provides an integer semaphore (a generalization of a mutex).
+ \li QWaitCondition provides a way for threads to go to sleep until
woken up by another thread.
- \o QAtomicInt provides atomic operations on integers.
- \o QAtomicPointer provides atomic operations on pointers.
+ \li QAtomicInt provides atomic operations on integers.
+ \li QAtomicPointer provides atomic operations on pointers.
\endlist
\endomit
@@ -226,10 +226,10 @@
how they can be used in multithread applications:
\list
- \o A \e thread-safe function can be called simultaneously from
+ \li A \e thread-safe function can be called simultaneously from
multiple threads, even when the invocations use shared data,
because all references to the shared data are serialized.
- \o A \e reentrant function can also be called simultaneously from
+ \li A \e reentrant function can also be called simultaneously from
multiple threads, but only if each invocation uses its own data.
\endlist
@@ -267,9 +267,9 @@
Indeed, they usually expand to three machine instructions:
\list 1
- \o Load the variable's value in a register.
- \o Increment or decrement the register's value.
- \o Store the register's value back into main memory.
+ \li Load the variable's value in a register.
+ \li Increment or decrement the register's value.
+ \li Store the register's value back into main memory.
\endlist
If thread A and thread B load the variable's old value
@@ -346,19 +346,19 @@
guaranteed to work. There are three constraints to be aware of:
\list
- \o \e{The child of a QObject must always be created in the thread
+ \li \e{The child of a QObject must always be created in the thread
where the parent was created.} This implies, among other
things, that you should never pass the QThread object (\c
this) as the parent of an object created in the thread (since
the QThread object itself was created in another thread).
- \o \e{Event driven objects may only be used in a single thread.}
+ \li \e{Event driven objects may only be used in a single thread.}
Specifically, this applies to the \l{timers.html}{timer
mechanism} and the \l{QtNetwork}{network module}. For example,
you cannot start a timer or connect a socket in a thread that
is not the \l{QObject::thread()}{object's thread}.
- \o \e{You must ensure that all objects created in a thread are
+ \li \e{You must ensure that all objects created in a thread are
deleted before you delete the QThread.} This can be done
easily by creating the objects on the stack in your
\l{QThread::run()}{run()} implementation.
@@ -469,26 +469,26 @@
\list
- \o \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
+ \li \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
emitted in the thread which the receiving object has affinity then
the behavior is the same as the Direct Connection. Otherwise,
the behavior is the same as the Queued Connection."
- \o \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
+ \li \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
immediately, when the signal is emitted. The slot is executed
in the emitter's thread, which is not necessarily the
receiver's thread.
- \o \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked
+ \li \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked
when control returns to the event loop of the receiver's
thread. The slot is executed in the receiver's thread.
- \o \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection}
+ \li \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection}
The slot is invoked as for the Queued Connection, except the
current thread blocks until the slot returns. \note Using this
type to connect objects in the same thread will cause deadlock.
- \o \l{Qt::UniqueConnection}{Unique Connection} The behavior is the
+ \li \l{Qt::UniqueConnection}{Unique Connection} The behavior is the
same as the Auto Connection, but the connection is made only if
it does not duplicate an existing connection. i.e., if the same
signal is already connected to the same slot for the same pair
@@ -546,33 +546,33 @@
\list
- \o QtConcurrent::map() applies a function to every item in a container,
+ \li QtConcurrent::map() applies a function to every item in a container,
modifying the items in-place.
- \o QtConcurrent::mapped() is like map(), except that it returns a new
+ \li QtConcurrent::mapped() is like map(), except that it returns a new
container with the modifications.
- \o QtConcurrent::mappedReduced() is like mapped(), except that the
+ \li QtConcurrent::mappedReduced() is like mapped(), except that the
modified results are reduced or folded into a single result.
- \o QtConcurrent::filter() removes all items from a container based on the
+ \li QtConcurrent::filter() removes all items from a container based on the
result of a filter function.
- \o QtConcurrent::filtered() is like filter(), except that it returns a new
+ \li QtConcurrent::filtered() is like filter(), except that it returns a new
container with the filtered results.
- \o QtConcurrent::filteredReduced() is like filtered(), except that the
+ \li QtConcurrent::filteredReduced() is like filtered(), except that the
filtered results are reduced or folded into a single result.
- \o QtConcurrent::run() runs a function in another thread.
+ \li QtConcurrent::run() runs a function in another thread.
- \o QFuture represents the result of an asynchronous computation.
+ \li QFuture represents the result of an asynchronous computation.
- \o QFutureIterator allows iterating through results available via QFuture.
+ \li QFutureIterator allows iterating through results available via QFuture.
- \o QFutureWatcher allows monitoring a QFuture using signals-and-slots.
+ \li QFutureWatcher allows monitoring a QFuture using signals-and-slots.
- \o QFutureSynchronizer is a convenience class that automatically
+ \li QFutureSynchronizer is a convenience class that automatically
synchronizes several QFutures.
\endlist
@@ -585,29 +585,29 @@
\table
\header
- \o Iterator Type
- \o Example classes
- \o Support status
+ \li Iterator Type
+ \li Example classes
+ \li Support status
\row
- \o Input Iterator
- \o
- \o Not Supported
+ \li Input Iterator
+ \li
+ \li Not Supported
\row
- \o Output Iterator
- \o
- \o Not Supported
+ \li Output Iterator
+ \li
+ \li Not Supported
\row
- \o Forward Iterator
- \o std::slist
- \o Supported
+ \li Forward Iterator
+ \li std::slist
+ \li Supported
\row
- \o Bidirectional Iterator
- \o QLinkedList, std::list
- \o Supported
+ \li Bidirectional Iterator
+ \li QLinkedList, std::list
+ \li Supported
\row
- \o Random Access Iterator
- \o QList, QVector, std::vector
- \o Supported and Recommended
+ \li Random Access Iterator
+ \li QList, QVector, std::vector
+ \li Supported and Recommended
\endtable
Random access iterators can be faster in cases where Qt Concurrent is iterating
diff --git a/doc/src/examples/addressbook.qdoc b/doc/src/examples/addressbook.qdoc
index 02820307e6c..51712d49d3f 100644
--- a/doc/src/examples/addressbook.qdoc
+++ b/doc/src/examples/addressbook.qdoc
@@ -107,15 +107,15 @@
dimensions of the model. Whereas, \c rowCount()'s value will vary
depending on the number of contacts added to the address book,
\c columnCount()'s value is always 2 because we only need space
- for the \bold Name and \bold Address columns.
+ for the \b Name and \b Address columns.
\note The \c Q_UNUSED() macro prevents the compiler from
generating warnings regarding unused parameters.
\snippet itemviews/addressbook/tablemodel.cpp 1
- The \c data() function returns either a \bold Name or
- \bold {Address}, based on the contents of the model index
+ The \c data() function returns either a \b Name or
+ \b {Address}, based on the contents of the model index
supplied. The row number stored in the model index is used to
reference an item in the list of pairs. Selection is handled
by the QItemSelectionModel, which will be explained with
@@ -124,7 +124,7 @@
\snippet itemviews/addressbook/tablemodel.cpp 2
The \c headerData() function displays the table's header,
- \bold Name and \bold Address. If you require numbered entries
+ \b Name and \b Address. If you require numbered entries
for your address book, you can use a vertical header which we
have hidden in this example (see the \c AddressWidget
implementation).
@@ -372,8 +372,8 @@
menus and actions necessary to manipulate the address book.
\table
- \row \o \inlineimage addressbook-filemenu.png
- \o \inlineimage addressbook-toolsmenu.png
+ \row \li \inlineimage addressbook-filemenu.png
+ \li \inlineimage addressbook-toolsmenu.png
\endtable
\snippet itemviews/addressbook/mainwindow.h 0
diff --git a/doc/src/examples/affine.qdoc b/doc/src/examples/affine.qdoc
index df85576e84a..c01031190aa 100644
--- a/doc/src/examples/affine.qdoc
+++ b/doc/src/examples/affine.qdoc
@@ -39,10 +39,10 @@
in the following ways:
\list
- \o Dragging the red circle in the centre of each drawing moves it to a new position.
- \o Dragging the displaced red circle causes the current drawing to be rotated about the
+ \li Dragging the red circle in the centre of each drawing moves it to a new position.
+ \li Dragging the displaced red circle causes the current drawing to be rotated about the
central circle. Rotation can also be controlled with the \key Rotate slider.
- \o Scaling is controlled with the \key Scale slider.
- \o Each drawing can be sheared with the \key Shear slider.
+ \li Scaling is controlled with the \key Scale slider.
+ \li Each drawing can be sheared with the \key Shear slider.
\endlist
*/
diff --git a/doc/src/examples/arrowpad.qdoc b/doc/src/examples/arrowpad.qdoc
index ee35aa59aec..79bf94c510a 100644
--- a/doc/src/examples/arrowpad.qdoc
+++ b/doc/src/examples/arrowpad.qdoc
@@ -142,18 +142,18 @@
Now, enter the following translations:
\list
- \o \c ArrowPad
+ \li \c ArrowPad
\list
- \o \&Up - \&Haut
- \o \&Left - \&Gauche
- \o \&Right - \&Droite
- \o \&Down - \&Bas
+ \li \&Up - \&Haut
+ \li \&Left - \&Gauche
+ \li \&Right - \&Droite
+ \li \&Down - \&Bas
\endlist
- \o \c MainWindow
+ \li \c MainWindow
\list
- \o E\&xit - \&Quitter
- \o Ctrl+Q - Ctrl+Q
- \o \&File - \&Fichier
+ \li E\&xit - \&Quitter
+ \li Ctrl+Q - Ctrl+Q
+ \li \&File - \&Fichier
\endlist
\endlist
@@ -164,18 +164,18 @@
Save the file and do the same for Dutch working with \c arrowpad_nl.ts:
\list
- \o \c ArrowPad
+ \li \c ArrowPad
\list
- \o \&Up - \&Omhoog
- \o \&Left - \&Links
- \o \&Right - \&Rechts
- \o \&Down - Omlaa\&g
+ \li \&Up - \&Omhoog
+ \li \&Left - \&Links
+ \li \&Right - \&Rechts
+ \li \&Down - Omlaa\&g
\endlist
- \o \c MainWindow
+ \li \c MainWindow
\list
- \o E\&xit - \&Afsluiten
- \o Ctrl+Q - Ctrl+A
- \o File - \&Bestand
+ \li E\&xit - \&Afsluiten
+ \li Ctrl+Q - Ctrl+A
+ \li File - \&Bestand
\endlist
\endlist
diff --git a/doc/src/examples/basicdrawing.qdoc b/doc/src/examples/basicdrawing.qdoc
index 3920811e30e..501b791bc1b 100644
--- a/doc/src/examples/basicdrawing.qdoc
+++ b/doc/src/examples/basicdrawing.qdoc
@@ -53,9 +53,9 @@
The Basic Drawing example consists of two classes:
\list
- \o \c RenderArea is a custom widget that renders multiple
+ \li \c RenderArea is a custom widget that renders multiple
copies of the currently active shape.
- \o \c Window is the application's main window displaying a
+ \li \c Window is the application's main window displaying a
\c RenderArea widget in addition to several parameter widgets.
\endlist
@@ -415,19 +415,19 @@
the associated QPainter drawing function:
\list
- \o QPainter::drawLine(),
- \o QPainter::drawPoints(),
- \o QPainter::drawPolyline(),
- \o QPainter::drawPolygon(),
- \o QPainter::drawRect(),
- \o QPainter::drawRoundedRect(),
- \o QPainter::drawEllipse(),
- \o QPainter::drawArc(),
- \o QPainter::drawChord(),
- \o QPainter::drawPie(),
- \o QPainter::drawPath(),
- \o QPainter::drawText() or
- \o QPainter::drawPixmap()
+ \li QPainter::drawLine(),
+ \li QPainter::drawPoints(),
+ \li QPainter::drawPolyline(),
+ \li QPainter::drawPolygon(),
+ \li QPainter::drawRect(),
+ \li QPainter::drawRoundedRect(),
+ \li QPainter::drawEllipse(),
+ \li QPainter::drawArc(),
+ \li QPainter::drawChord(),
+ \li QPainter::drawPie(),
+ \li QPainter::drawPath(),
+ \li QPainter::drawText() or
+ \li QPainter::drawPixmap()
\endlist
Before we started rendering, we saved the current painter state
diff --git a/doc/src/examples/basicgraphicslayouts.qdoc b/doc/src/examples/basicgraphicslayouts.qdoc
index c1703c3430c..b7023cf9ca7 100644
--- a/doc/src/examples/basicgraphicslayouts.qdoc
+++ b/doc/src/examples/basicgraphicslayouts.qdoc
@@ -57,9 +57,9 @@
We repeat the process:
\list
- \o create a new \c LayoutItem,
- \o add the item \c linear, and
- \o provide a stretch factor.
+ \li create a new \c LayoutItem,
+ \li add the item \c linear, and
+ \li provide a stretch factor.
\endlist
\snippet examples/graphicsview/basicgraphicslayouts/window.cpp 1
diff --git a/doc/src/examples/blockingfortuneclient.qdoc b/doc/src/examples/blockingfortuneclient.qdoc
index 34add534d48..6c3be78859d 100644
--- a/doc/src/examples/blockingfortuneclient.qdoc
+++ b/doc/src/examples/blockingfortuneclient.qdoc
@@ -38,14 +38,14 @@
\list
- \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
and performed when control returns to Qt's event loop. When the operation
is finished, QTcpSocket emits a signal. For example,
QTcpSocket::connectToHost() returns immediately, and when the connection
has been established, QTcpSocket emits
\l{QTcpSocket::connected()}{connected()}.
- \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
applications, you can call the \c waitFor...() functions (e.g.,
QTcpSocket::waitForConnected()) to suspend the calling thread until the
operation has completed, instead of connecting to signals.
diff --git a/doc/src/examples/boxes.qdoc b/doc/src/examples/boxes.qdoc
index f2ca92477ac..aa34a61bc38 100644
--- a/doc/src/examples/boxes.qdoc
+++ b/doc/src/examples/boxes.qdoc
@@ -37,11 +37,11 @@
Elements in the demo can be controlled using the mouse in the following
ways:
\list
- \o Dragging the mouse while pressing the left mouse button rotates the
+ \li Dragging the mouse while pressing the left mouse button rotates the
box in the center.
- \o Dragging the mouse while pressing the right mouse button rotates the
+ \li Dragging the mouse while pressing the right mouse button rotates the
satellite boxes.
- \o Scrolling the mouse wheel zooms in and out of the scene.
+ \li Scrolling the mouse wheel zooms in and out of the scene.
\endlist
The options pane can be used to fine-tune various parameters in the demo,
diff --git a/doc/src/examples/cachedtable.qdoc b/doc/src/examples/cachedtable.qdoc
index d6b0aa5013e..c9945a0efba 100644
--- a/doc/src/examples/cachedtable.qdoc
+++ b/doc/src/examples/cachedtable.qdoc
@@ -66,9 +66,9 @@
in additon to the model and the editor's buttons.
\table 100%
- \header \o Connecting to a Database
+ \header \li Connecting to a Database
\row
- \o
+ \li
Before we can use the \c TableEditor class, we must create a
connection to the database containing the table we want to edit:
@@ -187,8 +187,8 @@
\table 100%
\row
- \o
- \bold {See also:}
+ \li
+ \b {See also:}
A complete list of Qt's SQL \l {Database Classes}, and the \l
{Model/View Programming} documentation.
diff --git a/doc/src/examples/calculator.qdoc b/doc/src/examples/calculator.qdoc
index eb3ccedc355..8eddfa8c4ee 100644
--- a/doc/src/examples/calculator.qdoc
+++ b/doc/src/examples/calculator.qdoc
@@ -38,9 +38,9 @@
The example consists of two classes:
\list
- \o \c Calculator is the calculator widget, with all the
+ \li \c Calculator is the calculator widget, with all the
calculator functionality.
- \o \c Button is the widget used for each of the calculator
+ \li \c Button is the widget used for each of the calculator
button. It derives from QToolButton.
\endlist
@@ -85,18 +85,18 @@
display (a QLineEdit), encode the state of the calculator:
\list
- \o \c sumInMemory contains the value stored in the calculator's memory
+ \li \c sumInMemory contains the value stored in the calculator's memory
(using \gui{MS}, \gui{M+}, or \gui{MC}).
- \o \c sumSoFar stores the value accumulated so far. When the user
+ \li \c sumSoFar stores the value accumulated so far. When the user
clicks \gui{=}, \c sumSoFar is recomputed and shown on the
display. \gui{Clear All} resets \c sumSoFar to zero.
- \o \c factorSoFar stores a temporary value when doing
+ \li \c factorSoFar stores a temporary value when doing
multiplications and divisions.
- \o \c pendingAdditiveOperator stores the last additive operator
+ \li \c pendingAdditiveOperator stores the last additive operator
clicked by the user.
- \o \c pendingMultiplicativeOperator stores the last multiplicative operator
+ \li \c pendingMultiplicativeOperator stores the last multiplicative operator
clicked by the user.
- \o \c waitingForOperand is \c true when the calculator is
+ \li \c waitingForOperand is \c true when the calculator is
expecting the user to start typing an operand.
\endlist
@@ -109,16 +109,16 @@
the user enters a mathematical expression.
\table
- \header \o User Input \o Display \o Sum so Far \o Add. Op. \o Factor so Far \o Mult. Op. \o Waiting for Operand?
- \row \o \o 0 \o 0 \o \o \o \o \c true
- \row \o \gui{1} \o 1 \o 0 \o \o \o \o \c false
- \row \o \gui{1 +} \o 1 \o 1 \o \gui{+} \o \o \o \c true
- \row \o \gui{1 + 2} \o 2 \o 1 \o \gui{+} \o \o \o \c false
- \row \o \gui{1 + 2 \unicode{247}} \o 2 \o 1 \o \gui{+} \o 2 \o \gui{\unicode{247}} \o \c true
- \row \o \gui{1 + 2 \unicode{247} 3} \o 3 \o 1 \o \gui{+} \o 2 \o \gui{\unicode{247}} \o \c false
- \row \o \gui{1 + 2 \unicode{247} 3 -} \o 1.66667 \o 1.66667 \o \gui{-} \o \o \o \c true
- \row \o \gui{1 + 2 \unicode{247} 3 - 4} \o 4 \o 1.66667 \o \gui{-} \o \o \o \c false
- \row \o \gui{1 + 2 \unicode{247} 3 - 4 =} \o -2.33333 \o 0 \o \o \o \o \c true
+ \header \li User Input \li Display \li Sum so Far \li Add. Op. \li Factor so Far \li Mult. Op. \li Waiting for Operand?
+ \row \li \li 0 \li 0 \li \li \li \li \c true
+ \row \li \gui{1} \li 1 \li 0 \li \li \li \li \c false
+ \row \li \gui{1 +} \li 1 \li 1 \li \gui{+} \li \li \li \c true
+ \row \li \gui{1 + 2} \li 2 \li 1 \li \gui{+} \li \li \li \c false
+ \row \li \gui{1 + 2 \unicode{247}} \li 2 \li 1 \li \gui{+} \li 2 \li \gui{\unicode{247}} \li \c true
+ \row \li \gui{1 + 2 \unicode{247} 3} \li 3 \li 1 \li \gui{+} \li 2 \li \gui{\unicode{247}} \li \c false
+ \row \li \gui{1 + 2 \unicode{247} 3 -} \li 1.66667 \li 1.66667 \li \gui{-} \li \li \li \c true
+ \row \li \gui{1 + 2 \unicode{247} 3 - 4} \li 4 \li 1.66667 \li \gui{-} \li \li \li \c false
+ \row \li \gui{1 + 2 \unicode{247} 3 - 4 =} \li -2.33333 \li 0 \li \li \li \li \c true
\endtable
Unary operators, such as \gui Sqrt, require no special handling;
@@ -356,8 +356,8 @@
base class (QToolButton) but modify it in the following ways:
\list
- \o We add 20 to the \l{QSize::height()}{height} component of the size hint.
- \o We make the \l{QSize::width()}{width} component of the size
+ \li We add 20 to the \l{QSize::height()}{height} component of the size hint.
+ \li We make the \l{QSize::width()}{width} component of the size
hint at least as much as the \l{QSize::width()}{height}.
\endlist
diff --git a/doc/src/examples/calendar.qdoc b/doc/src/examples/calendar.qdoc
index d06bed7c6f5..aea98056698 100644
--- a/doc/src/examples/calendar.qdoc
+++ b/doc/src/examples/calendar.qdoc
@@ -37,10 +37,10 @@
Specifically, the example demonstrates the following:
\list
- \o Use of a text editor with a text document
- \o Insertion of tables and frames into a document
- \o Navigation within a table
- \o Insert text in different styles
+ \li Use of a text editor with a text document
+ \li Insertion of tables and frames into a document
+ \li Navigation within a table
+ \li Insert text in different styles
\endlist
The rich text editor used to display the document is used within a main window
diff --git a/doc/src/examples/calendarwidget.qdoc b/doc/src/examples/calendarwidget.qdoc
index 7ef99bfc658..0dd20b14910 100644
--- a/doc/src/examples/calendarwidget.qdoc
+++ b/doc/src/examples/calendarwidget.qdoc
@@ -51,28 +51,28 @@
below.
\table
- \header \o Property
- \o Description
- \row \o \l{QCalendarWidget::}{selectedDate}
- \o The currently selected date.
- \row \o \l{QCalendarWidget::}{minimumDate}
- \o The earliest date that can be selected.
- \row \o \l{QCalendarWidget::}{maximumDate}
- \o The latest date that can be selected.
- \row \o \l{QCalendarWidget::}{firstDayOfWeek}
- \o The day that is displayed as the first day of the week
+ \header \li Property
+ \li Description
+ \row \li \l{QCalendarWidget::}{selectedDate}
+ \li The currently selected date.
+ \row \li \l{QCalendarWidget::}{minimumDate}
+ \li The earliest date that can be selected.
+ \row \li \l{QCalendarWidget::}{maximumDate}
+ \li The latest date that can be selected.
+ \row \li \l{QCalendarWidget::}{firstDayOfWeek}
+ \li The day that is displayed as the first day of the week
(usually Sunday or Monday).
- \row \o \l{QCalendarWidget::}{gridVisible}
- \o Whether the grid should be shown.
- \row \o \l{QCalendarWidget::}{selectionMode}
- \o Whether the user can select a date or not.
- \row \o \l{QCalendarWidget::}{horizontalHeaderFormat}
- \o The format of the day names in the horizontal header
+ \row \li \l{QCalendarWidget::}{gridVisible}
+ \li Whether the grid should be shown.
+ \row \li \l{QCalendarWidget::}{selectionMode}
+ \li Whether the user can select a date or not.
+ \row \li \l{QCalendarWidget::}{horizontalHeaderFormat}
+ \li The format of the day names in the horizontal header
(e.g., "M", "Mon", or "Monday").
- \row \o \l{QCalendarWidget::}{verticalHeaderFormat}
- \o The format of the vertical header.
- \row \o \l{QCalendarWidget::}{navigationBarVisible}
- \o Whether the navigation bar at the top of the calendar
+ \row \li \l{QCalendarWidget::}{verticalHeaderFormat}
+ \li The format of the vertical header.
+ \row \li \l{QCalendarWidget::}{navigationBarVisible}
+ \li Whether the navigation bar at the top of the calendar
widget is shown.
\endtable
diff --git a/doc/src/examples/charactermap.qdoc b/doc/src/examples/charactermap.qdoc
index 33652118ef2..5fbcae1fad7 100644
--- a/doc/src/examples/charactermap.qdoc
+++ b/doc/src/examples/charactermap.qdoc
@@ -43,9 +43,9 @@ that may be unavailable or difficult to locate on their keyboards.
The example consists of the following classes:
\list
-\i \c CharacterWidget displays the available characters in the current
+\li \c CharacterWidget displays the available characters in the current
font and style.
-\i \c MainWindow provides a standard main window that contains font and
+\li \c MainWindow provides a standard main window that contains font and
style information, a view onto the characters, a line edit, and a push
button for submitting text to the clipboard.
\endlist
diff --git a/doc/src/examples/chart.qdoc b/doc/src/examples/chart.qdoc
index 565b1c6c7dd..947eddf1c96 100644
--- a/doc/src/examples/chart.qdoc
+++ b/doc/src/examples/chart.qdoc
@@ -37,7 +37,7 @@
relying on the flexibility of the model/view architecture to handle custom editing
and selection features.
- \bold{Note that you only need to create a new view class if your data requires a
+ \b{Note that you only need to create a new view class if your data requires a
specialized representation.} You should first consider using a standard QListView,
QTableView, or QTreeView with a custom QItemDelegate subclass if you need to
represent data in a special way.
@@ -61,10 +61,10 @@
We interpret the data in the following way:
\list
- \o Column 0 contains data in two different roles:
+ \li Column 0 contains data in two different roles:
The \l{Qt::ItemDataRole}{DisplayRole} contains a label, and the
\l{Qt::ItemDataRole}{DecorationRole} contains the color of the pie slice.
- \o Column 1 contains a quantity which we will convert to the angular extent of
+ \li Column 1 contains a quantity which we will convert to the angular extent of
the slice.
\endlist
diff --git a/doc/src/examples/classwizard.qdoc b/doc/src/examples/classwizard.qdoc
index 0fad22e56a2..8f84193f2ee 100644
--- a/doc/src/examples/classwizard.qdoc
+++ b/doc/src/examples/classwizard.qdoc
@@ -44,10 +44,10 @@
The Class Wizard example consists of the following classes:
\list
- \o \c ClassWizard inherits QWizard and provides a
+ \li \c ClassWizard inherits QWizard and provides a
three-step wizard that generates the skeleton of a C++ class
based on the user's input.
- \o \c IntroPage, \c ClassInfoPage, \c CodeStylePage, \c
+ \li \c IntroPage, \c ClassInfoPage, \c CodeStylePage, \c
OutputFilesPage, and \c ConclusionPage are QWizardPage
subclasses that implement the wizard pages.
\endlist
@@ -61,17 +61,17 @@
five pages:
\list
- \o The first page is an introduction page, telling the user what
+ \li The first page is an introduction page, telling the user what
the wizard is going to do.
- \o The second page asks for a class name and a base class, and
+ \li The second page asks for a class name and a base class, and
allows the user to specify whether the class should have a \c
Q_OBJECT macro and what constructors it should provide.
- \o The third page allows the user to set some options related to the code
+ \li The third page allows the user to set some options related to the code
style, such as the macro used to protect the header file from
multiple inclusion (e.g., \c MYDIALOG_H).
- \o The fourth page allows the user to specify the names of the
+ \li The fourth page allows the user to specify the names of the
output files.
- \o The fifth page is a conclusion page.
+ \li The fifth page is a conclusion page.
\endlist
Although the program is just an example, if you press \gui Finish
diff --git a/doc/src/examples/coloreditorfactory.qdoc b/doc/src/examples/coloreditorfactory.qdoc
index 741db7e3873..1806446fb75 100644
--- a/doc/src/examples/coloreditorfactory.qdoc
+++ b/doc/src/examples/coloreditorfactory.qdoc
@@ -134,16 +134,16 @@
Possible suggestions are:
\list
- \o If the editor widget has no user property defined, the delegate
+ \li If the editor widget has no user property defined, the delegate
asks the factory for the property name, which it in turn
asks the item editor creator for. In this case, you can use
the QItemEditorCreator class, which takes the property
name to use for editing as a constructor argument.
- \o If the editor requires other constructors or other
+ \li If the editor requires other constructors or other
initialization than provided by QItemEditorCreatorBase, you
must reimplement
QItemEditorCreatorBase::createWidget().
- \o You could also subclass QItemEditorFactory if you only want
+ \li You could also subclass QItemEditorFactory if you only want
to provide editors for certain kinds of data or use another
method of creating the editors than using creator bases.
\endlist
diff --git a/doc/src/examples/completer.qdoc b/doc/src/examples/completer.qdoc
index 767efe8ef1b..df832de4d63 100644
--- a/doc/src/examples/completer.qdoc
+++ b/doc/src/examples/completer.qdoc
@@ -77,8 +77,8 @@
The screenshots below illustrate this difference:
\table
- \row \o \inlineimage completer-example-qdirmodel.png
- \o \inlineimage completer-example-dirmodel.png
+ \row \li \inlineimage completer-example-qdirmodel.png
+ \li \inlineimage completer-example-dirmodel.png
\endtable
The Qt::EditRole, which QCompleter uses to look for matches, is left
diff --git a/doc/src/examples/composition.qdoc b/doc/src/examples/composition.qdoc
index 1da41dbfef5..6aca01d2558 100644
--- a/doc/src/examples/composition.qdoc
+++ b/doc/src/examples/composition.qdoc
@@ -33,10 +33,10 @@
\image composition-demo.png
- The two most common forms of composition are \bold{Source} and \bold{SourceOver}.
- \bold{Source} is used to draw opaque objects onto a paint device. In this mode,
+ The two most common forms of composition are \b{Source} and \b{SourceOver}.
+ \b{Source} is used to draw opaque objects onto a paint device. In this mode,
each pixel in the source replaces the corresponding pixel in the destination.
- In \bold{SourceOver} composition mode, the source object is transparent and is
+ In \b{SourceOver} composition mode, the source object is transparent and is
drawn on top of the destination.
In addition to these standard modes, Qt defines the complete set of composition modes
diff --git a/doc/src/examples/concentriccircles.qdoc b/doc/src/examples/concentriccircles.qdoc
index 73b49370494..22b0be8fb83 100644
--- a/doc/src/examples/concentriccircles.qdoc
+++ b/doc/src/examples/concentriccircles.qdoc
@@ -59,9 +59,9 @@
The example consists of two classes:
\list
- \o \c CircleWidget is a custom widget which renders several animated
+ \li \c CircleWidget is a custom widget which renders several animated
concentric circles.
- \o \c Window is the application's main window displaying four \c
+ \li \c Window is the application's main window displaying four \c
{CircleWidget}s drawn using different combinations of precision
and aliasing.
\endlist
diff --git a/doc/src/examples/cube.qdoc b/doc/src/examples/cube.qdoc
index 3c418562540..ec40be0f45d 100644
--- a/doc/src/examples/cube.qdoc
+++ b/doc/src/examples/cube.qdoc
@@ -61,9 +61,9 @@
The example consist of two classes:
\list
- \o \c MainWidget extends QGLWidget and contains OpenGL ES 2.0
+ \li \c MainWidget extends QGLWidget and contains OpenGL ES 2.0
initialization and drawing and mouse and timer event handling
- \o \c GeometryEngine handles polygon geometries. Transfers polygon geometry
+ \li \c GeometryEngine handles polygon geometries. Transfers polygon geometry
to vertex buffer objects and draws geometries from vertex buffer objects.
\endlist
diff --git a/doc/src/examples/customsortfiltermodel.qdoc b/doc/src/examples/customsortfiltermodel.qdoc
index ac9fbb93a3b..61230a7b9a8 100644
--- a/doc/src/examples/customsortfiltermodel.qdoc
+++ b/doc/src/examples/customsortfiltermodel.qdoc
@@ -48,10 +48,10 @@
\list
- \o The \c MySortFilterProxyModel class provides a custom proxy
+ \li The \c MySortFilterProxyModel class provides a custom proxy
model.
- \o The \c Window class provides the main application window,
+ \li The \c Window class provides the main application window,
using the custom proxy model to sort and filter a standard
item model.
diff --git a/doc/src/examples/dbscreen.qdoc b/doc/src/examples/dbscreen.qdoc
index 7d9cea5519a..bfecb9a3cbc 100644
--- a/doc/src/examples/dbscreen.qdoc
+++ b/doc/src/examples/dbscreen.qdoc
@@ -36,13 +36,13 @@
to writing and implementing this graphics driver:
\list 1
- \o \l {Step 1: Creating a Custom Graphics Driver}
+ \li \l {Step 1: Creating a Custom Graphics Driver}
{Creating a Custom Graphics Driver}
- \o \l {Step 2: Implementing the Back Buffer}
+ \li \l {Step 2: Implementing the Back Buffer}
{Implementing the Back Buffer}
- \o \l {Step 3: Creating the Driver Plugin}
+ \li \l {Step 3: Creating the Driver Plugin}
{Creating the Driver Plugin}
\endlist
@@ -71,11 +71,11 @@
functions belonging to QScreen:
\list
- \o \l{QScreen::initDevice()}{initDevice()},
- \o \l{QScreen::shutdownDevice()}{shutdownDevice()},
- \o \l{QScreen::blit()}{blit()},
- \o \l{QScreen::solidFill()}{solidFill()}, and
- \o \l{QScreen::exposeRegion()}{exposeRegion()}.
+ \li \l{QScreen::initDevice()}{initDevice()},
+ \li \l{QScreen::shutdownDevice()}{shutdownDevice()},
+ \li \l{QScreen::blit()}{blit()},
+ \li \l{QScreen::solidFill()}{solidFill()}, and
+ \li \l{QScreen::exposeRegion()}{exposeRegion()}.
\endlist
\snippet examples/qws/dbscreen/dbscreen.h 0
@@ -89,10 +89,10 @@
The graphics driver must carry out three main functions:
\list 1
- \o Allocate the back buffer on startup and deallocate it on shutdown.
- \o Draw to the back buffer instead of directly to the screen
+ \li Allocate the back buffer on startup and deallocate it on shutdown.
+ \li Draw to the back buffer instead of directly to the screen
(which is what QLinuxFbScreen does).
- \o Copy the back buffer to the screen whenever a screen update is
+ \li Copy the back buffer to the screen whenever a screen update is
done.
\endlist
@@ -165,9 +165,9 @@
There are only two functions to reimplement:
\list
- \o \l{QScreenDriverPlugin::create()}{create()} - creates a driver
+ \li \l{QScreenDriverPlugin::create()}{create()} - creates a driver
matching the given key
- \o \l{QScreenDriverPlugin::create()}{keys()} - returns a list of
+ \li \l{QScreenDriverPlugin::create()}{keys()} - returns a list of
valid keys representing the drivers supported by the plugin
\endlist
diff --git a/doc/src/examples/diagramscene.qdoc b/doc/src/examples/diagramscene.qdoc
index 9f2a8f8b765..ac9ca2f2945 100644
--- a/doc/src/examples/diagramscene.qdoc
+++ b/doc/src/examples/diagramscene.qdoc
@@ -55,28 +55,28 @@
In particular we show how to:
\list
- \o Create custom graphics items.
- \o Handle mouse events and movement of items.
- \o Implement a graphics scene that can manage our custom items.
- \o Custom painting of items.
- \o Create a movable and editable text item.
+ \li Create custom graphics items.
+ \li Handle mouse events and movement of items.
+ \li Implement a graphics scene that can manage our custom items.
+ \li Custom painting of items.
+ \li Create a movable and editable text item.
\endlist
The example consists of the following classes:
\list
- \o \c MainWindow creates the widgets and display
+ \li \c MainWindow creates the widgets and display
them in a QMainWindow. It also manages the interaction
between the widgets and the graphics scene, view and
items.
- \o \c DiagramItem inherits QGraphicsPolygonItem and
+ \li \c DiagramItem inherits QGraphicsPolygonItem and
represents a flowchart shape.
- \o \c TextDiagramItem inherits QGraphicsTextItem and
+ \li \c TextDiagramItem inherits QGraphicsTextItem and
represents text items in the diagram. The class adds
support for moving the item with the mouse, which is not
supported by QGraphicsTextItem.
- \o \c Arrow inherits QGraphicsLineItem and is an arrow
+ \li \c Arrow inherits QGraphicsLineItem and is an arrow
that connect two DiagramItems.
- \o \c DiagramScene inherits QGraphicsDiagramScene and
+ \li \c DiagramScene inherits QGraphicsDiagramScene and
provides support for \c DiagramItem, \c Arrow and
\c DiagramTextItem (In addition to the support already
handled by QGraphicsScene).
diff --git a/doc/src/examples/drilldown.qdoc b/doc/src/examples/drilldown.qdoc
index 1e7b8c01d6d..7f195d52617 100644
--- a/doc/src/examples/drilldown.qdoc
+++ b/doc/src/examples/drilldown.qdoc
@@ -45,13 +45,13 @@
The example consists of three classes:
\list
- \o \c ImageItem is a custom graphics item class used to
+ \li \c ImageItem is a custom graphics item class used to
display the office images.
- \o \c View is the main application widget allowing the user to
+ \li \c View is the main application widget allowing the user to
browse through the various locations.
- \o \c InformationWindow displays the requested information,
+ \li \c InformationWindow displays the requested information,
allowing the users to alter it and submit their changes to the
database.
\endlist
diff --git a/doc/src/examples/dropsite.qdoc b/doc/src/examples/dropsite.qdoc
index 024d191b740..77b40986aa1 100644
--- a/doc/src/examples/dropsite.qdoc
+++ b/doc/src/examples/dropsite.qdoc
@@ -53,10 +53,10 @@
reimplementations of four \l{QWidget} event handlers:
\list 1
- \o \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
- \o \l{QWidget::dragMoveEvent()}{dragMoveEvent()}
- \o \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()}
- \o \l{QWidget::dropEvent()}{dropEvent()}
+ \li \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
+ \li \l{QWidget::dragMoveEvent()}{dragMoveEvent()}
+ \li \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()}
+ \li \l{QWidget::dropEvent()}{dropEvent()}
\endlist
These event handlers are further explained in the implementation of the
@@ -108,17 +108,17 @@
\snippet draganddrop/dropsite/droparea.cpp dropEvent() function part2
\list
- \o If \c mimeData contains an image, we display it in \c DropArea with
+ \li If \c mimeData contains an image, we display it in \c DropArea with
\l{QLabel::setPixmap()}{setPixmap()}.
- \o If \c mimeData contains HTML, we display it with
+ \li If \c mimeData contains HTML, we display it with
\l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format
as Qt::RichText.
- \o If \c mimeData contains plain text, we display it with
+ \li If \c mimeData contains plain text, we display it with
\l{QLabel::setText()}{setText()} and set \c{DropArea}'s text format
as Qt::PlainText. In the event that \c mimeData contains URLs, we
iterate through the list of URLs to display them on individual
lines.
- \o If \c mimeData contains other types of objects, we set
+ \li If \c mimeData contains other types of objects, we set
\c{DropArea}'s text, with \l{QLabel::setText()}{setText()} to
"Cannot display data" to inform the user.
\endlist
diff --git a/doc/src/examples/editabletreemodel.qdoc b/doc/src/examples/editabletreemodel.qdoc
index 306295842eb..958080ad586 100644
--- a/doc/src/examples/editabletreemodel.qdoc
+++ b/doc/src/examples/editabletreemodel.qdoc
@@ -82,8 +82,8 @@
\target Relations-between-internal-items
\table
- \row \o \inlineimage itemviews-editabletreemodel-items.png
- \o \bold{Relations between internal items}
+ \row \li \inlineimage itemviews-editabletreemodel-items.png
+ \li \b{Relations between internal items}
When designing a data structure for use with a custom model, it is useful
to expose each item's parent via a function like
@@ -99,10 +99,10 @@
\l{TreeItem::parent}{parent()} and \l{TreeItem::child}{child()}
functions.
- In the example shown, two top-level items, \bold{A} and
- \bold{B}, can be obtained from the root item by calling its child()
+ In the example shown, two top-level items, \b{A} and
+ \b{B}, can be obtained from the root item by calling its child()
function, and each of these items return the root node from their
- parent() functions, though this is only shown for item \bold{A}.
+ parent() functions, though this is only shown for item \b{A}.
\endtable
Each \c TreeItem stores data for each column in the row it represents
@@ -126,23 +126,23 @@
horizontal header titles.
\table
- \row \o \inlineimage itemviews-editabletreemodel-model.png
- \o \bold{Accessing data via the model}
+ \row \li \inlineimage itemviews-editabletreemodel-model.png
+ \li \b{Accessing data via the model}
In the case shown in the diagram, the piece of information represented
- by \bold{a} can be obtained using the standard model/view API:
+ by \b{a} can be obtained using the standard model/view API:
\snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.cpp 0
Since each items holds pieces of data for each column in a given row,
there can be many model indexes that map to the same \c TreeItem object.
- For example, the information represented by \bold{b} can be obtained
+ For example, the information represented by \b{b} can be obtained
using the following code:
\snippet doc/src/snippets/code/doc_src_examples_editabletreemodel.cpp 1
The same underlying \c TreeItem would be accessed to obtain information
- for the other model indexes in the same row as \bold{b}.
+ for the other model indexes in the same row as \b{b}.
\endtable
In the model class, \c TreeModel, we relate \c TreeItem objects to
@@ -166,20 +166,20 @@
that the model does not attempt to access items that have been deleted.
\table
- \row \o \bold{Storing information in the underlying data structure}
+ \row \li \b{Storing information in the underlying data structure}
Several pieces of data are stored as QVariant objects in the \c itemData
member of each \c TreeItem instance
The diagram shows how pieces of information,
- represented by the labels \bold{a}, \bold{b} and \bold{c} in the
- previous two diagrams, are stored in items \bold{A}, \bold{B} and
- \bold{C} in the underlying data structure. Note that pieces of
+ represented by the labels \b{a}, \b{b} and \b{c} in the
+ previous two diagrams, are stored in items \b{A}, \b{B} and
+ \b{C} in the underlying data structure. Note that pieces of
information from the same row in the model are all obtained from the
same item. Each element in a list corresponds to a piece of information
exposed by each column in a given row in the model.
- \o \inlineimage itemviews-editabletreemodel-values.png
+ \li \inlineimage itemviews-editabletreemodel-values.png
\endtable
Since the \c TreeModel implementation has been designed for use with
@@ -202,8 +202,8 @@
\target Relating-items-using-model-indexes
\table
\row
- \o \inlineimage itemviews-editabletreemodel-indexes.png
- \o \bold{Relating items using model indexes}
+ \li \inlineimage itemviews-editabletreemodel-indexes.png
+ \li \b{Relating items using model indexes}
As with the \l{itemviews/simpletreemodel}{Simple Tree Model} example,
the \c TreeModel needs to be able to take a model index, find the
@@ -215,13 +215,13 @@
an item supplied by the caller, using the items shown in a
\l{Relations-between-internal-items}{previous diagram}.
- A pointer to item \bold{C} is obtained from the corresponding model index
+ A pointer to item \b{C} is obtained from the corresponding model index
using the \l{QModelIndex::internalPointer()} function. The pointer was
stored internally in the index when it was created. Since the child
contains a pointer to its parent, we use its \l{TreeItem::parent}{parent()}
- function to obtain a pointer to item \bold{B}. The parent model index is
+ function to obtain a pointer to item \b{B}. The parent model index is
created using the QAbstractItemModel::createIndex() function, passing
- the pointer to item \bold{B} as the internal pointer.
+ the pointer to item \b{B} as the internal pointer.
\endtable
\section1 TreeItem Class Definition
diff --git a/doc/src/examples/elasticnodes.qdoc b/doc/src/examples/elasticnodes.qdoc
index 51a0a6048a1..bd25008f60a 100644
--- a/doc/src/examples/elasticnodes.qdoc
+++ b/doc/src/examples/elasticnodes.qdoc
@@ -54,9 +54,9 @@
The \c Node class serves three purposes:
\list
- \o Painting a yellow gradient "ball" in two states: sunken and raised.
- \o Managing connections to other nodes.
- \o Calculating forces pulling and pushing the nodes in the grid.
+ \li Painting a yellow gradient "ball" in two states: sunken and raised.
+ \li Managing connections to other nodes.
+ \li Calculating forces pulling and pushing the nodes in the grid.
\endlist
Let's start by looking at the \c Node class declaration.
diff --git a/doc/src/examples/fortuneclient.qdoc b/doc/src/examples/fortuneclient.qdoc
index f2c6fa02d90..d997fc077ee 100644
--- a/doc/src/examples/fortuneclient.qdoc
+++ b/doc/src/examples/fortuneclient.qdoc
@@ -47,14 +47,14 @@
\list
- \o \e{The asynchronous (non-blocking) approach.} Operations are scheduled
+ \li \e{The asynchronous (non-blocking) approach.} Operations are scheduled
and performed when control returns to Qt's event loop. When the operation
is finished, QTcpSocket emits a signal. For example,
QTcpSocket::connectToHost() returns immediately, and when the connection
has been established, QTcpSocket emits
\l{QTcpSocket::connected()}{connected()}.
- \o \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
+ \li \e{The synchronous (blocking) approach.} In non-GUI and multithreaded
applications, you can call the \c waitFor...() functions (e.g.,
QTcpSocket::waitForConnected()) to suspend the calling thread until the
operation has completed, instead of connecting to signals.
@@ -107,11 +107,11 @@
one of two things can happen:
\list
- \o \e{The connection is established.} In this case, the server will send us a
+ \li \e{The connection is established.} In this case, the server will send us a
fortune. QTcpSocket will emit \l{QTcpSocket::readyRead()}{readyRead()}
every time it receives a block of data.
- \o \e{An error occurs.} We need to inform the user if the connection
+ \li \e{An error occurs.} We need to inform the user if the connection
failed or was broken. In this case, QTcpSocket will emit
\l{QTcpSocket::error()}{error()}, and \c Client::displayError() will be
called.
diff --git a/doc/src/examples/fridgemagnets.qdoc b/doc/src/examples/fridgemagnets.qdoc
index b2bd4407073..7b7218bba20 100644
--- a/doc/src/examples/fridgemagnets.qdoc
+++ b/doc/src/examples/fridgemagnets.qdoc
@@ -39,9 +39,9 @@
the words on the magnets. The example consists of two classes:
\list
- \o \c DragLabel is a custom widget representing one
+ \li \c DragLabel is a custom widget representing one
single fridge magnet.
- \o \c DragWidget provides the main application window.
+ \li \c DragWidget provides the main application window.
\endlist
We will first take a look at the \c DragLabel class, then we will
diff --git a/doc/src/examples/gradients.qdoc b/doc/src/examples/gradients.qdoc
index 75876fdf2c1..75f78b56ea1 100644
--- a/doc/src/examples/gradients.qdoc
+++ b/doc/src/examples/gradients.qdoc
@@ -37,10 +37,10 @@
There are three types of gradients:
\list
- \o \bold{Linear} gradients interpolate colors between start and end points.
- \o \bold{Radial} gradients interpolate colors between a focal point and the
+ \li \b{Linear} gradients interpolate colors between start and end points.
+ \li \b{Radial} gradients interpolate colors between a focal point and the
points on a circle surrounding it.
- \o \bold{Conical} gradients interpolate colors around a center point.
+ \li \b{Conical} gradients interpolate colors around a center point.
\endlist
The panel on the right contains a color table editor that defines
diff --git a/doc/src/examples/hellogl.qdoc b/doc/src/examples/hellogl.qdoc
index a0b6fc6c065..f6f8591ad0f 100644
--- a/doc/src/examples/hellogl.qdoc
+++ b/doc/src/examples/hellogl.qdoc
@@ -285,12 +285,12 @@
by reimplementing the following functions:
\list
- \o QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation
+ \li QGLWidget::initializeGL() sets up resources needed by the OpenGL implementation
to render the scene.
- \o QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto
+ \li QGLWidget::resizeGL() resizes the viewport so that the rendered scene fits onto
the widget, and sets up a projection matrix to map 3D coordinates to 2D viewport
coordinates.
- \o QGLWidget::paintGL() performs painting operations using OpenGL calls.
+ \li QGLWidget::paintGL() performs painting operations using OpenGL calls.
\endlist
Since QGLWidget is a subclass of QWidget, it can also be used
diff --git a/doc/src/examples/icons.qdoc b/doc/src/examples/icons.qdoc
index be7b0dd46ce..9e7dda7c89a 100644
--- a/doc/src/examples/icons.qdoc
+++ b/doc/src/examples/icons.qdoc
@@ -47,24 +47,24 @@
of the icon. Qt currently defines four modes:
\table
- \header \o Mode \o Description
+ \header \li Mode \li Description
\row
- \o QIcon::Normal
- \o Display the pixmap when the user is not interacting with the
+ \li QIcon::Normal
+ \li Display the pixmap when the user is not interacting with the
icon, but the functionality represented by the icon is
available.
\row
- \o QIcon::Active
- \o Display the pixmap when the functionality represented by the
+ \li QIcon::Active
+ \li Display the pixmap when the functionality represented by the
icon is available and the user is interacting with the icon,
for example, moving the mouse over it or clicking it.
\row
- \o QIcon::Disabled
- \o Display the pixmap when the functionality represented by
+ \li QIcon::Disabled
+ \li Display the pixmap when the functionality represented by
the icon is not available.
\row
- \o QIcon::Selected
- \o Display the pixmap when the icon is selected.
+ \li QIcon::Selected
+ \li Display the pixmap when the icon is selected.
\endtable
QIcon's states are QIcon::On and QIcon::Off, which will display
@@ -148,16 +148,16 @@
search algorithm described in the table below:
\table 100%
- \header \o{2,1} Requested Pixmap \o {8,1} Preferred Alternatives (mode/state)
- \header \o Mode \o State \o 1 \o 2 \o 3 \o 4 \o 5 \o 6 \o 7 \o 8
- \row \o{1,2} Normal \o Off \o \bold N0 \o A0 \o N1 \o A1 \o D0 \o S0 \o D1 \o S1
- \row \o On \o N1 \o \bold A1 \o N0 \o A0 \o D1 \o S1 \o D0 \o S0
- \row \o{1,2} Active \o Off \o A0 \o \bold N0 \o A1 \o N1 \o D0 \o S0 \o D1 \o S1
- \row \o On \o \bold A1 \o N1 \o A0 \o N0 \o D1 \o S1 \o D0 \o S0
- \row \o{1,2} Disabled \o Off \o D0 \o \bold {N0'} \o A0' \o D1 \o N1' \o A1' \o S0' \o S1'
- \row \o On \o D1 \o N1' \o \bold {A1'} \o D0 \o N0' \o A0' \o S1' \o S0'
- \row \o{1,2} Selected \o Off \o S0 \o \bold {N0''} \o A0'' \o S1 \o N1'' \o A1'' \o D0'' \o D1''
- \row \o On \o S1 \o N1'' \o \bold {A1''} \o S0 \o N0'' \o A0'' \o D1'' \o D0''
+ \header \li{2,1} Requested Pixmap \li {8,1} Preferred Alternatives (mode/state)
+ \header \li Mode \li State \li 1 \li 2 \li 3 \li 4 \li 5 \li 6 \li 7 \li 8
+ \row \li{1,2} Normal \li Off \li \b N0 \li A0 \li N1 \li A1 \li D0 \li S0 \li D1 \li S1
+ \row \li On \li N1 \li \b A1 \li N0 \li A0 \li D1 \li S1 \li D0 \li S0
+ \row \li{1,2} Active \li Off \li A0 \li \b N0 \li A1 \li N1 \li D0 \li S0 \li D1 \li S1
+ \row \li On \li \b A1 \li N1 \li A0 \li N0 \li D1 \li S1 \li D0 \li S0
+ \row \li{1,2} Disabled \li Off \li D0 \li \b {N0'} \li A0' \li D1 \li N1' \li A1' \li S0' \li S1'
+ \row \li On \li D1 \li N1' \li \b {A1'} \li D0 \li N0' \li A0' \li S1' \li S0'
+ \row \li{1,2} Selected \li Off \li S0 \li \b {N0''} \li A0'' \li S1 \li N1'' \li A1'' \li D0'' \li D1''
+ \row \li On \li S1 \li N1'' \li \b {A1''} \li S0 \li N0'' \li A0'' \li D1'' \li D0''
\endtable
In the table, "0" and "1" stand for Off" and "On", respectively.
@@ -176,8 +176,8 @@
\table
\row
- \o \inlineimage icons_monkey.png Screenshot of the Monkey Files
- \o \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files
+ \li \inlineimage icons_monkey.png Screenshot of the Monkey Files
+ \li \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files
\endtable
For any given mode/state combination, it is possible to specify
@@ -193,25 +193,25 @@
\table
\row
- \o
- \o \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
- \o \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
- \o \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
+ \li
+ \li \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
+ \li \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
+ \li \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
\row
- \o
- \o 8 x 8
- \o \bold {16 x 16}
- \o 17 x 17
+ \li
+ \li 8 x 8
+ \li \b {16 x 16}
+ \li 17 x 17
\row
- \o \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
- \o \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
- \o \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
- \o \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
+ \li \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
+ \li \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
+ \li \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
+ \li \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
\row
- \o \bold {32 x 32}
- \o 33 x 33
- \o \bold {48 x 48}
- \o 64 x 64
+ \li \b {32 x 32}
+ \li 33 x 33
+ \li \b {48 x 48}
+ \li 64 x 64
\endtable
For sizes up to 16 x 16, QIcon uses \c qt_extended_16x16.png and
@@ -224,13 +224,13 @@
The Icons example consists of four classes:
\list
- \o \c MainWindow inherits QMainWindow and is the main application
+ \li \c MainWindow inherits QMainWindow and is the main application
window.
- \o \c IconPreviewArea is a custom widget that displays all
+ \li \c IconPreviewArea is a custom widget that displays all
combinations of states and modes for a given icon.
- \o \c IconSizeSpinBox is a subclass of QSpinBox that lets the
+ \li \c IconSizeSpinBox is a subclass of QSpinBox that lets the
user enter icon sizes (e.g., "48 x 48").
- \o \c ImageDelegate is a subclass of QItemDelegate that provides
+ \li \c ImageDelegate is a subclass of QItemDelegate that provides
comboboxes for letting the user set the mode and state
associated with an image.
\endlist
@@ -332,13 +332,13 @@
constructor, and declare several private slots:
\list
- \o The \c about() slot simply provides information about the example.
- \o The \c changeStyle() slot changes the application's GUI style and
+ \li The \c about() slot simply provides information about the example.
+ \li The \c changeStyle() slot changes the application's GUI style and
adjust the style dependent size options.
- \o The \c changeSize() slot changes the size of the preview area's icon.
- \o The \c changeIcon() slot updates the set of pixmaps available to the
+ \li The \c changeSize() slot changes the size of the preview area's icon.
+ \li The \c changeIcon() slot updates the set of pixmaps available to the
icon displayed in the preview area.
- \o The \c addImage() slot allows the user to load a new image into the
+ \li The \c addImage() slot allows the user to load a new image into the
application.
\endlist
diff --git a/doc/src/examples/imagecomposition.qdoc b/doc/src/examples/imagecomposition.qdoc
index edefcface46..d7700858a0b 100644
--- a/doc/src/examples/imagecomposition.qdoc
+++ b/doc/src/examples/imagecomposition.qdoc
@@ -86,11 +86,11 @@
We connect the following signals to their corresponding slots:
\list
- \o \c{sourceButton}'s \l{QPushButton::clicked()}{clicked()} signal is
+ \li \c{sourceButton}'s \l{QPushButton::clicked()}{clicked()} signal is
connected to \c chooseSource(),
- \o \c{operatorComboBox}'s \l{QComboBox::activated()}{activated()}
+ \li \c{operatorComboBox}'s \l{QComboBox::activated()}{activated()}
signal is connected to \c recalculateResult(), and
- \o \c{destinationButton}'s \l{QToolButton::clicked()}{clicked()} signal
+ \li \c{destinationButton}'s \l{QToolButton::clicked()}{clicked()} signal
is connected to \c chooseDestination().
\endlist
diff --git a/doc/src/examples/imageviewer.qdoc b/doc/src/examples/imageviewer.qdoc
index 18cdccb5eda..638c0c3fb48 100644
--- a/doc/src/examples/imageviewer.qdoc
+++ b/doc/src/examples/imageviewer.qdoc
@@ -49,18 +49,18 @@
to:
\list
- \o \gui{Open...} - Open an image file
- \o \gui{Print...} - Print an image
- \o \gui{Exit} - Exit the application
+ \li \gui{Open...} - Open an image file
+ \li \gui{Print...} - Print an image
+ \li \gui{Exit} - Exit the application
\endlist
Once an image is loaded, the \gui View menu allows the users to:
\list
- \o \gui{Zoom In} - Scale the image up by 25%
- \o \gui{Zoom Out} - Scale the image down by 25%
- \o \gui{Normal Size} - Show the image at its original size
- \o \gui{Fit to Window} - Stretch the image to occupy the entire window
+ \li \gui{Zoom In} - Scale the image up by 25%
+ \li \gui{Zoom Out} - Scale the image down by 25%
+ \li \gui{Normal Size} - Show the image at its original size
+ \li \gui{Fit to Window} - Stretch the image to occupy the entire window
\endlist
In addition the \gui Help menu provides the users with information
@@ -202,9 +202,9 @@
\table
\row
- \o \inlineimage imageviewer-original_size.png
- \o \inlineimage imageviewer-zoom_in_1.png
- \o \inlineimage imageviewer-zoom_in_2.png
+ \li \inlineimage imageviewer-original_size.png
+ \li \inlineimage imageviewer-zoom_in_1.png
+ \li \inlineimage imageviewer-zoom_in_2.png
\endtable
\snippet examples/widgets/imageviewer/imageviewer.cpp 11
@@ -246,9 +246,9 @@
\table
\row
- \o \inlineimage imageviewer-original_size.png
- \o \inlineimage imageviewer-fit_to_window_1.png
- \o \inlineimage imageviewer-fit_to_window_2.png
+ \li \inlineimage imageviewer-original_size.png
+ \li \inlineimage imageviewer-fit_to_window_1.png
+ \li \inlineimage imageviewer-fit_to_window_2.png
\endtable
If the slot is called to turn off the option, the
diff --git a/doc/src/examples/licensewizard.qdoc b/doc/src/examples/licensewizard.qdoc
index 92e51dec3bc..3a325100a73 100644
--- a/doc/src/examples/licensewizard.qdoc
+++ b/doc/src/examples/licensewizard.qdoc
@@ -50,10 +50,10 @@
The example consists of the following classes:
\list
- \o \c LicenseWizard inherits QWizard and implements a non-linear
+ \li \c LicenseWizard inherits QWizard and implements a non-linear
five-page wizard that leads the user through the process of
choosing a license agreement.
- \o \c IntroPage, \c EvaluatePage, \c RegisterPage, \c
+ \li \c IntroPage, \c EvaluatePage, \c RegisterPage, \c
DetailsPage, and \c ConclusionPage are QWizardPage subclasses
that implement the wizard pages.
\endlist
@@ -71,12 +71,12 @@
The enum defines the IDs associated with the various pages:
\table
- \header \o Class name \o Enum value \o Page ID
- \row \o \c IntroPage \o \c Page_Intro \o 0
- \row \o \c EvaluatePage \o \c Page_Evaluate \o 1
- \row \o \c RegisterPage \o \c Page_Register \o 2
- \row \o \c DetailsPage \o \c Page_Details \o 3
- \row \o \c ConclusionPage \o \c Page_Conclusion \o 4
+ \header \li Class name \li Enum value \li Page ID
+ \row \li \c IntroPage \li \c Page_Intro \li 0
+ \row \li \c EvaluatePage \li \c Page_Evaluate \li 1
+ \row \li \c RegisterPage \li \c Page_Register \li 2
+ \row \li \c DetailsPage \li \c Page_Details \li 3
+ \row \li \c ConclusionPage \li \c Page_Conclusion \li 4
\endtable
For this example, the IDs are arbitrary. The only constraints are
@@ -206,11 +206,11 @@
QWidget::setVisible():
\list
- \o If the page is shown, we set the \l{QWizard::}{CustomButton1} button's
+ \li If the page is shown, we set the \l{QWizard::}{CustomButton1} button's
text to \gui{\underline{P}rint}, we enable the \l{QWizard::}{HaveCustomButton1}
option, and we connect the QWizard's \l{QWizard::}{customButtonClicked()}
signal to our \c printButtonClicked() slot.
- \o If the page is hidden, we disable the \l{QWizard::}{HaveCustomButton1}
+ \li If the page is hidden, we disable the \l{QWizard::}{HaveCustomButton1}
option and disconnect the \c printButtonClicked() slot.
\endlist
diff --git a/doc/src/examples/maemovibration.qdoc b/doc/src/examples/maemovibration.qdoc
index 855793cf751..78bb7f53344 100644
--- a/doc/src/examples/maemovibration.qdoc
+++ b/doc/src/examples/maemovibration.qdoc
@@ -47,11 +47,11 @@
The code makes use of two classes:
\list
- \o \c MceVibrator connects to the MCE service and can start a certain
+ \li \c MceVibrator connects to the MCE service and can start a certain
vibrator pattern. It also is responsible to parse the configuration
file.
- \o \c ButtonWidget provides a button for each pattern. Pressing the button
+ \li \c ButtonWidget provides a button for each pattern. Pressing the button
activates the pattern in question.
\endlist
@@ -68,10 +68,10 @@
are available to us.
\list
- \o \c mceInterface is our D-Bus handle to the MCE service. We use it to
+ \li \c mceInterface is our D-Bus handle to the MCE service. We use it to
invoke methods on the MCE request object.
- \o \c lastPatternName contains the pattern that was activated last time. We
+ \li \c lastPatternName contains the pattern that was activated last time. We
have to keep track of this, because the last pattern has to be
deactivated before activating a new pattern.
\endlist
diff --git a/doc/src/examples/mandelbrot.qdoc b/doc/src/examples/mandelbrot.qdoc
index 23e51ba6371..a560766bdd6 100644
--- a/doc/src/examples/mandelbrot.qdoc
+++ b/doc/src/examples/mandelbrot.qdoc
@@ -66,9 +66,9 @@
\table
\row
- \o \inlineimage mandelbrot_zoom1.png
- \o \inlineimage mandelbrot_zoom2.png
- \o \inlineimage mandelbrot_zoom3.png
+ \li \inlineimage mandelbrot_zoom1.png
+ \li \inlineimage mandelbrot_zoom2.png
+ \li \inlineimage mandelbrot_zoom3.png
\endtable
Similarly, when the user scrolls, the previous pixmap is scrolled
@@ -77,17 +77,17 @@
\table
\row
- \o \inlineimage mandelbrot_scroll1.png
- \o \inlineimage mandelbrot_scroll2.png
- \o \inlineimage mandelbrot_scroll3.png
+ \li \inlineimage mandelbrot_scroll1.png
+ \li \inlineimage mandelbrot_scroll2.png
+ \li \inlineimage mandelbrot_scroll3.png
\endtable
The application consists of two classes:
\list
- \o \c RenderThread is a QThread subclass that renders
+ \li \c RenderThread is a QThread subclass that renders
the Mandelbrot set.
- \o \c MandelbrotWidget is a QWidget subclass that shows the
+ \li \c MandelbrotWidget is a QWidget subclass that shows the
Mandelbrot set on screen and lets the user zoom and scroll.
\endlist
diff --git a/doc/src/examples/mousecalibration.qdoc b/doc/src/examples/mousecalibration.qdoc
index b42d95956ee..39b9140f283 100644
--- a/doc/src/examples/mousecalibration.qdoc
+++ b/doc/src/examples/mousecalibration.qdoc
@@ -39,8 +39,8 @@
The example consists of two classes in addition to the main program:
\list
- \o \c Calibration is a dialog widget that retrieves the device coordinates.
- \o \c ScribbleWidget is a minimal drawing program used to let the user
+ \li \c Calibration is a dialog widget that retrieves the device coordinates.
+ \li \c ScribbleWidget is a minimal drawing program used to let the user
test the new mouse settings.
\endlist
diff --git a/doc/src/examples/moveblocks.qdoc b/doc/src/examples/moveblocks.qdoc
index d3332be8344..38551abd28f 100644
--- a/doc/src/examples/moveblocks.qdoc
+++ b/doc/src/examples/moveblocks.qdoc
@@ -40,14 +40,14 @@
The example consists of the following classes:
\list
- \o \c StateSwitcher inherits QState and can add
+ \li \c StateSwitcher inherits QState and can add
\c {StateSwitchTransition}s to other states.
When entered, it will randomly transition to one of these
states.
- \o \c StateSwitchTransition is a custom transition that
+ \li \c StateSwitchTransition is a custom transition that
triggers on \c{StateSwitchEvent}s.
- \o \c StateSwitchEvent is a QEvent that triggers \c{StateSwitchTransition}s.
- \o \c QGraphicsRectWidget is a QGraphicsWidget that simply
+ \li \c StateSwitchEvent is a QEvent that triggers \c{StateSwitchTransition}s.
+ \li \c QGraphicsRectWidget is a QGraphicsWidget that simply
paints its background in a solid \l{Qt::}{blue} color.
\endlist
diff --git a/doc/src/examples/orderform.qdoc b/doc/src/examples/orderform.qdoc
index de967ecebdd..94e49144442 100644
--- a/doc/src/examples/orderform.qdoc
+++ b/doc/src/examples/orderform.qdoc
@@ -161,21 +161,21 @@
\table
\row
- \o {1, 8} frame with \e{referenceFrameFormat}
+ \li {1, 8} frame with \e{referenceFrameFormat}
\row
- \o block \o \c{A company}
+ \li block \li \c{A company}
\row
- \o block
+ \li block
\row
- \o block \o \c{321 City Street}
+ \li block \li \c{321 City Street}
\row
- \o block
+ \li block
\row
- \o block \o \c{Industry Park}
+ \li block \li \c{Industry Park}
\row
- \o block
+ \li block
\row
- \o block \o \c{Another country}
+ \li block \li \c{Another country}
\endtable
This is accomplished with the following code:
@@ -196,11 +196,11 @@
\table
\row
- \o block \o \c{Donald}
+ \li block \li \c{Donald}
\row
- \o block \o \c{47338 Park Avenue}
+ \li block \li \c{47338 Park Avenue}
\row
- \o block \o \c{Big City}
+ \li block \li \c{Big City}
\endtable
For spacing purposes, we invoke \l{QTextCursor::insertBlock()}
@@ -221,21 +221,21 @@
\table
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\row
- \o block \o \c{Date: 25 May 2007}
+ \li block \li \c{Date: 25 May 2007}
\row
- \o block
+ \li block
\row
- \o {1, 4} frame with \e{bodyFrameFormat}
+ \li {1, 4} frame with \e{bodyFrameFormat}
\row
- \o block \o \c{I would like to place an order for the following items:}
+ \li block \li \c{I would like to place an order for the following items:}
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\endtable
A QTextTableFormat object, \c orderTableFormat, is used to hold the type
@@ -257,27 +257,27 @@
\table
\row
- \o {1, 11} \c{orderTable} with \e{orderTableFormat}
+ \li {1, 11} \c{orderTable} with \e{orderTableFormat}
\row
- \o block \o \c{Product}
+ \li block \li \c{Product}
\row
- \o block \o \c{Quantity}
+ \li block \li \c{Quantity}
\row
- \o block \o \c{T-shirt}
+ \li block \li \c{T-shirt}
\row
- \o block \o \c{4}
+ \li block \li \c{4}
\row
- \o block \o \c{Badge}
+ \li block \li \c{Badge}
\row
- \o block \o \c{3}
+ \li block \li \c{3}
\row
- \o block \o \c{Reference book}
+ \li block \li \c{Reference book}
\row
- \o block \o \c{2}
+ \li block \li \c{2}
\row
- \o block \o \c{Coffee cup}
+ \li block \li \c{Coffee cup}
\row
- \o block \o \c{5}
+ \li block \li \c{5}
\endtable
The \c cursor is then moved back to \c{topFrame}'s
@@ -296,19 +296,19 @@
\table
\row
- \o block
+ \li block
\row
- \o block\o \c{Please update my...}
+ \li block\li \c{Please update my...}
\row
- \o {1, 5} block
+ \li {1, 5} block
\row
- \o {1, 4} \c{offersTable}
+ \li {1, 4} \c{offersTable}
\row
- \o block \o \c{I want to receive...}
+ \li block \li \c{I want to receive...}
\row
- \o block \o \c{I do not want to receive...}
+ \li block \li \c{I do not want to receive...}
\row
- \o block \o \c{X}
+ \li block \li \c{X}
\endtable
The \c cursor is moved to insert "Sincerely" along with the customer's
@@ -321,17 +321,17 @@
\table
\row
- \o block
+ \li block
\row
- \o {1, 5} block\o \c{Sincerely,}
+ \li {1, 5} block\li \c{Sincerely,}
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\row
- \o block
+ \li block
\row
- \o block \o \c{Donald}
+ \li block \li \c{Donald}
\endtable
The \c createSample() function is used for illustration purposes, to create
diff --git a/doc/src/examples/overpainting.qdoc b/doc/src/examples/overpainting.qdoc
index 74f9f0a8727..d20ee646983 100644
--- a/doc/src/examples/overpainting.qdoc
+++ b/doc/src/examples/overpainting.qdoc
@@ -214,30 +214,30 @@
calls, using the following approach:
\list
- \o Reimplement QGLWidget::initializeGL(), but only perform minimal
+ \li Reimplement QGLWidget::initializeGL(), but only perform minimal
initialization. QPainter will perform its own initialization
routines, modifying the matrix and property stacks, so it is better
to defer certain initialization tasks until just before you render
the 3D scene.
- \o Reimplement QGLWidget::resizeGL() as in the pure 3D case.
- \o Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics.
+ \li Reimplement QGLWidget::resizeGL() as in the pure 3D case.
+ \li Reimplement QWidget::paintEvent() to draw both 2D and 3D graphics.
\endlist
The \l{QWidget::paintEvent()}{paintEvent()} implementation performs the
following tasks:
\list
- \o Push the current OpenGL modelview matrix onto a stack.
- \o Perform initialization tasks usually done in the
+ \li Push the current OpenGL modelview matrix onto a stack.
+ \li Perform initialization tasks usually done in the
\l{QGLWidget::initializeGL()}{initializeGL()} function.
- \o Perform code that would normally be located in the widget's
+ \li Perform code that would normally be located in the widget's
\l{QGLWidget::resizeGL()}{resizeGL()} function to set the correct
perspective transformation and set up the viewport.
- \o Render the scene using OpenGL calls.
- \o Pop the OpenGL modelview matrix off the stack.
- \o Construct a QPainter object.
- \o Initialize it for use on the widget with the QPainter::begin() function.
- \o Draw primitives using QPainter's member functions.
- \o Call QPainter::end() to finish painting.
+ \li Render the scene using OpenGL calls.
+ \li Pop the OpenGL modelview matrix off the stack.
+ \li Construct a QPainter object.
+ \li Initialize it for use on the widget with the QPainter::begin() function.
+ \li Draw primitives using QPainter's member functions.
+ \li Call QPainter::end() to finish painting.
\endlist
*/
diff --git a/doc/src/examples/padnavigator.qdoc b/doc/src/examples/padnavigator.qdoc
index 52d80adcb74..840c16b0c91 100644
--- a/doc/src/examples/padnavigator.qdoc
+++ b/doc/src/examples/padnavigator.qdoc
@@ -81,11 +81,11 @@
The private data members are:
\list
- \o \c pix: The optional pixmap that is drawn on top of the rectangle.
- \o \c fillRect: Corresponds to the \c fill property.
- \o \c color: The configurable gradient color fill of the rectangle.
- \o \c bounds: The bounds of the rectangle.
- \o \c gradient: A precalculated gradient used to fill the rectangle.
+ \li \c pix: The optional pixmap that is drawn on top of the rectangle.
+ \li \c fillRect: Corresponds to the \c fill property.
+ \li \c color: The configurable gradient color fill of the rectangle.
+ \li \c bounds: The bounds of the rectangle.
+ \li \c gradient: A precalculated gradient used to fill the rectangle.
\endlist
We will now review the \c RoundRectItem implementation. Let's start by
@@ -320,13 +320,13 @@
QGraphicsRotation object for each of these.
\list
- \o \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
+ \li \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is
animated from 0 to 180, and eventually back, when enter is pressed on the
keyboard, flipping the pad around.
- \o \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
+ \li \c xRotation: Rotates the grid around its Qt::XAxis. This is used to
tilt the pad vertically corresponding to which item is currently selected.
This way, the selected item is always kept in front.
- \o \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
+ \li \c yRotation: Rotates the grid around its Qt::YAxis. This is used to
tilt the pad horizontally corresponding to which item is selected. This
way, the selected item is always kept in front.
\endlist
@@ -391,11 +391,11 @@
values when flipped back:
\list
- \o \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
- \o \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
- \o \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
- \o \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
- \o \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
+ \li \c smoothFlipRotation: Animates the main 180 degree rotation of the pad.
+ \li \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating.
+ \li \c smoothFlipXRotation: Animates the selection item's X-tilt to 0 and back.
+ \li \c smoothFlipYRotation: Animates the selection item's Y-tilt to 0 and back.
+ \li \c flipAnimation: A parallel animation group that ensures all the above animations are run in parallel.
\endlist
All animations are given a 500 millisecond duration and an
@@ -433,10 +433,10 @@
states:
\list
- \o \c splashState: The initial state where the splash item is visible.
- \o \c frontState: The base state where the splash is gone and we can see
+ \li \c splashState: The initial state where the splash item is visible.
+ \li \c frontState: The base state where the splash is gone and we can see
the front side of the pad, and navigate the selection item.
- \o \c backState: The flipped state where the \c backItem is visible, and we
+ \li \c backState: The flipped state where the \c backItem is visible, and we
can interact with the QGraphicsProxyWidget-embedded form.
\endlist
@@ -531,18 +531,18 @@
The view toggles a few necessary properties:
\list
- \o It disables its scroll bars - this application has no use for scroll bars.
- \o It assigns a minimum size. This is necessary to avoid numerical errors
+ \li It disables its scroll bars - this application has no use for scroll bars.
+ \li It assigns a minimum size. This is necessary to avoid numerical errors
in our fit-in-view \c resizeEvent() implementation.
- \o It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
+ \li It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to
ensure QGraphicsView doesn't spend time figuring out precisely what needs
to be redrawn. This application is very simple - if anything changes,
everything is updated.
- \o It enables background caching - this makes no performance difference
+ \li It enables background caching - this makes no performance difference
with OpenGL, but without OpenGL it avoids unnecessary re-scaling of the
background pixmap.
- \o It sets render hints that increase rendering quality.
- \o If OpenGL is supported, a QGLWidget viewport is assigned to the view.
+ \li It sets render hints that increase rendering quality.
+ \li If OpenGL is supported, a QGLWidget viewport is assigned to the view.
\endlist
Finally, we start the state engine.
diff --git a/doc/src/examples/painterpaths.qdoc b/doc/src/examples/painterpaths.qdoc
index 868c4f5283b..1bee28f0298 100644
--- a/doc/src/examples/painterpaths.qdoc
+++ b/doc/src/examples/painterpaths.qdoc
@@ -48,9 +48,9 @@
The example consists of two classes:
\list
- \o The \c RenderArea class which is a custom widget displaying
+ \li The \c RenderArea class which is a custom widget displaying
a single painter path.
- \o The \c Window class which is the applications main window
+ \li The \c Window class which is the applications main window
displaying several \c RenderArea widgets, and allowing the user
to manipulate the painter paths' filling, pen, color
and rotation angle.
diff --git a/doc/src/examples/pixelator.qdoc b/doc/src/examples/pixelator.qdoc
index 8eec198aba5..6dff9e1b87f 100644
--- a/doc/src/examples/pixelator.qdoc
+++ b/doc/src/examples/pixelator.qdoc
@@ -44,9 +44,9 @@
of standard views. To do this, we implement the following components:
\list
- \i A model which represents each pixel in an image as an item of data, where each
+ \li A model which represents each pixel in an image as an item of data, where each
item contains a value for the brightness of the corresponding pixel.
- \i A custom delegate that uses the information supplied by the model to represent
+ \li A custom delegate that uses the information supplied by the model to represent
each pixel as a black circle on a white background, where the radius of the
circle corresponds to the darkness of the pixel.
\endlist
diff --git a/doc/src/examples/plugandpaint.qdoc b/doc/src/examples/plugandpaint.qdoc
index 118afa6a024..ee3f6fefe94 100644
--- a/doc/src/examples/plugandpaint.qdoc
+++ b/doc/src/examples/plugandpaint.qdoc
@@ -55,13 +55,13 @@
Plug & Paint consists of the following classes:
\list
- \o \c MainWindow is a QMainWindow subclass that provides the menu
+ \li \c MainWindow is a QMainWindow subclass that provides the menu
system and that contains a \c PaintArea as the central widget.
- \o \c PaintArea is a QWidget that allows the user to draw using a
+ \li \c PaintArea is a QWidget that allows the user to draw using a
brush and to insert shapes.
- \o \c PluginDialog is a dialog that shows information about the
+ \li \c PluginDialog is a dialog that shows information about the
plugins detected by the application.
- \o \c BrushInterface, \c ShapeInterface, and \c FilterInterface are
+ \li \c BrushInterface, \c ShapeInterface, and \c FilterInterface are
abstract base classes that can be implemented by plugins to
provide custom brushes, shapes, and image filters.
\endlist
@@ -321,10 +321,10 @@
plugin:
\list 1
- \o Declare a plugin class.
- \o Implement the interfaces provided by the plugin.
- \o Export the plugin using the Q_EXPORT_PLUGIN2() macro.
- \o Build the plugin using an adequate \c .pro file.
+ \li Declare a plugin class.
+ \li Implement the interfaces provided by the plugin.
+ \li Export the plugin using the Q_EXPORT_PLUGIN2() macro.
+ \li Build the plugin using an adequate \c .pro file.
\endlist
\section1 Declaration of the Plugin Class
@@ -377,15 +377,15 @@
Then comes the brush-dependent part of the code:
\list
- \o If the brush is \gui{Pencil}, we just call
+ \li If the brush is \gui{Pencil}, we just call
QPainter::drawLine() with the current QPen.
- \o If the brush is \gui{Air Brush}, we start by setting the
+ \li If the brush is \gui{Air Brush}, we start by setting the
painter's QBrush to Qt::Dense6Pattern to obtain a dotted
pattern. Then we draw a circle filled with that QBrush several
times, resulting in a thick line.
- \o If the brush is \gui{Random Letters}, we draw a random letter
+ \li If the brush is \gui{Random Letters}, we draw a random letter
at the new cursor position. Most of the code is for setting
the font to be bold and larger than the default font and for
computing an appropriate bounding rect.
diff --git a/doc/src/examples/rogue.qdoc b/doc/src/examples/rogue.qdoc
index 38c871c7db1..44e371c6679 100644
--- a/doc/src/examples/rogue.qdoc
+++ b/doc/src/examples/rogue.qdoc
@@ -64,10 +64,10 @@
The example consists of two classes:
\list
- \o \c Window draws the text display of the game and sets
+ \li \c Window draws the text display of the game and sets
up the state machine. The window also has a status bar
above the area in which the rouge moves.
- \o \c MovementTransition is a transition that carries out
+ \li \c MovementTransition is a transition that carries out
a single move of the rogue.
\endlist
diff --git a/doc/src/examples/screenshot.qdoc b/doc/src/examples/screenshot.qdoc
index e99fe6cc190..7ee7ddb9c7f 100644
--- a/doc/src/examples/screenshot.qdoc
+++ b/doc/src/examples/screenshot.qdoc
@@ -41,9 +41,9 @@
desktop. They are provided with a couple of options:
\list
- \o Delaying the screenshot, giving them time to rearrange
+ \li Delaying the screenshot, giving them time to rearrange
their desktop.
- \o Hiding the application's window while the screenshot is taken.
+ \li Hiding the application's window while the screenshot is taken.
\endlist
In addition the application allows the users to save their
@@ -63,10 +63,10 @@
to facilitate the options:
\list
- \o The \c newScreenshot() slot prepares a new screenshot.
- \o The \c saveScreenshot() slot saves the last screenshot.
- \o The \c shootScreen() slot takes the screenshot.
- \o The \c updateCheckBox() slot enables or disables the
+ \li The \c newScreenshot() slot prepares a new screenshot.
+ \li The \c saveScreenshot() slot saves the last screenshot.
+ \li The \c shootScreen() slot takes the screenshot.
+ \li The \c updateCheckBox() slot enables or disables the
\gui {Hide This Window} option.
\endlist
diff --git a/doc/src/examples/scribble.qdoc b/doc/src/examples/scribble.qdoc
index d9386843a55..5d801bf9ccd 100644
--- a/doc/src/examples/scribble.qdoc
+++ b/doc/src/examples/scribble.qdoc
@@ -55,9 +55,9 @@
The example consists of two classes:
\list
- \o \c ScribbleArea is a custom widget that displays a QImage and
+ \li \c ScribbleArea is a custom widget that displays a QImage and
allows to the user to draw on it.
- \o \c MainWindow provides a menu above the \c ScribbleArea.
+ \li \c MainWindow provides a menu above the \c ScribbleArea.
\endlist
We will start by reviewing the \c ScribbleArea class. Then we will
@@ -85,14 +85,14 @@
We also need the following private variables:
\list
- \o \c modified is \c true if there are unsaved
+ \li \c modified is \c true if there are unsaved
changes to the image displayed in the scribble area.
- \o \c scribbling is \c true while the user is pressing
+ \li \c scribbling is \c true while the user is pressing
the left mouse button within the scribble area.
- \o \c penWidth and \c penColor hold the currently
+ \li \c penWidth and \c penColor hold the currently
set width and color for the pen used in the application.
- \o \c image stores the image drawn by the user.
- \o \c lastPoint holds the position of the cursor at the last
+ \li \c image stores the image drawn by the user.
+ \li \c lastPoint holds the position of the cursor at the last
mouse press or mouse move event.
\endlist
@@ -176,18 +176,18 @@
good reasons for this:
\list
- \o The window system requires us to be able to redraw the widget
+ \li The window system requires us to be able to redraw the widget
\e{at any time}. For example, if the window is minimized and
restored, the window system might have forgotten the contents
of the widget and send us a paint event. In other words, we
can't rely on the window system to remember our image.
- \o Qt normally doesn't allow us to paint outside of \c
+ \li Qt normally doesn't allow us to paint outside of \c
paintEvent(). In particular, we can't paint from the mouse
event handlers. (This behavior can be changed using the
Qt::WA_PaintOnScreen widget attribute, though.)
- \o If initialized properly, a QImage is guaranteed to use 8-bit
+ \li If initialized properly, a QImage is guaranteed to use 8-bit
for each color channel (red, green, blue, and alpha), whereas
a QWidget might have a lower color depth, depending on the
monitor configuration. This means that if we load a 24-bit or
diff --git a/doc/src/examples/simpletreemodel.qdoc b/doc/src/examples/simpletreemodel.qdoc
index 36e0632eb2a..ed584a3307a 100644
--- a/doc/src/examples/simpletreemodel.qdoc
+++ b/doc/src/examples/simpletreemodel.qdoc
@@ -59,8 +59,8 @@
\target SimpleTreeModelStructure
\table
- \row \i \inlineimage treemodel-structure.png
- \i \bold{Simple Tree Model Structure}
+ \row \li \inlineimage treemodel-structure.png
+ \li \b{Simple Tree Model Structure}
The data is stored internally in the model using \c TreeItem objects that
are linked together in a pointer-based tree structure. Generally, each
@@ -101,14 +101,14 @@
structure. The functions provide the following features:
\list
- \o The \c appendChildItem() is used to add data when the model is first
+ \li The \c appendChildItem() is used to add data when the model is first
constructed and is not used during normal use.
- \o The \c child() and \c childCount() functions allow the model to obtain
+ \li The \c child() and \c childCount() functions allow the model to obtain
information about any child items.
- \o Information about the number of columns associated with the item is
+ \li Information about the number of columns associated with the item is
provided by \c columnCount(), and the data in each column can be
obtained with the data() function.
- \o The \c row() and \c parent() functions are used to obtain the item's
+ \li The \c row() and \c parent() functions are used to obtain the item's
row number and parent item.
\endlist
@@ -320,10 +320,10 @@
We process the text file with the following two rules:
\list
- \o For each pair of strings on each line, create an item (or node)
+ \li For each pair of strings on each line, create an item (or node)
in a tree structure, and place each string in a column of data
in the item.
- \o When the first string on a line is indented with respect to the
+ \li When the first string on a line is indented with respect to the
first string on the previous line, make the item a child of the
previous item created.
\endlist
diff --git a/doc/src/examples/sipdialog.qdoc b/doc/src/examples/sipdialog.qdoc
index 2b51af4fdc1..b5f18cb4bef 100644
--- a/doc/src/examples/sipdialog.qdoc
+++ b/doc/src/examples/sipdialog.qdoc
@@ -34,8 +34,8 @@
the Windows Mobile SIP (Software Input Panel) and reacts to it.
\table
- \row \o \inlineimage sipdialog-closed.png
- \o \inlineimage sipdialog-opened.png
+ \row \li \inlineimage sipdialog-closed.png
+ \li \inlineimage sipdialog-opened.png
\endtable
Sometimes it is necessary for a dialog to take the SIP into account,
@@ -90,10 +90,10 @@
The following signals are connected to their respective slots:
\list
- \o \c{button}'s \l{QPushButton::pressed()}{pressed()} signal to
+ \li \c{button}'s \l{QPushButton::pressed()}{pressed()} signal to
\l{QApplication}'s \l{QApplication::closeAllWindows()}
{closeAllWindows()} slot,
- \o \l{QDesktopWidget}'s \l{QDesktopWidget::workAreaResized()}
+ \li \l{QDesktopWidget}'s \l{QDesktopWidget::workAreaResized()}
{workAreaResized()} signal to \c{dialog}'s \c desktopResized() slot.
\endlist
diff --git a/doc/src/examples/sliders.qdoc b/doc/src/examples/sliders.qdoc
index e71986bfc94..49d41a9d18c 100644
--- a/doc/src/examples/sliders.qdoc
+++ b/doc/src/examples/sliders.qdoc
@@ -46,10 +46,10 @@
\list
- \o \c SlidersGroup is a custom widget. It combines a QSlider, a
+ \li \c SlidersGroup is a custom widget. It combines a QSlider, a
QScrollBar and a QDial.
- \o \c Window is the main widget combining a QGroupBox and a
+ \li \c Window is the main widget combining a QGroupBox and a
QStackedWidget. In this example, the QStackedWidget provides a
stack of two \c SlidersGroup widgets. The QGroupBox contain
several widgets that control the behavior of the slider-like
@@ -122,10 +122,10 @@
slider-like widgets:
\table
- \header \o \o{2,1} QSlider \o{2,1} QScrollBar \o{2,1} QDial
- \header \o \o Normal \o Inverted \o Normal \o Inverted \o Normal \o Inverted
- \row \o Qt::Horizontal \o Left to right \o Right to left \o Left to right \o Right to left \o Clockwise \o Counterclockwise
- \row \o Qt::Vertical \o Bottom to top \o Top to bottom \o Top to bottom \o Bottom to top \o Clockwise \o Counterclockwise
+ \header \li \li{2,1} QSlider \li{2,1} QScrollBar \li{2,1} QDial
+ \header \li \li Normal \li Inverted \li Normal \li Inverted \li Normal \li Inverted
+ \row \li Qt::Horizontal \li Left to right \li Right to left \li Left to right \li Right to left \li Clockwise \li Counterclockwise
+ \row \li Qt::Vertical \li Bottom to top \li Top to bottom \li Top to bottom \li Bottom to top \li Clockwise \li Counterclockwise
\endtable
It is common to invert the appearance of a vertical QSlider. A
diff --git a/doc/src/examples/stardelegate.qdoc b/doc/src/examples/stardelegate.qdoc
index 01507eaf824..c9cc1f40cf5 100644
--- a/doc/src/examples/stardelegate.qdoc
+++ b/doc/src/examples/stardelegate.qdoc
@@ -58,15 +58,15 @@
The example consists of the following classes:
\list
- \o \c StarRating is the custom data type. It stores a rating
+ \li \c StarRating is the custom data type. It stores a rating
expressed as stars, such as "2 out of 5 stars" or "5 out of
6 stars".
- \o \c StarDelegate inherits QItemDelegate and provides support
+ \li \c StarDelegate inherits QItemDelegate and provides support
for \c StarRating (in addition to the data types already
handled by QItemDelegate).
- \o \c StarEditor inherits QWidget and is used by \c StarDelegate
+ \li \c StarEditor inherits QWidget and is used by \c StarDelegate
to let the user edit a star rating using the mouse.
\endlist
@@ -281,7 +281,7 @@
editor are:
\list
- \o It is possible to open editors programmatically by calling
+ \li It is possible to open editors programmatically by calling
QAbstractItemView::edit(), instead of relying on edit
triggers. This could be use to support other edit triggers
than those offered by the QAbstractItemView::EditTrigger enum.
@@ -289,7 +289,7 @@
item with the mouse might make sense as a way to pop up an
editor.
- \o By reimplementing QAbstractItemDelegate::editorEvent(), it is
+ \li By reimplementing QAbstractItemDelegate::editorEvent(), it is
possible to implement the editor directly in the delegate,
instead of creating a separate QWidget subclass.
\endlist
diff --git a/doc/src/examples/styles.qdoc b/doc/src/examples/styles.qdoc
index 91fd1d54d71..d1f5091a4b0 100644
--- a/doc/src/examples/styles.qdoc
+++ b/doc/src/examples/styles.qdoc
@@ -56,9 +56,9 @@
The example consists of the following classes:
\list
- \o \c NorwegianWoodStyle inherits from QMotifStyle and implements
+ \li \c NorwegianWoodStyle inherits from QMotifStyle and implements
the Norwegian Wood style.
- \o \c WidgetGallery is a \c QDialog subclass that shows the most
+ \li \c WidgetGallery is a \c QDialog subclass that shows the most
common widgets and allows the user to switch style
dynamically.
\endlist
@@ -91,16 +91,16 @@
resources}.
\table
- \row \o \inlineimage widgets/styles/images/woodbackground.png
+ \row \li \inlineimage widgets/styles/images/woodbackground.png
- \o \bold{woodbackground.png}
+ \li \b{woodbackground.png}
This texture is used as the background of most widgets.
The wood pattern is horizontal.
- \row \o \inlineimage widgets/styles/images/woodbutton.png
+ \row \li \inlineimage widgets/styles/images/woodbutton.png
- \o \bold{woodbutton.png}
+ \li \b{woodbutton.png}
This texture is used for filling push buttons and
comboboxes. The wood pattern is vertical and more reddish
@@ -261,17 +261,17 @@
them based on the state of the button:
\list
- \o If the button is a \l{QPushButton::flat}{flat button}, we use
+ \li If the button is a \l{QPushButton::flat}{flat button}, we use
the \l{QPalette::Background}{Background} brush. We set \c
darker to \c true if the button is
\l{QAbstractButton::down}{down} or
\l{QAbstractButton::checked}{checked}.
- \o If the button is currently held down by the user or in the
+ \li If the button is currently held down by the user or in the
\l{QAbstractButton::checked}{checked} state, we use the
\l{QPalette::Mid}{Mid} component of the palette. We set
\c darker to \c true if the button is
\l{QAbstractButton::checked}{checked}.
- \o Otherwise, we use the \l{QPalette::Button}{Button} component
+ \li Otherwise, we use the \l{QPalette::Button}{Button} component
of the palette.
\endlist
diff --git a/doc/src/examples/svgalib.qdoc b/doc/src/examples/svgalib.qdoc
index cac14a74694..f25a3e21a84 100644
--- a/doc/src/examples/svgalib.qdoc
+++ b/doc/src/examples/svgalib.qdoc
@@ -49,13 +49,13 @@
approach:
\list 1
- \o \l {Step 1: Creating a Custom Graphics Driver}
+ \li \l {Step 1: Creating a Custom Graphics Driver}
{Creating a Custom Graphics Driver}
- \o \l {Step 2: Implementing a Custom Raster Paint Engine}
+ \li \l {Step 2: Implementing a Custom Raster Paint Engine}
{Implementing a Custom Paint Engine}
- \o \l {Step 3: Making the Widgets Aware of the Custom Paint
+ \li \l {Step 3: Making the Widgets Aware of the Custom Paint
Engine}{Making the Widgets Aware of the Custom Paint Engine}
\endlist
@@ -69,8 +69,8 @@
\snippet doc/src/snippets/code/doc_src_examples_svgalib.qdoc 0
\table
- \header \o SVGAlib
- \row \o
+ \header \li SVGAlib
+ \row \li
Instead of interfacing the graphics hardware directly, this
example relies on \l {http://www.svgalib.org}{SVGAlib} being
@@ -212,9 +212,9 @@
respectively.
\table
- \header \o Private Header Files
+ \header \li Private Header Files
\row
- \o
+ \li
Note the \c include statement used by this class. The files
prefixed with \c private/ are private headers file within
@@ -285,9 +285,9 @@
adjustments of the graphics driver.
\list
- \o \l {Implementing a Custom Paint Device}
- \o \l {Implementing a Custom Window Surface}
- \o \l {Adjusting the Graphics Driver}
+ \li \l {Implementing a Custom Paint Device}
+ \li \l {Implementing a Custom Window Surface}
+ \li \l {Adjusting the Graphics Driver}
\endlist
\section2 Implementing a Custom Paint Device
diff --git a/doc/src/examples/syntaxhighlighter.qdoc b/doc/src/examples/syntaxhighlighter.qdoc
index d86719ab197..597a1a2bf38 100644
--- a/doc/src/examples/syntaxhighlighter.qdoc
+++ b/doc/src/examples/syntaxhighlighter.qdoc
@@ -40,9 +40,9 @@
The example consists of two classes:
\list
- \o The \c Highlighter class defines and applies the
+ \li The \c Highlighter class defines and applies the
highlighting rules.
- \o The \c MainWindow widget is the application's main window.
+ \li The \c MainWindow widget is the application's main window.
\endlist
We will first review the \c Highlighter class to see how you can
diff --git a/doc/src/examples/tablet.qdoc b/doc/src/examples/tablet.qdoc
index 249b593e9bf..57fa7d5eca1 100644
--- a/doc/src/examples/tablet.qdoc
+++ b/doc/src/examples/tablet.qdoc
@@ -61,15 +61,15 @@
The example consists of the following:
\list
- \o The \c MainWindow class inherits QMainWindow and creates
+ \li The \c MainWindow class inherits QMainWindow and creates
the examples menus and connect their slots and signals.
- \o The \c TabletCanvas class inherits QWidget and
+ \li The \c TabletCanvas class inherits QWidget and
receives tablet events. It uses the events to paint on a
offscreen pixmap, which it draws onto itself.
- \o The \c TabletApplication class inherits QApplication. This
+ \li The \c TabletApplication class inherits QApplication. This
class handles tablet events that are not sent to \c tabletEvent().
We will look at this later.
- \o The \c main() function creates a \c MainWindow and shows it
+ \li The \c main() function creates a \c MainWindow and shows it
as a top level window.
\endlist
diff --git a/doc/src/examples/tetrix.qdoc b/doc/src/examples/tetrix.qdoc
index 1eb92a2a4a5..fca5229ad84 100644
--- a/doc/src/examples/tetrix.qdoc
+++ b/doc/src/examples/tetrix.qdoc
@@ -53,11 +53,11 @@
This example shows how a simple game can be created using only three classes:
\list
- \o The \c TetrixWindow class is used to display the player's score, number of
+ \li The \c TetrixWindow class is used to display the player's score, number of
lives, and information about the next piece to appear.
- \o The \c TetrixBoard class contains the game logic, handles keyboard input, and
+ \li The \c TetrixBoard class contains the game logic, handles keyboard input, and
displays the pieces on the playing area.
- \o The \c TetrixPiece class contains information about each piece.
+ \li The \c TetrixPiece class contains information about each piece.
\endlist
In this approach, the \c TetrixBoard class is the most complex class, since it
diff --git a/doc/src/examples/textfinder.qdoc b/doc/src/examples/textfinder.qdoc
index 17c52c2208a..8f1ed5d3402 100644
--- a/doc/src/examples/textfinder.qdoc
+++ b/doc/src/examples/textfinder.qdoc
@@ -37,16 +37,16 @@
resource and is loaded into the display at startup.
\table
- \row \o \inlineimage textfinder-example-find.png
- \o \inlineimage textfinder-example-find2.png
+ \row \li \inlineimage textfinder-example-find.png
+ \li \inlineimage textfinder-example-find2.png
\endtable
\section1 Setting Up The Resource File
The resources required for Text Finder are:
\list
- \o \e{textfinder.ui} - the user interface file created in QtDesigner
- \o \e{input.txt} - a text file containing some text to be displayed
+ \li \e{textfinder.ui} - the user interface file created in QtDesigner
+ \li \e{input.txt} - a text file containing some text to be displayed
in the QTextEdit
\endlist
diff --git a/doc/src/examples/tooltips.qdoc b/doc/src/examples/tooltips.qdoc
index d506268bd8c..cfa1884097e 100644
--- a/doc/src/examples/tooltips.qdoc
+++ b/doc/src/examples/tooltips.qdoc
@@ -53,8 +53,8 @@
The Tooltips example consists of two classes:
\list
- \o \c ShapeItem is a custom widget representing one single shape item.
- \o \c SortingBox inherits from QWidget and is the application's main
+ \li \c ShapeItem is a custom widget representing one single shape item.
+ \li \c SortingBox inherits from QWidget and is the application's main
widget.
\endlist
diff --git a/doc/src/examples/transformations.qdoc b/doc/src/examples/transformations.qdoc
index 9a23c6c8e69..8bca26eb77b 100644
--- a/doc/src/examples/transformations.qdoc
+++ b/doc/src/examples/transformations.qdoc
@@ -42,9 +42,9 @@
The example consists of two classes and a global enum:
\list
- \o The \c RenderArea class controls the rendering of a given shape.
- \o The \c Window class is the application's main window.
- \o The \c Operation enum describes the various transformation
+ \li The \c RenderArea class controls the rendering of a given shape.
+ \li The \c Window class is the application's main window.
+ \li The \c Operation enum describes the various transformation
operations available in the application.
\endlist
diff --git a/doc/src/examples/trollprint.qdoc b/doc/src/examples/trollprint.qdoc
index 4127348b391..63566bdc214 100644
--- a/doc/src/examples/trollprint.qdoc
+++ b/doc/src/examples/trollprint.qdoc
@@ -200,11 +200,11 @@
editor and follow these steps:
\list
- \o Uncomment the two lines that create a QLabel with the text
+ \li Uncomment the two lines that create a QLabel with the text
"\TROLL PRINT\" in \c printpanel.cpp.
- \o Word-tidying: Replace "2-sided" by "Two-sided" in \c printpanel.cpp.
- \o Replace "1.0" with "1.1" everywhere it occurs in \c mainwindow.cpp.
- \o Update the copyright year to 1999-2000 in \c mainwindow.cpp.
+ \li Word-tidying: Replace "2-sided" by "Two-sided" in \c printpanel.cpp.
+ \li Replace "1.0" with "1.1" everywhere it occurs in \c mainwindow.cpp.
+ \li Update the copyright year to 1999-2000 in \c mainwindow.cpp.
\endlist
(Of course the version number and copyright year would be consts or
@@ -214,25 +214,25 @@
Linguist}. The following items are of special interest:
\list
- \o \c MainWindow
+ \li \c MainWindow
\list
- \o Troll Print 1.0 - marked "(obs.)", obsolete
- \o About Troll Print 1.0 - marked "(obs.)", obsolete
- \o Troll Print 1.0. Copyright 1999 Software, Inc. -
+ \li Troll Print 1.0 - marked "(obs.)", obsolete
+ \li About Troll Print 1.0 - marked "(obs.)", obsolete
+ \li Troll Print 1.0. Copyright 1999 Software, Inc. -
marked obsolete
- \o Troll Print 1.1 - automatically translated as
+ \li Troll Print 1.1 - automatically translated as
"Troll Imprimir 1.1"
- \o About Troll Print 1.1 - automatically translated as
+ \li About Troll Print 1.1 - automatically translated as
"Troll Imprimir 1.1"
- \o Troll Print 1.1. Copyright 1999-2000 Software,
+ \li Troll Print 1.1. Copyright 1999-2000 Software,
Inc. - automatically translated as "Troll Imprimir 1.1.
Copyright 1999-2000 Software, Inc."
\endlist
- \o \c PrintPanel
+ \li \c PrintPanel
\list
- \o 2-sided - marked "(obs.)", obsolete
- \o \TROLL PRINT\ - unmarked, i.e. untranslated
- \o Two-sided - unmarked, i.e. untranslated.
+ \li 2-sided - marked "(obs.)", obsolete
+ \li \TROLL PRINT\ - unmarked, i.e. untranslated
+ \li Two-sided - unmarked, i.e. untranslated.
\endlist
\endlist
diff --git a/doc/src/examples/undoframework.qdoc b/doc/src/examples/undoframework.qdoc
index 36e43f2ed8c..0bc2efd0251 100644
--- a/doc/src/examples/undoframework.qdoc
+++ b/doc/src/examples/undoframework.qdoc
@@ -61,18 +61,18 @@
The example consists of the following classes:
\list
- \o \c MainWindow is the main window and arranges the
+ \li \c MainWindow is the main window and arranges the
example's widgets. It creates the commands based
on user input and keeps them on the command stack.
- \o \c AddCommand adds an item to the scene.
- \o \c DeleteCommand deletes an item from the scene.
- \o \c MoveCommand when an item is moved the MoveCommand keeps record
+ \li \c AddCommand adds an item to the scene.
+ \li \c DeleteCommand deletes an item from the scene.
+ \li \c MoveCommand when an item is moved the MoveCommand keeps record
of the start and stop positions of the move, and it
moves the item according to these when \c redo() and \c undo()
is called.
- \o \c DiagramScene inherits QGraphicsScene and
+ \li \c DiagramScene inherits QGraphicsScene and
emits signals for the \c MoveComands when an item is moved.
- \o \c DiagramItem inherits QGraphicsPolygonItem and represents
+ \li \c DiagramItem inherits QGraphicsPolygonItem and represents
an item in the diagram.
\endlist
diff --git a/doc/src/examples/widgets/mousebuttons.qdoc b/doc/src/examples/widgets/mousebuttons.qdoc
new file mode 100644
index 00000000000..bf63cd50767
--- /dev/null
+++ b/doc/src/examples/widgets/mousebuttons.qdoc
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Rick Stockton
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example widgets/mousebuttons/buttontester
+ \title Mouse Button Tester
+
+ \brief The 'Mouse Button Tester' example demonstrates how to reimplement
+ mouse events within a custom class. You can also use this program to
+ verify that Qt is actually receiving mouse events from your mouse.
+
+ Many 'gamer' mouse devices are configured with high-numbered "buttons"
+ sending text shortcuts for certain games. With such a mouse, no mouse
+ button events occur: The "mouse" sends keystrokes, and the
+ 'Mouse Button Tester' Window will not see the event. Receving no event,
+ it will not repaint the Window with new text describing a \button event.
+
+ And so, in addition to it's use as Qt example code, the program may be
+ useful s a mouse device tester. Note that there is another example
+ muouse buttons example which provides the same function, written in QML.
+
+ This program (the Widget-based example) consists of three classes,
+ in addition to the main() parent program:
+
+ \list
+ \o \c A QPushButton, "Quit".
+ \o \c ButtonTester. This is derived from Qt's TextArea class, for
+ purpose of customizing/re-implementing the mouse and wheel event
+ member functions.
+ \o \c A simple QVBoxLayout layout.
+ \endlist
+
+ First we will review the main program, with it's layout and "Quit"
+ QPushButton. Then we will take a look at the \c ButtonTester class.
+
+ \section1 The Main Program
+
+ Note that the QPushButton, "Quit", is defined directly within the main()
+ program, rather than another class. This is a correct way of defining a
+ "Quit" QPushButton: A "Quit" Button defined inside another
+ class would result in the destructor of that second class being
+ called twice. This "Quit" Button uses the traditional Signal/Slot
+ connection to invoke termination of the QApp, which will properly destroy
+ its child classes \before terminating itself.
+
+ The remainder of the main() program is concerned with defining the layout,
+ and applying a minimum size to the customized ButtonTester.
+
+ \section1 ButtonTester Class Definition
+
+ The \c ButtonTester class inherits from QTextEdit, and listens for
+ mouse events on all possible Qt::MouseButton values. It also listens for
+ wheel events from the mouse, and indicates the direction of wheel motion
+ ("up", down", "left", or "right"). It prints short debug messages into
+ the Window, and also on the console QDebug() stream, when mouse button
+ and wheel events occur. Our reimplementation of mousePressEvent(),
+ mouseReleaseEvent(), mouseDoubleClickEvent(), and wheelEvent() "drive"
+ the program; the other functions simply convert the Qt::MouseButton
+ values into text strings.
+
+ You should call the ignore() function on any mouse event (or other event)
+ which your widget-based classes do not use and consume. This function
+ assures that Qt will propagate the event through each parent widget,
+ until it is used or propagated to the Window Manager. (Qt attempts to do
+ this automatically, but it is better programming practice to explicitly
+ invoke the function.)
+
+ \image widgets/mousebutton-buttontester.png
+*/
diff --git a/doc/src/examples/wiggly.qdoc b/doc/src/examples/wiggly.qdoc
index 739f14d623b..677e8b08ca7 100644
--- a/doc/src/examples/wiggly.qdoc
+++ b/doc/src/examples/wiggly.qdoc
@@ -48,10 +48,10 @@
The example consists of two classes:
\list
- \o \c WigglyWidget is the custom widget displaying the text
+ \li \c WigglyWidget is the custom widget displaying the text
in a wiggly line.
- \o \c Dialog is the dialog widget allowing the user to enter a
+ \li \c Dialog is the dialog widget allowing the user to enter a
text. It combines a \c WigglyWidget and a \c QLineEdit.
\endlist
diff --git a/doc/src/examples/windowflags.qdoc b/doc/src/examples/windowflags.qdoc
index e39e4eddc74..09dc45c27fa 100644
--- a/doc/src/examples/windowflags.qdoc
+++ b/doc/src/examples/windowflags.qdoc
@@ -46,10 +46,10 @@
The example consists of two classes:
\list
- \o \c ControllerWindow is the main application widget that allows
+ \li \c ControllerWindow is the main application widget that allows
the user to choose among the available window flags, and displays
the effect on a separate preview window.
- \o \c PreviewWindow is a custom widget displaying the name of
+ \li \c PreviewWindow is a custom widget displaying the name of
its currently set window flags in a read-only text editor.
\endlist
diff --git a/doc/src/gui/coordsys.qdoc b/doc/src/gui/coordsys.qdoc
index ae1506ddd83..655dbf7cf3e 100644
--- a/doc/src/gui/coordsys.qdoc
+++ b/doc/src/gui/coordsys.qdoc
@@ -67,11 +67,11 @@
\table
\row
- \o \inlineimage coordinatesystem-rect.png
- \o \inlineimage coordinatesystem-line.png
+ \li \inlineimage coordinatesystem-rect.png
+ \li \inlineimage coordinatesystem-line.png
\row
- \o QRect(1, 2, 6, 4)
- \o QLine(2, 7, 6, 1)
+ \li QRect(1, 2, 6, 4)
+ \li QLine(2, 7, 6, 1)
\endtable
\section2 Aliased Painting
@@ -92,14 +92,14 @@
\table
\row
- \o \inlineimage coordinatesystem-rect-raster.png
- \o \inlineimage coordinatesystem-line-raster.png
+ \li \inlineimage coordinatesystem-rect-raster.png
+ \li \inlineimage coordinatesystem-line-raster.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 0
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 1
\endtable
@@ -112,19 +112,19 @@
\table
\header
- \o {3,1} QRectF
+ \li {3,1} QRectF
\row
- \o \inlineimage qrect-diagram-zero.png
- \o \inlineimage qrectf-diagram-one.png
+ \li \inlineimage qrect-diagram-zero.png
+ \li \inlineimage qrectf-diagram-one.png
\row
- \o Logical representation
- \o One pixel wide pen
+ \li Logical representation
+ \li One pixel wide pen
\row
- \o \inlineimage qrectf-diagram-two.png
- \o \inlineimage qrectf-diagram-three.png
+ \li \inlineimage qrectf-diagram-two.png
+ \li \inlineimage qrectf-diagram-three.png
\row
- \o Two pixel wide pen
- \o Three pixel wide pen
+ \li Two pixel wide pen
+ \li Three pixel wide pen
\endtable
Note that for historical reasons the return value of the
@@ -158,14 +158,14 @@
\table
\row
- \o \inlineimage coordinatesystem-rect-antialias.png
- \o \inlineimage coordinatesystem-line-antialias.png
+ \li \inlineimage coordinatesystem-rect-antialias.png
+ \li \inlineimage coordinatesystem-line-antialias.png
\row
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 2
- \o
+ \li
\snippet doc/src/snippets/code/doc_src_coordsys.cpp 3
\endtable
@@ -183,15 +183,15 @@
\table
\row
- \o \inlineimage qpainter-clock.png
- \o \inlineimage qpainter-rotation.png
- \o \inlineimage qpainter-scale.png
- \o \inlineimage qpainter-translation.png
+ \li \inlineimage qpainter-clock.png
+ \li \inlineimage qpainter-rotation.png
+ \li \inlineimage qpainter-scale.png
+ \li \inlineimage qpainter-translation.png
\row
- \o nop
- \o \l {QPainter::rotate()}{rotate()}
- \o \l {QPainter::scale()}{scale()}
- \o \l {QPainter::translate()}{translate()}
+ \li nop
+ \li \l {QPainter::rotate()}{rotate()}
+ \li \l {QPainter::scale()}{scale()}
+ \li \l {QPainter::translate()}{translate()}
\endtable
You can also twist the coordinate system around the origin using
@@ -218,10 +218,10 @@
\table 100%
\header
- \o {2,1} Analog Clock Example
+ \li {2,1} Analog Clock Example
\row
- \o \inlineimage coordinatesystem-analogclock.png
- \o
+ \li \inlineimage coordinatesystem-analogclock.png
+ \li
The Analog Clock example shows how to draw the contents of a
custom widget using QPainter's transformation matrix.
@@ -236,7 +236,7 @@
sizes.
\row
- \o {2,1}
+ \li {2,1}
\snippet examples/widgets/analogclock/analogclock.cpp 9
@@ -368,23 +368,23 @@
QPaintDevice, and QPaintEngine classes:
\table
- \header \o Class \o Description
+ \header \li Class \li Description
\row
- \o QPainter
- \o
+ \li QPainter
+ \li
The QPainter class performs low-level painting on widgets and
other paint devices. QPainter can operate on any object that
inherits the QPaintDevice class, using the same code.
\row
- \o QPaintDevice
- \o
+ \li QPaintDevice
+ \li
The QPaintDevice class is the base class of objects that can be
painted. Qt provides several devices: QWidget, QImage, QPixmap,
QPrinter and QPicture, and other devices can also be defined by
subclassing QPaintDevice.
\row
- \o QPaintEngine
- \o
+ \li QPaintEngine
+ \li
The QPaintEngine class provides an abstract definition of how
QPainter draws to a given device on a given platform. Qt 4
provides several premade implementations of QPaintEngine for the
@@ -397,10 +397,10 @@
using the QTransform class:
\table
- \header \o Class \o Description
+ \header \li Class \li Description
\row
- \o QTransform
- \o
+ \li QTransform
+ \li
A 3 x 3 transformation matrix. Use QTransform to rotate, shear,
scale, or translate the coordinate system.
\endtable
@@ -411,45 +411,45 @@
name is suffixed with an \c F.
\table
- \header \o Class \o Description
+ \header \li Class \li Description
\row
- \o \l{QPoint}(\l{QPointF}{F})
- \o
+ \li \l{QPoint}(\l{QPointF}{F})
+ \li
A single 2D point in the coordinate system. Most functions in Qt
that deal with points can accept either a QPoint, a QPointF, two
\c{int}s, or two \c{qreal}s.
\row
- \o \l{QSize}(\l{QSizeF}{F})
- \o
+ \li \l{QSize}(\l{QSizeF}{F})
+ \li
A single 2D vector. Internally, QPoint and QSize are the same, but
a point is not the same as a size, so both classes exist. Again,
most functions accept either QSizeF, a QSize, two \c{int}s, or two
\c{qreal}s.
\row
- \o \l{QRect}(\l{QRectF}{F})
- \o
+ \li \l{QRect}(\l{QRectF}{F})
+ \li
A 2D rectangle. Most functions accept either a QRectF, a QRect,
four \c{int}s, or four \c {qreal}s.
\row
- \o \l{QLine}(\l{QLineF}{F})
- \o
+ \li \l{QLine}(\l{QLineF}{F})
+ \li
A 2D finite-length line, characterized by a start point and an end
point.
\row
- \o \l{QPolygon}(\l{QPolygonF}{F})
- \o
+ \li \l{QPolygon}(\l{QPolygonF}{F})
+ \li
A 2D polygon. A polygon is a vector of \c{QPoint(F)}s. If the
first and last points are the same, the polygon is closed.
\row
- \o QPainterPath
- \o
+ \li QPainterPath
+ \li
A vectorial specification of a 2D shape. Painter paths are the
ultimate painting primitive, in the sense that any shape
(rectange, ellipse, spline) or combination of shapes can be
expressed as a path. A path specifies both an outline and an area.
\row
- \o QRegion
- \o
+ \li QRegion
+ \li
An area in a paint device, expressed as a list of
\l{QRect}s. In general, we recommend using the vectorial
QPainterPath class instead of QRegion for specifying areas,
diff --git a/doc/src/gui/paintsystem.qdoc b/doc/src/gui/paintsystem.qdoc
index f9670ff5d86..4b33e4fed3f 100644
--- a/doc/src/gui/paintsystem.qdoc
+++ b/doc/src/gui/paintsystem.qdoc
@@ -74,13 +74,13 @@
\section1 Topics
\list
- \o \l{Classes for Painting}
- \o \l{Paint Devices and Backends}
- \o \l{Drawing and Filling}
- \o \l{Coordinate System}
- \o \l{Reading and Writing Image Files}
- \o \l{Styling}
- \o \l{Printing with Qt}
+ \li \l{Classes for Painting}
+ \li \l{Paint Devices and Backends}
+ \li \l{Drawing and Filling}
+ \li \l{Coordinate System}
+ \li \l{Reading and Writing Image Files}
+ \li \l{Styling}
+ \li \l{Printing with Qt}
\endlist
\section1 Classes for Painting
@@ -115,14 +115,14 @@
\image paintsystem-devices.png
\table 100%
- \row \o \bold Widget
+ \row \li \b Widget
The QWidget class is the base class of all user interface
objects. The widget is the atom of the user interface: it receives
mouse, keyboard and other events from the window system, and
paints a representation of itself on the screen.
- \row \o \bold Image
+ \row \li \b Image
The QImage class provides a hardware-independent image
representation which is designed and optimized for I/O, and for
@@ -136,7 +136,7 @@
painting can be performed in another thread than the current GUI
thread.
- \row \o \bold Pixmap
+ \row \li \b Pixmap
The QPixmap class is an off-screen image representation which is
designed and optimized for showing images on screen. Unlike
@@ -156,7 +156,7 @@
constructing QRegion objects, and for setting masks for pixmaps
and widgets.
- \row \o \bold {OpenGL Widget}
+ \row \li \b {OpenGL Widget}
As mentioned previously, Qt provides the QtOpenGL module offering
classes that makes it easy to use OpenGL in Qt applications. For
@@ -169,7 +169,7 @@
most drawing operations, such as transformations and pixmap
drawing.
- \row \o \bold {Pixel Buffer}
+ \row \li \b {Pixel Buffer}
The QtOpenGL module also provides the QGLPixelBuffer class which
inherits QPaintDevice directly.
@@ -178,7 +178,7 @@
pbuffer is normally done using full hardware acceleration which
can be significantly faster than rendering into a QPixmap.
- \row \o \bold {Framebuffer Object}
+ \row \li \b {Framebuffer Object}
The QtOpenGL module also provides the QGLFramebufferObject class
which inherits QPaintDevice directly.
@@ -188,7 +188,7 @@
offer several advantages over pixel buffers for this purpose.
These are described in the QGLFramebufferObject class documentation.
- \row \o \bold {Picture}
+ \row \li \b {Picture}
The QPicture class is a paint device that records and replays
QPainter commands. A picture serializes painter commands to an IO
@@ -200,7 +200,7 @@
Qt provides the QPicture::load() and QPicture::save() functions
as well as streaming operators for loading and saving pictures.
- \row \o \bold {Printer}
+ \row \li \b {Printer}
The QPrinter class is a paint device that paints on a printer. On
Windows or Mac OS X, QPrinter uses the built-in printer
@@ -218,7 +218,7 @@
to QPrinter::PdfFormat, QPrinter will generate its output as a PDF
file.
- \row \o \bold {Custom Backends}
+ \row \li \b {Custom Backends}
Support for a new backend can be implemented by deriving from the
QPaintDevice class and reimplementing the virtual
@@ -238,17 +238,17 @@
\table
\row
- \o Windows
- \o Software Rasterizer
+ \li Windows
+ \li Software Rasterizer
\row
- \o X11
- \o X11
+ \li X11
+ \li X11
\row
- \o Mac OS X
- \o CoreGraphics
+ \li Mac OS X
+ \li CoreGraphics
\row
- \o Embedded
- \o Software Rasterizer
+ \li Embedded
+ \li Software Rasterizer
\endtable
Passing a command line parameter to the application, such as,
@@ -289,8 +289,8 @@
\table 100%
\row
- \o \image paintsystem-painterpath.png
- \o \bold QPainterPath
+ \li \image paintsystem-painterpath.png
+ \li \b QPainterPath
A painter path is an object composed of lines and curves. For
example, a rectangle is composed by lines and an ellipse is
@@ -333,8 +333,8 @@
pixels, and the benefits of anti-aliased painting.
\table 100%
- \row \o
- \bold {Anti-Aliased Painting}
+ \row \li
+ \b {Anti-Aliased Painting}
When drawing, the pixel rendering is controlled by the
QPainter::Antialiasing render hint. The QPainter::RenderHint enum
@@ -345,7 +345,7 @@
antialias edges of primitives if possible, i.e. smoothing the
edges by using different color intensities.
- \o \image paintsystem-antialiasing.png
+ \li \image paintsystem-antialiasing.png
\endtable
@@ -376,8 +376,8 @@
\table 100%
\row
- \o \image paintsystem-fancygradient.png
- \o \bold QGradient
+ \li \image paintsystem-fancygradient.png
+ \li \b QGradient
The QGradient class is used in combination with QBrush to specify
gradient fills.
@@ -416,14 +416,14 @@
\table 100%
\row
- \o \bold QMovie
+ \li \b QMovie
QMovie is a convenience class for displaying animations, using the
QImageReader class internally. Once created, the QMovie class
provides various functions for both running and controlling the
given animation.
- \o \image paintsystem-movie.png
+ \li \image paintsystem-movie.png
\endtable
The QImageReader and QImageWriter classes rely on the
@@ -450,8 +450,8 @@
\table 100%
\row
- \o \image paintsystem-svg.png
- \o \bold {SVG Rendering}
+ \li \image paintsystem-svg.png
+ \li \b {SVG Rendering}
Scalable Vector Graphics (SVG) is a language for describing two-dimensional
graphics and graphical applications in XML. SVG 1.1 is a W3C Recommendation
@@ -513,10 +513,10 @@
Most functions for drawing style elements take four arguments:
\list
- \o an enum value specifying which graphical element to draw
- \o a QStyleOption object specifying how and where to render that element
- \o a QPainter object that should be used to draw the element
- \o a QWidget object on which the drawing is performed (optional)
+ \li an enum value specifying which graphical element to draw
+ \li a QStyleOption object specifying how and where to render that element
+ \li a QPainter object that should be used to draw the element
+ \li a QWidget object on which the drawing is performed (optional)
\endlist
The style gets all the information it needs to render the
@@ -538,8 +538,8 @@
\table 100%
\row
- \o \inlineimage paintsystem-icon.png
- \o \bold QIcon
+ \li \inlineimage paintsystem-icon.png
+ \li \b QIcon
The QIcon class provides scalable icons in different modes and states.
diff --git a/doc/src/images/widgets/mousebutton-buttontester.png b/doc/src/images/widgets/mousebutton-buttontester.png
new file mode 100644
index 00000000000..82fcb7617ff
Binary files /dev/null and b/doc/src/images/widgets/mousebutton-buttontester.png differ
diff --git a/doc/src/network/files-and-resources/datastreamformat.qdoc b/doc/src/network/files-and-resources/datastreamformat.qdoc
index 97cadac93ee..8ff31371a27 100644
--- a/doc/src/network/files-and-resources/datastreamformat.qdoc
+++ b/doc/src/network/files-and-resources/datastreamformat.qdoc
@@ -43,326 +43,331 @@
the application happens to be running on.
\table
- \row \o bool
- \o \list
- \o boolean
+ \row \li bool
+ \li \list
+ \li boolean
\endlist
- \row \o qint8
- \o \list
- \o signed byte
+ \row \li qint8
+ \li \list
+ \li signed byte
\endlist
- \row \o qint16
- \o \list
- \o signed 16-bit integer
+ \row \li qint16
+ \li \list
+ \li signed 16-bit integer
\endlist
- \row \o qint32
- \o \list
- \o signed 32-bit integer
+ \row \li qint32
+ \li \list
+ \li signed 32-bit integer
\endlist
- \row \o qint64
- \o \list
- \o signed 64-bit integer
+ \row \li qint64
+ \li \list
+ \li signed 64-bit integer
\endlist
- \row \o quint8
- \o \list
- \o unsigned byte
+ \row \li quint8
+ \li \list
+ \li unsigned byte
\endlist
- \row \o quint16
- \o \list
- \o unsigned 16-bit integer
+ \row \li quint16
+ \li \list
+ \li unsigned 16-bit integer
\endlist
- \row \o quint32
- \o \list
- \o unsigned 32-bit integer
+ \row \li quint32
+ \li \list
+ \li unsigned 32-bit integer
\endlist
- \row \o quint64
- \o \list
- \o unsigned 64-bit integer
+ \row \li quint64
+ \li \list
+ \li unsigned 64-bit integer
\endlist
- \row \o \c float
- \o \list
- \o 32-bit floating point number using the standard IEEE 754 format
+ \row \li \c float
+ \li \list
+ \li 32-bit floating point number using the standard IEEE 754 format
\endlist
- \row \o \c double
- \o \list
- \o 64-bit floating point number using the standard IEEE 754 format
+ \row \li \c double
+ \li \list
+ \li 64-bit floating point number using the standard IEEE 754 format
\endlist
- \row \o \c {const char *}
- \o \list
- \o The string length (quint32)
- \o The string bytes, excluding the terminating 0
+ \row \li \c {const char *}
+ \li \list
+ \li The string length (quint32)
+ \li The string bytes, excluding the terminating 0
\endlist
- \row \o QBitArray
- \o \list
- \o The array size (quint32)
- \o The array bits, i.e. (size + 7)/8 bytes
+ \row \li QBitArray
+ \li \list
+ \li The array size (quint32)
+ \li The array bits, i.e. (size + 7)/8 bytes
\endlist
- \row \o QBrush
- \o \list
- \o The brush style (quint8)
- \o The brush color (QColor)
- \o If style is CustomPattern, the brush pixmap (QPixmap)
+ \row \li QBrush
+ \li \list
+ \li The brush style (quint8)
+ \li The brush color (QColor)
+ \li If style is CustomPattern, the brush pixmap (QPixmap)
\endlist
- \row \o QByteArray
- \o \list
- \o If the byte array is null: 0xFFFFFFFF (quint32)
- \o Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes
+ \row \li QByteArray
+ \li \list
+ \li If the byte array is null: 0xFFFFFFFF (quint32)
+ \li Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes
\endlist
- \row \o \l QColor
- \o \list
- \o Color spec (qint8)
- \o Alpha value (quint16)
- \o Red value (quint16)
- \o Green value (quint16)
- \o Blue value (quint16)
- \o Pad value (quint16)
+ \row \li \l QColor
+ \li \list
+ \li Color spec (qint8)
+ \li Alpha value (quint16)
+ \li Red value (quint16)
+ \li Green value (quint16)
+ \li Blue value (quint16)
+ \li Pad value (quint16)
\endlist
- \row \o QCursor
- \o \list
- \o Shape ID (qint16)
- \o If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint)
+ \row \li QCursor
+ \li \list
+ \li Shape ID (qint16)
+ \li If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint)
\endlist
- \row \o QDate
- \o \list
- \o Julian day (quint32)
+ \row \li QDate
+ \li \list
+ \li Julian day (quint32)
\endlist
- \row \o QDateTime
- \o \list
- \o Date (QDate)
- \o Time (QTime)
- \o 0 for Qt::LocalTime, 1 for Qt::UTC (quint8)
+ \row \li QDateTime
+ \li \list
+ \li Date (QDate)
+ \li Time (QTime)
+ \li 0 for Qt::LocalTime, 1 for Qt::UTC (quint8)
\endlist
- \row \o QEasingCurve
- \o \list
- \o type (quint8)
- \o func (quint64)
- \o hasConfig (bool)
- \o If hasConfig is true then these fields follow:
- \o list
- \o period (double)
- \o amplitude (double)
- \o overshoot (double)
+ \row \li QEasingCurve
+ \li \list
+ \li type (quint8)
+ \li func (quint64)
+ \li hasConfig (bool)
+ \li If hasConfig is true then these fields follow:
+ \li list
+ \li period (double)
+ \li amplitude (double)
+ \li overshoot (double)
\endlist
- \row \o QFont
- \o \list
- \o The family (QString)
- \o The point size (qint16)
- \o The style hint (quint8)
- \o The char set (quint8)
- \o The weight (quint8)
- \o The font bits (quint8)
+ \row \li QFont
+ \li \list
+ \li The family (QString)
+ \li The point size (qint16)
+ \li The style hint (quint8)
+ \li The char set (quint8)
+ \li The weight (quint8)
+ \li The font bits (quint8)
\endlist
- \row \o QHash
- \o \list
- \o The number of items (quint32)
- \o For all items, the key (Key) and value (T)
+ \row \li QHash
+ \li \list
+ \li The number of items (quint32)
+ \li For all items, the key (Key) and value (T)
\endlist
- \row \o QIcon
- \o \list
- \o The number of pixmap entries (quint32)
- \o For all pixmap entries:
+ \row \li QIcon
+ \li \list
+ \li The number of pixmap entries (quint32)
+ \li For all pixmap entries:
\list
- \o The pixmap (QPixmap)
- \o The file name (QString)
- \o The pixmap size (QSize)
- \o The \l{QIcon::Mode}{mode} (quint32)
- \o The \l{QIcon::State}{state} (quint32)
+ \li The pixmap (QPixmap)
+ \li The file name (QString)
+ \li The pixmap size (QSize)
+ \li The \l{QIcon::Mode}{mode} (quint32)
+ \li The \l{QIcon::State}{state} (quint32)
\endlist
\endlist
- \row \o QImage
- \o \list
- \o If the image is null a "null image" marker is saved;
+ \row \li QImage
+ \li \list
+ \li If the image is null a "null image" marker is saved;
otherwise the image is saved in PNG or BMP format (depending
on the stream version). If you want control of the format,
stream the image into a QBuffer (using QImageIO) and stream
that.
\endlist
- \row \o QKeySequence
- \o \list
- \o A QList, where each integer is a key in the key sequence
+ \row \li QKeySequence
+ \li \list
+ \li A QList, where each integer is a key in the key sequence
\endlist
- \row \o QLinkedList
- \o \list
- \o The number of items (quint32)
- \o The items (T)
+ \row \li QLinkedList
+ \li \list
+ \li The number of items (quint32)
+ \li The items (T)
\endlist
- \row \o QList
- \o \list
- \o The number of items (quint32)
- \o The items (T)
+ \row \li QList
+ \li \list
+ \li The number of items (quint32)
+ \li The items (T)
\endlist
- \row \o QMap
- \o \list
- \o The number of items (quint32)
- \o For all items, the key (Key) and value (T)
+ \row \li QMap
+ \li \list
+ \li The number of items (quint32)
+ \li For all items, the key (Key) and value (T)
\endlist
- \row \o QMargins
- \o \list
- \o left (int)
- \o top (int)
- \o right (int)
- \o bottom (int)
+ \row \li QMargins
+ \li \list
+ \li left (int)
+ \li top (int)
+ \li right (int)
+ \li bottom (int)
\endlist
- \row \o QMatrix
- \o \list
- \o m11 (double)
- \o m12 (double)
- \o m21 (double)
- \o m22 (double)
- \o dx (double)
- \o dy (double)
+ \row \li QMatrix
+ \li \list
+ \li m11 (double)
+ \li m12 (double)
+ \li m21 (double)
+ \li m22 (double)
+ \li dx (double)
+ \li dy (double)
\endlist
- \row \o QMatrix4x4
- \o \list
- \o m11 (double)
- \o m12 (double)
- \o m13 (double)
- \o m14 (double)
- \o m21 (double)
- \o m22 (double)
- \o m23 (double)
- \o m24 (double)
- \o m31 (double)
- \o m32 (double)
- \o m33 (double)
- \o m34 (double)
- \o m41 (double)
- \o m42 (double)
- \o m43 (double)
- \o m44 (double)
+ \row \li QMatrix4x4
+ \li \list
+ \li m11 (double)
+ \li m12 (double)
+ \li m13 (double)
+ \li m14 (double)
+ \li m21 (double)
+ \li m22 (double)
+ \li m23 (double)
+ \li m24 (double)
+ \li m31 (double)
+ \li m32 (double)
+ \li m33 (double)
+ \li m34 (double)
+ \li m41 (double)
+ \li m42 (double)
+ \li m43 (double)
+ \li m44 (double)
\endlist
- \row \o QPair
- \o \list
- \o first (T1)
- \o second (T2)
+ \row \li QPair
+ \li \list
+ \li first (T1)
+ \li second (T2)
\endlist
- \row \o QPalette
- \o The disabled, active, and inactive color groups, each of which consists
+ \row \li QPalette
+ \li The disabled, active, and inactive color groups, each of which consists
of the following:
\list
- \o foreground (QBrush)
- \o button (QBrush)
- \o light (QBrush)
- \o midlight (QBrush)
- \o dark (QBrush)
- \o mid (QBrush)
- \o text (QBrush)
- \o brightText (QBrush)
- \o buttonText (QBrush)
- \o base (QBrush)
- \o background (QBrush)
- \o shadow (QBrush)
- \o highlight (QBrush)
- \o highlightedText (QBrush)
- \o link (QBrush)
- \o linkVisited (QBrush)
+ \li foreground (QBrush)
+ \li button (QBrush)
+ \li light (QBrush)
+ \li midlight (QBrush)
+ \li dark (QBrush)
+ \li mid (QBrush)
+ \li text (QBrush)
+ \li brightText (QBrush)
+ \li buttonText (QBrush)
+ \li base (QBrush)
+ \li background (QBrush)
+ \li shadow (QBrush)
+ \li highlight (QBrush)
+ \li highlightedText (QBrush)
+ \li link (QBrush)
+ \li linkVisited (QBrush)
\endlist
- \row \o QPen
- \o \list
- \o The pen styles (quint8)
- \o The pen width (quint16)
- \o The pen color (QColor)
+ \row \li QPen
+ \li \list
+ \li The pen styles (quint8)
+ \li The pen width (quint16)
+ \li The pen color (QColor)
\endlist
- \row \o QPicture
- \o \list
- \o The size of the picture data (quint32)
- \o The raw bytes of picture data (char)
+ \row \li QPicture
+ \li \list
+ \li The size of the picture data (quint32)
+ \li The raw bytes of picture data (char)
\endlist
- \row \o QPixmap
- \o \list
- \o Save it as a PNG image.
+ \row \li QPixmap
+ \li \list
+ \li Save it as a PNG image.
\endlist
- \row \o QPoint
- \o \list
- \o The x coordinate (qint32)
- \o The y coordinate (qint32)
+ \row \li QPoint
+ \li \list
+ \li The x coordinate (qint32)
+ \li The y coordinate (qint32)
\endlist
- \row \o QQuaternion
- \o \list
- \o The scalar component (double)
- \o The x coordinate (double)
- \o The y coordinate (double)
- \o The z coordinate (double)
+ \row \li QQuaternion
+ \li \list
+ \li The scalar component (double)
+ \li The x coordinate (double)
+ \li The y coordinate (double)
+ \li The z coordinate (double)
\endlist
- \row \o QRect
- \o \list
- \o left (qint32)
- \o top (qint32)
- \o right (qint32)
- \o bottom (qint32)
+ \row \li QRect
+ \li \list
+ \li left (qint32)
+ \li top (qint32)
+ \li right (qint32)
+ \li bottom (qint32)
\endlist
- \row \o QRegExp
- \o \list
- \o The regexp pattern (QString)
- \o Case sensitivity (quint8)
- \o Regular expression syntax (quint8)
- \o Minimal matching (quint8)
+ \row \li QRegExp
+ \li \list
+ \li The regexp pattern (QString)
+ \li Case sensitivity (quint8)
+ \li Regular expression syntax (quint8)
+ \li Minimal matching (quint8)
\endlist
- \row \o QRegion
- \o \list
- \o The size of the data, i.e. 8 + 16 * (number of rectangles) (quint32)
- \o 10 (qint32)
- \o The number of rectangles (quint32)
- \o The rectangles in sequential order (QRect)
+ \row \li QRegularExpression
+ \li \list
+ \li The regular expression pattern (QString)
+ \li The pattern options (quint32)
\endlist
- \row \o QSize
- \o \list
- \o width (qint32)
- \o height (qint32)
+ \row \li QRegion
+ \li \list
+ \li The size of the data, i.e. 8 + 16 * (number of rectangles) (quint32)
+ \li 10 (qint32)
+ \li The number of rectangles (quint32)
+ \li The rectangles in sequential order (QRect)
\endlist
- \row \o QString
- \o \list
- \o If the string is null: 0xFFFFFFFF (quint32)
- \o Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
+ \row \li QSize
+ \li \list
+ \li width (qint32)
+ \li height (qint32)
\endlist
- \row \o QTime
- \o \list
- \o Milliseconds since midnight (quint32)
+ \row \li QString
+ \li \list
+ \li If the string is null: 0xFFFFFFFF (quint32)
+ \li Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
\endlist
- \row \o QTransform
- \o \list
- \o m11 (double)
- \o m12 (double)
- \o m13 (double)
- \o m21 (double)
- \o m22 (double)
- \o m23 (double)
- \o m31 (double)
- \o m32 (double)
- \o m33 (double)
+ \row \li QTime
+ \li \list
+ \li Milliseconds since midnight (quint32)
\endlist
- \row \o QUrl
- \o \list
- \o Holds an URL (QString)
+ \row \li QTransform
+ \li \list
+ \li m11 (double)
+ \li m12 (double)
+ \li m13 (double)
+ \li m21 (double)
+ \li m22 (double)
+ \li m23 (double)
+ \li m31 (double)
+ \li m32 (double)
+ \li m33 (double)
\endlist
- \row \o QVariant
- \o \list
- \o The type of the data (quint32)
- \o The null flag (qint8)
- \o The data of the specified type
+ \row \li QUrl
+ \li \list
+ \li Holds an URL (QString)
\endlist
- \row \o QVector2D
- \o \list
- \o the x coordinate (double)
- \o the y coordinate (double)
+ \row \li QVariant
+ \li \list
+ \li The type of the data (quint32)
+ \li The null flag (qint8)
+ \li The data of the specified type
\endlist
- \row \o QVector3D
- \o \list
- \o the x coordinate (double)
- \o the y coordinate (double)
- \o the z coordinate (double)
+ \row \li QVector2D
+ \li \list
+ \li the x coordinate (double)
+ \li the y coordinate (double)
\endlist
- \row \o QVector4D
- \o \list
- \o the x coordinate (double)
- \o the y coordinate (double)
- \o the z coordinate (double)
- \o the w coordinate (double)
+ \row \li QVector3D
+ \li \list
+ \li the x coordinate (double)
+ \li the y coordinate (double)
+ \li the z coordinate (double)
\endlist
- \row \o QVector
- \o \list
- \o The number of items (quint32)
- \o The items (T)
+ \row \li QVector4D
+ \li \list
+ \li the x coordinate (double)
+ \li the y coordinate (double)
+ \li the z coordinate (double)
+ \li the w coordinate (double)
+ \endlist
+ \row \li QVector
+ \li \list
+ \li The number of items (quint32)
+ \li The items (T)
\endlist
\endtable
*/
diff --git a/doc/src/network/network-programming/bearermanagement.qdoc b/doc/src/network/network-programming/bearermanagement.qdoc
index bcedc85a590..91dc32c5a5d 100644
--- a/doc/src/network/network-programming/bearermanagement.qdoc
+++ b/doc/src/network/network-programming/bearermanagement.qdoc
@@ -81,16 +81,16 @@ lists the major QNetworkSession functions and how they fit into the session and
hardware management categories:
\table 60%
-\header \o Interface management \o Session management
-\row \o QNetworkSession::stop() \o QNetworkSession::open()
-\row \o QNetworkSession::interface() \o QNetworkSession::close()
-\row \o QNetworkSession::state() \o QNetworkSession::isOpen()
-\row \o QNetworkSession::bytesWritten() \o QNetworkSession::migrate()
-\row \o QNetworkSession::bytesReceived() \o QNetworkSession::ignore()
-\row \o QNetworkSession::activeTime() \o QNetworkSession::accept()
-\row \o QNetworkSession::stateChanged() \o QNetworkSession::reject()
-\row \o \o QNetworkSession::opened()
-\row \o \o QNetworkSession::closed()
+\header \li Interface management \li Session management
+\row \li QNetworkSession::stop() \li QNetworkSession::open()
+\row \li QNetworkSession::interface() \li QNetworkSession::close()
+\row \li QNetworkSession::state() \li QNetworkSession::isOpen()
+\row \li QNetworkSession::bytesWritten() \li QNetworkSession::migrate()
+\row \li QNetworkSession::bytesReceived() \li QNetworkSession::ignore()
+\row \li QNetworkSession::activeTime() \li QNetworkSession::accept()
+\row \li QNetworkSession::stateChanged() \li QNetworkSession::reject()
+\row \li \li QNetworkSession::opened()
+\row \li \li QNetworkSession::closed()
\endtable
The state of the session represents the state of the underlying access point
@@ -242,27 +242,27 @@ determining the feature support:
\table
\header
- \o Platform
- \o Backend capabilities
+ \li Platform
+ \li Backend capabilities
\row
- \o Linux\unicode{0xAE}
- \o Linux uses the \l {http://projects.gnome.org/NetworkManager}{NetworkManager}
+ \li Linux\unicode{0xAE}
+ \li Linux uses the \l {http://projects.gnome.org/NetworkManager}{NetworkManager}
and \l {http://connman.net/}{ConnMan} / \l {http://ofono.org/}{oFono} APIs
which support interface notifications and starting and stopping of network
interfaces.
\row
- \o Windows\unicode{0xAE} XP
- \o This platform supports interface notifications without active polling.
+ \li Windows\unicode{0xAE} XP
+ \li This platform supports interface notifications without active polling.
\row
- \o Windows XP SP2+Hotfixes, Windows XP SP3, Windows Vista, Windows 7
- \o In addition to standard Windows XP wifi access point monitoring has been improved which includes the ability to start and stop wifi interfaces. This requires Windows to manage the wifi interfaces.
+ \li Windows XP SP2+Hotfixes, Windows XP SP3, Windows Vista, Windows 7
+ \li In addition to standard Windows XP wifi access point monitoring has been improved which includes the ability to start and stop wifi interfaces. This requires Windows to manage the wifi interfaces.
\row
- \o Mac OS\unicode{0xAE}
- \o This platform has full support by way of CoreWLAN offered in Mac OS 10.6. Previous
+ \li Mac OS\unicode{0xAE}
+ \li This platform has full support by way of CoreWLAN offered in Mac OS 10.6. Previous
versions of Mac OS - 10.5 and 10.4 have limited support.
\row
- \o All other platforms (*nix, Windows Mobile)
- \o This backend is the fallback for all platforms supports network interface notifications via active polling only.
+ \li All other platforms (*nix, Windows Mobile)
+ \li This backend is the fallback for all platforms supports network interface notifications via active polling only.
\endtable
*/
diff --git a/doc/src/printsupport/printing.qdoc b/doc/src/printsupport/printing.qdoc
index 5277d1c5475..5447032a2be 100644
--- a/doc/src/printsupport/printing.qdoc
+++ b/doc/src/printsupport/printing.qdoc
@@ -112,7 +112,7 @@
too small for the higher resolutions of typical printers.
\table
- \row \o \bold{Printer and Painter Coordinate Systems}
+ \row \li \b{Printer and Painter Coordinate Systems}
The \l{QPrinter::}{paperRect()} and \l{QPrinter::}{pageRect()} functions
provide information about the size of the paper used for printing and the
@@ -126,7 +126,7 @@
rectangle, and painting operations will be clipped to the bounds of the
drawable part of the page.
- \o \inlineimage printer-rects.png
+ \li \inlineimage printer-rects.png
\endtable
The paint system automatically uses the correct device metrics when painting
@@ -164,12 +164,12 @@
functionality can be obtained via a function in the corresponding widget's API.
\table
- \header \o Widget \o Printing function \o Accepts
- \row \o QGraphicsView \o QGraphicsView::render() \o QPainter
- \row \o QSvgWidget \o QSvgRenderer::render() \o QPainter
- \row \o QTextEdit \o QTextDocument::print() \o QPrinter
- \row \o QTextLayout \o QTextLayout::draw() \o QPainter
- \row \o QTextLine \o QTextLine::draw() \o QPainter
+ \header \li Widget \li Printing function \li Accepts
+ \row \li QGraphicsView \li QGraphicsView::render() \li QPainter
+ \row \li QSvgWidget \li QSvgRenderer::render() \li QPainter
+ \row \li QTextEdit \li QTextDocument::print() \li QPrinter
+ \row \li QTextLayout \li QTextLayout::draw() \li QPainter
+ \row \li QTextLine \li QTextLine::draw() \li QPainter
\endtable
QTextEdit requires a QPrinter rather than a QPainter because it uses information
diff --git a/doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp b/doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp
new file mode 100644
index 00000000000..cab89d9c9e6
--- /dev/null
+++ b/doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Giuseppe D'Angelo .
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//! [0]
+QRegularExpression re("a pattern");
+//! [0]
+
+
+//! [1]
+QRegularExpression re;
+re.setPattern("another pattern");
+//! [1]
+
+
+//! [2]
+// matches two digits followed by a space and a word
+QRegularExpression re("\\d\\d \\w+");
+
+// matches a backslash
+QRegularExpression re2("\\\\");
+//! [2]
+
+
+//! [3]
+QRegularExpression re("a third pattern");
+QString pattern = re.pattern(); // pattern == "a third pattern"
+//! [3]
+
+
+//! [4]
+// matches "Qt rocks", but also "QT rocks", "QT ROCKS", "qT rOcKs", etc.
+QRegularExpression re("Qt rocks", QRegularExpression::CaseInsensitiveOption);
+//! [4]
+
+
+//! [5]
+QRegularExpression re("^\\d+$");
+re.setPatternOptions(QRegularExpression::MultilineOption);
+// re matches any line in the subject string that contains only digits (but at least one)
+//! [5]
+
+
+//! [6]
+QRegularExpression re = QRegularExpression("^two.*words$", QRegularExpression::MultilineOption
+ | QRegularExpression::DotMatchesEverythingOption);
+
+QRegularExpression::PatternOptions options = re.patternOptions();
+// options == QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption
+//! [6]
+
+
+//! [7]
+// match two digits followed by a space and a word
+QRegularExpression re("\\d\\d \\w+");
+QRegularExpressionMatch match = re.match("abc123 def");
+bool hasMatch = match.hasMatch(); // true
+//! [7]
+
+
+//! [8]
+QRegularExpression re("\\d\\d \\w+");
+QRegularExpressionMatch match = re.match("abc123 def");
+if (match.hasMatch()) {
+ QString matched = match.captured(0); // matched == "23 def"
+ // ...
+}
+//! [8]
+
+
+//! [9]
+QRegularExpression re("\\d\\d \\w+");
+QRegularExpressionMatch match = re.match("12 abc 45 def", 1);
+if (match.hasMatch()) {
+ QString matched = match.captured(0); // matched == "45 def"
+ // ...
+}
+//! [9]
+
+
+//! [10]
+QRegularExpression re("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$");
+QRegularExpressionMatch match = re.match("08/12/1985");
+if (match.hasMatch()) {
+ QString day = re.captured(1); // day == "08"
+ QString month = re.captured(2); // month == "12"
+ QString year = re.captured(3); // year == "1985"
+ // ...
+}
+//! [10]
+
+
+//! [11]
+QRegularExpression re("abc(\\d+)def");
+QRegularExpressionMatch match = re.match("XYZabc123defXYZ");
+if (match.hasMatch()) {
+ int startOffset = re.capturedStart(1); // startOffset == 6
+ int endOffset = re.capturedEnd(1); // endOffset == 9
+ // ...
+}
+//! [11]
+
+
+//! [12]
+QRegularExpression re("^(?\\d\\d)/(?\\d\\d)/(?\\d\\d\\d\\d)$");
+QRegularExpressionMatch match = re.match("08/12/1985");
+if (match.hasMatch()) {
+ QString date = match.captured("date"); // date == "08"
+ QString month = match.captured("month"); // month == "12"
+ QString year = match.captured("year"); // year == 1985
+}
+//! [12]
+
+
+//! [13]
+QRegularExpression re("(\\w+)");
+QRegularExpressionMatchIterator i = re.globalMatch("the quick fox");
+//! [13]
+
+
+//! [14]
+QStringList words;
+while (i.hasNext()) {
+ QRegularExpressionMatch match = i.next();
+ QString word = match.captured(1);
+ words << word;
+}
+// words contains "the", "quick", "fox"
+//! [14]
+
+
+//! [15]
+QString pattern("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d\\d?, \\d\\d\\d\\d$");
+QRegularExpression re(pattern);
+
+QString input("Jan 21,");
+QRegularExpressionMatch match = re.match(input, 0, QRegularExpressionMatch::PartialPreferCompleteMatch);
+bool hasMatch = match.hasMatch(); // false
+bool hasPartialMatch = match.hasPartialMatch(); // true
+//! [15]
+
+
+//! [16]
+QString input("Dec 8, 1985");
+QRegularExpressionMatch match = re.match(input, 0, QRegularExpressionMatch::PartialPreferCompleteMatch);
+bool hasMatch = match.hasMatch(); // true
+bool hasPartialMatch = match.hasPartialMatch(); // false
+//! [16]
+
+
+//! [17]
+QRegularExpression re("abc\\w+X|def");
+QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpressionMatch::PartialPreferCompleteMatch);
+bool hasMatch = match.hasMatch(); // true
+bool hasPartialMatch = match.hasPartialMatch(); // false
+QString captured = match.captured(0); // captured == "def"
+//! [17]
+
+
+//! [18]
+QRegularExpression re("abc\\w+X|defY");
+QRegularExpressionMatch match = re.match("abcdef", 0, QRegularExpressionMatch::PartialPreferCompleteMatch);
+bool hasMatch = match.hasMatch(); // false
+bool hasPartialMatch = match.hasPartialMatch(); // true
+QString captured = match.captured(0); // captured == "abcdef"
+//! [18]
+
+
+//! [19]
+QRegularExpression re("abc|ab");
+QRegularExpressionMatch match = re.match("ab", 0, QRegularExpressionMatch::PartialPreferFirstMatch);
+bool hasMatch = match.hasMatch(); // false
+bool hasPartialMatch = match.hasPartialMatch(); // true
+//! [19]
+
+
+//! [20]
+QRegularExpression re("abc(def)?");
+QRegularExpressionMatch match = re.match("abc", 0, QRegularExpressionMatch::PartialPreferFirstMatch);
+bool hasMatch = match.hasMatch(); // false
+bool hasPartialMatch = match.hasPartialMatch(); // true
+//! [20]
+
+//! [21]
+QRegularExpression re("(abc)*");
+QRegularExpressionMatch match = re.match("abc", 0, QRegularExpressionMatch::PartialPreferFirstMatch);
+bool hasMatch = match.hasMatch(); // false
+bool hasPartialMatch = match.hasPartialMatch(); // true
+//! [21]
+
+//! [22]
+QRegularExpression invalidRe("(unmatched|parenthesis");
+bool isValid = invalidRe.isValid(); // false
+//! [22]
+
+//! [23]
+QRegularExpression invalidRe("(unmatched|parenthesis");
+if (!invalidRe.isValid()) {
+ QString errorString = invalidRe.errorString(); // errorString == "missing )"
+ int errorOffset = invalidRe.patternErrorOffset(); // errorOffset == 22
+ // ...
+}
+//! [23]
+
+//! [24]
+QRegularExpression re("^this pattern must match exactly$");
+//! [24]
+
+//! [25]
+QString p("a .*|pattern");
+QRegularExpression re("\\A(?:" + p + ")\\z"); // re matches exactly the pattern string p
+//! [25]
+
+//! [26]
+QString escaped = QRegularExpression::escape("a(x) = f(x) + g(x)");
+// escaped == "a\\(x\\)\\ \\=\\ f\\(x\\)\\ \\+\\ g\\(x\\)"
+//! [26]
+
+//! [27]
+QString pattern = "(" + QRegularExpression::escape(name) +
+ "|" + QRegularExpression::escape(nickname) + ")";
+QRegularExpression re(pattern);
+//! [27]
+
+//! [28]
+QRegularExpressionMatch match = re.match(...);
+for (int i = 0; i <= match.lastCapturedIndex(); ++i) {
+ QString captured = match.captured(i);
+ // ...
+}
+//! [28]
+
+//! [29]
+QRegularExpression("(\d\d) (?\w+)");
+QRegularExpressionMatch match = re.match("23 Jordan");
+if (match.hasMatch()) {
+ QString number = match.captured(1); // first == "23"
+ QString name = match.captured("name"); // name == "Jordan"
+}
+//! [29]
+
+//! [30]
+// extracts the words
+QRegularExpression re("(\w+)");
+QString subject("the quick fox");
+QRegularExpressionMatchIterator i = re.globalMatch(subject);
+while (i.hasNext()) {
+ QRegularExpressionMatch match = i.next();
+ // ...
+}
+//! [30]
+
+
diff --git a/doc/src/sql/sql-programming/qsqldatatype-table.qdoc b/doc/src/sql/sql-programming/qsqldatatype-table.qdoc
index bc1c8b3c13b..a7e03cf28f1 100644
--- a/doc/src/sql/sql-programming/qsqldatatype-table.qdoc
+++ b/doc/src/sql/sql-programming/qsqldatatype-table.qdoc
@@ -48,518 +48,518 @@
\table 90%
\header
- \o IBM DB2 data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li IBM DB2 data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL
- \o 32-bit Single-precision floating point
- \o By default mapping to QString
+ \li REAL
+ \li 32-bit Single-precision floating point
+ \li By default mapping to QString
\row
- \o DOUBLE PRECISION
- \o 64-bit Double-precision floating point
- \o By default mapping to QString
+ \li DOUBLE PRECISION
+ \li 64-bit Double-precision floating point
+ \li By default mapping to QString
\row
- \o FLOAT
- \o 64-bit Double-precision floating point
- \o By default mapping to QString
+ \li FLOAT
+ \li 64-bit Double-precision floating point
+ \li By default mapping to QString
\row
- \o CHAR
- \o Fixed-length, null-terminated character string
- \o Mapped to QString
+ \li CHAR
+ \li Fixed-length, null-terminated character string
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Null-terminated varying length string
- \o Mapped to QString
+ \li VARCHAR
+ \li Null-terminated varying length string
+ \li Mapped to QString
\row
- \o LONG VARCHAR
- \o Not null-terminated varying length character string
- \o Mapped to QString
+ \li LONG VARCHAR
+ \li Not null-terminated varying length character string
+ \li Mapped to QString
\row
- \o BLOB
- \o Not null-terminated varying binary string with 4-byte string
+ \li BLOB
+ \li Not null-terminated varying binary string with 4-byte string
length indicator
- \o Mapped to QByteArray
+ \li Mapped to QByteArray
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o DATE
- \o Null-terminated character string of the following format:
+ \li DATE
+ \li Null-terminated character string of the following format:
yyyy-mm-dd
- \o Mapped to QDate
+ \li Mapped to QDate
\row
- \o TIME
- \o Null-terminated character string of the following format: hh.mm.ss
- \o Mapped to QTime
+ \li TIME
+ \li Null-terminated character string of the following format: hh.mm.ss
+ \li Mapped to QTime
\row
- \o TIMESTAMP
- \o Null-terminated character string of the following format: yyyy-mm-dd-hh.mm.ss.nnnnnn
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Null-terminated character string of the following format: yyyy-mm-dd-hh.mm.ss.nnnnnn
+ \li Mapped to QDateTime
\endtable
\section2 Borland InterBase Data Types
\table 90%
\header
- \o Borland InterBase data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li Borland InterBase data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BOOLEAN
- \o Boolean
- \o bool
+ \li BOOLEAN
+ \li Boolean
+ \li bool
\row
- \o TINYINT
- \o 8 bit signed integer
- \o typedef qint8
+ \li TINYINT
+ \li 8 bit signed integer
+ \li typedef qint8
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT LONG
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT LONG
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL FLOAT
- \o 32-bit floating point
- \o By default mapping to QString
+ \li REAL FLOAT
+ \li 32-bit floating point
+ \li By default mapping to QString
\row
- \o FLOAT
- \o 64-bit floating point
- \o By default mapping to QString
+ \li FLOAT
+ \li 64-bit floating point
+ \li By default mapping to QString
\row
- \o DOUBLE
- \o 64-bit floating point
- \o By default mapping to QString
+ \li DOUBLE
+ \li 64-bit floating point
+ \li By default mapping to QString
\row
- \o DOUBLE PRECISION
- \o 64-bit Double-precision floating point
- \o By default mapping to QString
+ \li DOUBLE PRECISION
+ \li 64-bit Double-precision floating point
+ \li By default mapping to QString
\row
- \o VARCHAR STRING
- \o Character string, Unicode
- \o Mapped to QString
+ \li VARCHAR STRING
+ \li Character string, Unicode
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o DATE
- \o Displays date. Format: 'yyyy-mm-dd'
- \o Mapped to QDate
+ \li DATE
+ \li Displays date. Format: 'yyyy-mm-dd'
+ \li Mapped to QDate
\row
- \o TIME
- \o Displays time. Format is 'hh:mm:ss' in 24-hour format
- \o Mapped to QTime
+ \li TIME
+ \li Displays time. Format is 'hh:mm:ss' in 24-hour format
+ \li Mapped to QTime
\row
- \o TIMESTAMP
- \o Displays a timestamp. Format is 'yyyy-mm-dd hh:mm:ss'
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Displays a timestamp. Format is 'yyyy-mm-dd hh:mm:ss'
+ \li Mapped to QDateTime
\endtable
\section2 MySQL Data Types
\table 90%
\header
- \o MySQL data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li MySQL data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o TINYINT
- \o 8 bit signed integer
- \o typedef qint8
+ \li TINYINT
+ \li 8 bit signed integer
+ \li typedef qint8
\row
- \o TINYINT UNSIGNED
- \o 8 bit unsigned integer
- \o typedef quint8
+ \li TINYINT UNSIGNED
+ \li 8 bit unsigned integer
+ \li typedef quint8
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o SMALLINT UNSIGNED
- \o 16-bit unsigned integer
- \o typedef quint16
+ \li SMALLINT UNSIGNED
+ \li 16-bit unsigned integer
+ \li typedef quint16
\row
- \o INT
- \o 32-bit signed integer
- \o typedef qint32
+ \li INT
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o INT UNSIGNED
- \o 32-bit unsigned integer
- \o typedef quint32
+ \li INT UNSIGNED
+ \li 32-bit unsigned integer
+ \li typedef quint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o FLOAT
- \o 32-bit Floating Point
- \o By default mapping to QString
+ \li FLOAT
+ \li 32-bit Floating Point
+ \li By default mapping to QString
\row
- \o DOUBLE
- \o 64-bit Floating Point
- \o By default mapping to QString
+ \li DOUBLE
+ \li 64-bit Floating Point
+ \li By default mapping to QString
\row
- \o CHAR
- \o Character string
- \o Mapped to QString
+ \li CHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Character string
- \o Mapped to QString
+ \li VARCHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o TINYTEXT
- \o Character string
- \o Mapped to QString
+ \li TINYTEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o TEXT
- \o Character string
- \o Mapped to QString
+ \li TEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o MEDIUMTEXT
- \o Character string
- \o Mapped to QString
+ \li MEDIUMTEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o LONGTEXT
- \o Character string
- \o Mapped to QString
+ \li LONGTEXT
+ \li Character string
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o all BLOB types
- \o BLOB
- \o Mapped to QByteArray
+ \li all BLOB types
+ \li BLOB
+ \li Mapped to QByteArray
\row
- \o DATE
- \o Date without Time
- \o Mapped to QDate
+ \li DATE
+ \li Date without Time
+ \li Mapped to QDate
\row
- \o DATETIME
- \o Date and Time
- \o Mapped to QDateTime
+ \li DATETIME
+ \li Date and Time
+ \li Mapped to QDateTime
\row
- \o TIMESTAMP
- \o Date and Time
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Date and Time
+ \li Mapped to QDateTime
\row
- \o TIME
- \o Time
- \o Mapped to QTime
+ \li TIME
+ \li Time
+ \li Mapped to QTime
\row
- \o YEAR
- \o Year (int)
- \o Mapped to QDateTime
+ \li YEAR
+ \li Year (int)
+ \li Mapped to QDateTime
\row
- \o ENUM
- \o Enumeration of Value Set
- \o Mapped to QString
+ \li ENUM
+ \li Enumeration of Value Set
+ \li Mapped to QString
\endtable
\section2 Oracle Call Interface Data Types
\table 90%
\header
- \o Oracle Call Interface data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li Oracle Call Interface data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o NUMBER
- \o FLOAT, DOUBLE, PRECISIONc REAL
- \o By default mapping to QString
+ \li NUMBER
+ \li FLOAT, DOUBLE, PRECISIONc REAL
+ \li By default mapping to QString
\row
- \o NUMBER(38)
- \o INTEGER INT SMALLINT
- \o typedef qint8/16/32/64
+ \li NUMBER(38)
+ \li INTEGER INT SMALLINT
+ \li typedef qint8/16/32/64
\row
- \o NUMBER(p,s)
- \o NUMERIC(p,s) DECIMAL(p,s)a
- \o By default mapping to QString
+ \li NUMBER(p,s)
+ \li NUMERIC(p,s) DECIMAL(p,s)a
+ \li By default mapping to QString
\row
- \o NVARCHAR2(n)
- \o Character string (NATIONAL CHARACTER VARYING(n) NATIONAL
+ \li NVARCHAR2(n)
+ \li Character string (NATIONAL CHARACTER VARYING(n) NATIONAL
CHAR VARYING(n) NCHAR VARYING(n))
- \o Mapped to QString
+ \li Mapped to QString
\row
- \o NCHAR(n)
- \o Character string (NATIONAL CHARACTER(n) NATIONAL CHAR(n)
+ \li NCHAR(n)
+ \li Character string (NATIONAL CHARACTER(n) NATIONAL CHAR(n)
NCHAR(n))
- \o Mapped to QString
+ \li Mapped to QString
\row
- \o CHAR(n)
- \o Character string (CHARACTER(n) CHAR(n))
- \o Mapped to QString
+ \li CHAR(n)
+ \li Character string (CHARACTER(n) CHAR(n))
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o BLOB
- \o A binary large object
- \o Mapped to QByteArray
+ \li BLOB
+ \li A binary large object
+ \li Mapped to QByteArray
\row
- \o TIMESTAMP
- \o Year, month, and day values of date, as well as hour, minute,
+ \li TIMESTAMP
+ \li Year, month, and day values of date, as well as hour, minute,
and second values of time
- \o Mapped to QDateTime
+ \li Mapped to QDateTime
\endtable
\section2 ODBC Data Types
\table 90%
\header
- \o ODBC data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li ODBC data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BIT
- \o Boolean
- \o BOOL
+ \li BIT
+ \li Boolean
+ \li BOOL
\row
- \o TINYINT
- \o 8 bit integer
- \o typedef qint8
+ \li TINYINT
+ \li 8 bit integer
+ \li typedef qint8
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL
- \o 32-bit Single-precision floating point
- \o By default mapping to QString
+ \li REAL
+ \li 32-bit Single-precision floating point
+ \li By default mapping to QString
\row
- \o FLOAT
- \o 64-bit Double floating point
- \o By default mapping to QString
+ \li FLOAT
+ \li 64-bit Double floating point
+ \li By default mapping to QString
\row
- \o DOUBLE
- \o 64-bit Double floating point
- \o By default mapping to QString
+ \li DOUBLE
+ \li 64-bit Double floating point
+ \li By default mapping to QString
\row
- \o CHAR
- \o Character string
- \o Mapped to QString
+ \li CHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Character string
- \o Mapped to QString
+ \li VARCHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o LONGVARCHAR
- \o Character string
- \o Mapped to QString
+ \li LONGVARCHAR
+ \li Character string
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o DATE
- \o Character string
- \o Mapped to QDate
+ \li DATE
+ \li Character string
+ \li Mapped to QDate
\row
- \o TIME
- \o Character Time, Character string
- \o Mapped to QTime
+ \li TIME
+ \li Character Time, Character string
+ \li Mapped to QTime
\row
- \o TIMESTAMP
- \o Character Time, Character string
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li Character Time, Character string
+ \li Mapped to QDateTime
\endtable
\section2 PostgreSQL Data Types
\table 90%
\header
- \o PostgreSQL data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li PostgreSQL data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BOOLEAN
- \o Boolean
- \o bool
+ \li BOOLEAN
+ \li Boolean
+ \li bool
\row
- \o SMALLINT
- \o 16-bit signed integer
- \o typedef qint16
+ \li SMALLINT
+ \li 16-bit signed integer
+ \li typedef qint16
\row
- \o INTEGER
- \o 32-bit signed integer
- \o typedef qint32
+ \li INTEGER
+ \li 32-bit signed integer
+ \li typedef qint32
\row
- \o BIGINT
- \o 64-bit signed integer
- \o typedef qint64
+ \li BIGINT
+ \li 64-bit signed integer
+ \li typedef qint64
\row
- \o REAL
- \o 32-bit variable-precision floating point
- \o By default mapping to QString
+ \li REAL
+ \li 32-bit variable-precision floating point
+ \li By default mapping to QString
\row
- \o DOUBLE PRECISION
- \o 64-bit variable-precision floating point
- \o By default mapping to QString
+ \li DOUBLE PRECISION
+ \li 64-bit variable-precision floating point
+ \li By default mapping to QString
\row
- \o DECIMAL VARIABLE
- \o user-specified precision, exact
- \o Mapped to QString
+ \li DECIMAL VARIABLE
+ \li user-specified precision, exact
+ \li Mapped to QString
\row
- \o NUMERIC VARIABLE
- \o user-specified precision, exact
- \o Mapped to QString
+ \li NUMERIC VARIABLE
+ \li user-specified precision, exact
+ \li Mapped to QString
\row
- \o VARCHAR
- \o variable-length character string
- \o Mapped to QString
+ \li VARCHAR
+ \li variable-length character string
+ \li Mapped to QString
\row
- \o CHARACTER
- \o Character string of fixed-length
- \o Mapped to QString
+ \li CHARACTER
+ \li Character string of fixed-length
+ \li Mapped to QString
\row
- \o TEXT
- \o Character string of variable-length
- \o Mapped to QString
+ \li TEXT
+ \li Character string of variable-length
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o TIMESTAMP
- \o 8 bytes, both date and time
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li 8 bytes, both date and time
+ \li Mapped to QDateTime
\row
- \o TIMESTAMP
- \o 8 bytes, both date and time, with time zone
- \o Mapped to QDateTime
+ \li TIMESTAMP
+ \li 8 bytes, both date and time, with time zone
+ \li Mapped to QDateTime
\row
- \o DATE
- \o 4 bytes, dates only
- \o Mapped to QDate
+ \li DATE
+ \li 4 bytes, dates only
+ \li Mapped to QDate
\row
- \o TIME
- \o 8 bytes, times of day only 00:00:00.00 - 23:59:59.99
- \o Mapped to QTime
+ \li TIME
+ \li 8 bytes, times of day only 00:00:00.00 - 23:59:59.99
+ \li Mapped to QTime
\row
- \o TIME
- \o 12 bytes times of day only, with time zone 00:00:00.00+12
- \o Mapped to QDateTime
+ \li TIME
+ \li 12 bytes times of day only, with time zone 00:00:00.00+12
+ \li Mapped to QDateTime
\endtable
\section2 QSQLITE SQLite version 3 Data Types
\table 90%
\header
- \o QSQLITE SQLite version 3 data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li QSQLITE SQLite version 3 data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o NULL
- \o NULL value.
- \o NULL
+ \li NULL
+ \li NULL value.
+ \li NULL
\row
- \o INTEGER
- \o Signed integer, stored in 8, 16, 24, 32, 48, or 64-bits
+ \li INTEGER
+ \li Signed integer, stored in 8, 16, 24, 32, 48, or 64-bits
depending on the magnitude of the value.
- \o typedef qint8/16/32/64
+ \li typedef qint8/16/32/64
\row
- \o REAL
- \o 64-bit floating point value.
- \o By default mapping to QString
+ \li REAL
+ \li 64-bit floating point value.
+ \li By default mapping to QString
\row
- \o TEXT
- \o Character string (UTF-8, UTF-16BE or UTF-16-LE).
- \o Mapped to QString
+ \li TEXT
+ \li Character string (UTF-8, UTF-16BE or UTF-16-LE).
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o BLOB
- \o The value is a BLOB of data, stored exactly as it was input.
- \o Mapped to QByteArray
+ \li BLOB
+ \li The value is a BLOB of data, stored exactly as it was input.
+ \li Mapped to QByteArray
\endtable
\section2 Sybase Adaptive Server Data Types
\table 90%
\header
- \o Sybase Adaptive Server data type
- \o SQL type description
- \o Recommended input (C++ or Qt data type)
+ \li Sybase Adaptive Server data type
+ \li SQL type description
+ \li Recommended input (C++ or Qt data type)
\row
- \o BINARY
- \o Describes a fixed-length binary value up to 255 bytes in size.
- \o Mapped to QByteArray
+ \li BINARY
+ \li Describes a fixed-length binary value up to 255 bytes in size.
+ \li Mapped to QByteArray
\row
- \o CHAR
- \o Character String
- \o Mapped to QString
+ \li CHAR
+ \li Character String
+ \li Mapped to QString
\row
- \o DATETIME
- \o Date and time. Range: 1753-01-01 00:00:00 through 9999-12-31 23:59:59.
- \o Mapped to QDateTime
+ \li DATETIME
+ \li Date and time. Range: 1753-01-01 00:00:00 through 9999-12-31 23:59:59.
+ \li Mapped to QDateTime
\row
- \o NCHAR
- \o Character String of fixed length
- \o Mapped to QString
+ \li NCHAR
+ \li Character String of fixed length
+ \li Mapped to QString
\row
- \o NVARACHAR
- \o Character String of variable length
- \o Mapped to QString
+ \li NVARACHAR
+ \li Character String of variable length
+ \li Mapped to QString
\row
- \o VARCHAR
- \o Character String of fixed length
- \o Mapped to QString
+ \li VARCHAR
+ \li Character String of fixed length
+ \li Mapped to QString
\row
- \o CLOB
- \o Character large string object
- \o Mapped to QString
+ \li CLOB
+ \li Character large string object
+ \li Mapped to QString
\row
- \o TIMESTAMP
- \o A unique number within a database
- \o Mapped to QString
+ \li TIMESTAMP
+ \li A unique number within a database
+ \li Mapped to QString
\row
- \o SMALLDATETIME
- \o Date and time. Range: 1900-01-01 00:00 through 2079-12-31 23:59
- \o Mapped to QDateTime
+ \li SMALLDATETIME
+ \li Date and time. Range: 1900-01-01 00:00 through 2079-12-31 23:59
+ \li Mapped to QDateTime
\row
- \o UNICHAR
- \o Character String of fixed length.(Unicode)
- \o Mapped to QString
+ \li UNICHAR
+ \li Character String of fixed length.(Unicode)
+ \li Mapped to QString
\row
- \o UNIVARCHAR
- \o Character String of variable length.(Unicode)
- \o Mapped to QString
+ \li UNIVARCHAR
+ \li Character String of variable length.(Unicode)
+ \li Mapped to QString
\row
- \o VARBINARY
- \o Describes a variable-length binary value up to 255 bytes in size
- \o Mapped to QByteArray
+ \li VARBINARY
+ \li Describes a variable-length binary value up to 255 bytes in size
+ \li Mapped to QByteArray
\endtable
\section2 SQLite Version 2
diff --git a/doc/src/sql/sql-programming/sql-driver.qdoc b/doc/src/sql/sql-programming/sql-driver.qdoc
index 667b9eba54e..eec61abd15e 100644
--- a/doc/src/sql/sql-programming/sql-driver.qdoc
+++ b/doc/src/sql/sql-programming/sql-driver.qdoc
@@ -49,18 +49,18 @@
are provided with Open Source Versions of Qt.
\table
- \header \o Driver name \o DBMS
- \row \o \link #QDB2 QDB2\endlink \o IBM DB2 (version 7.1 and above)
- \row \o \link #QIBASE QIBASE\endlink \o Borland InterBase
- \row \o \link #QMYSQL QMYSQL\endlink \o MySQL
- \row \o \link #QOCI QOCI\endlink \o Oracle Call Interface Driver
- \row \o \link #QODBC QODBC\endlink
- \o Open Database Connectivity (ODBC) - Microsoft SQL Server and other
+ \header \li Driver name \li DBMS
+ \row \li \link #QDB2 QDB2\endlink \li IBM DB2 (version 7.1 and above)
+ \row \li \link #QIBASE QIBASE\endlink \li Borland InterBase
+ \row \li \link #QMYSQL QMYSQL\endlink \li MySQL
+ \row \li \link #QOCI QOCI\endlink \li Oracle Call Interface Driver
+ \row \li \link #QODBC QODBC\endlink
+ \li Open Database Connectivity (ODBC) - Microsoft SQL Server and other
ODBC-compliant databases
- \row \o \link #QPSQL QPSQL\endlink \o PostgreSQL (versions 7.3 and above)
- \row \o \link #QSQLITE2 QSQLITE2\endlink \o SQLite version 2
- \row \o \link #QSQLITE QSQLITE\endlink \o SQLite version 3
- \row \o \link #QTDS QTDS\endlink \o Sybase Adaptive Server \note obsolete from Qt 4.7
+ \row \li \link #QPSQL QPSQL\endlink \li PostgreSQL (versions 7.3 and above)
+ \row \li \link #QSQLITE2 QSQLITE2\endlink \li SQLite version 2
+ \row \li \link #QSQLITE QSQLITE\endlink \li SQLite version 3
+ \row \li \link #QTDS QTDS\endlink \li Sybase Adaptive Server \note obsolete from Qt 4.7
\endtable
SQLite is the in-process database system with the best test coverage
@@ -69,7 +69,7 @@
Linux. The completeness of the support for other systems depends on the
availability and quality of client libraries.
- \bold{Note:} To build a driver plugin you need to have the appropriate
+ \b{Note:} To build a driver plugin you need to have the appropriate
client library for your Database Management System (DBMS). This provides
access to the API exposed by the DBMS, and is typically shipped with it.
Most installation programs also allow you to install "development
@@ -123,7 +123,7 @@
\snippet doc/src/snippets/code/doc_src_sql-driver.cpp 2
- \bold{Note:} \c{@outval1} and \c{@outval2} are variables local to the current
+ \b{Note:} \c{@outval1} and \c{@outval2} are variables local to the current
connection and will not be affected by queries sent from another host
or connection.
@@ -185,59 +185,59 @@
\list
- \o Download the following components:
+ \li Download the following components:
\list
- \o \c{MinGW-5.1.6.exe}
- \o \c{mingw-utils-0.3.tar.gz}
- \o Qt sources, e.g. \c{qt-everywhere-opensource-src-4.6.2.zip}
- \o \c{mysql-5.1.35-win32.msi}
+ \li \c{MinGW-5.1.6.exe}
+ \li \c{mingw-utils-0.3.tar.gz}
+ \li Qt sources, e.g. \c{qt-everywhere-opensource-src-4.6.2.zip}
+ \li \c{mysql-5.1.35-win32.msi}
\endlist
- \o Install \c{MinGW-5.1.6.exe} in, e.g. \c{C:\MinGW}.
+ \li Install \c{MinGW-5.1.6.exe} in, e.g. \c{C:\MinGW}.
- \o Extract \c{mingw-utils-0.3.tar.gz} into, e.g. \c{C:\MinGW}.
+ \li Extract \c{mingw-utils-0.3.tar.gz} into, e.g. \c{C:\MinGW}.
- \o Add the path for \c{MinGW-5.1.6.exe} to your \c{PATH} variable,
+ \li Add the path for \c{MinGW-5.1.6.exe} to your \c{PATH} variable,
e.g. \c{C:\MinGW\bin;}
- \o Extract the Qt sources, (\c{qt-everywhere-opensource-src-4.6.2.zip}),
+ \li Extract the Qt sources, (\c{qt-everywhere-opensource-src-4.6.2.zip}),
into, e.g. \c{C:\Qt}.
- \o Add the path for the eventual Qt binary to your \c{PATH} variable,
+ \li Add the path for the eventual Qt binary to your \c{PATH} variable,
e.g. \c{C:\Qt\4.6.2\bin;}.
- \o Install MySQL (\c{mysql-5.1.35-win32.msi}), customizing the
+ \li Install MySQL (\c{mysql-5.1.35-win32.msi}), customizing the
components. Select only the headers and libraries. Install in,
e.g. \c{C:\MySQL\MySQL51}.
- \o Open the DOS prompt, go to \c{C:\MySQL\MySQL51\lib\opt}, and run
+ \li Open the DOS prompt, go to \c{C:\MySQL\MySQL51\lib\opt}, and run
the following commands:
\list
- \o \c{reimp -d libmysql.lib}
- \o \c{dlltool -k -d libmysql.def -l libmysql.a}
+ \li \c{reimp -d libmysql.lib}
+ \li \c{dlltool -k -d libmysql.def -l libmysql.a}
\endlist
- \o Open the DOS prompt, go to \c{C:\Qt\4.6.2} and run the following commands:
+ \li Open the DOS prompt, go to \c{C:\Qt\4.6.2} and run the following commands:
\list
- \o \c{configure.exe -debug-and-release -platform win32-g++ -qt-sql-mysql
+ \li \c{configure.exe -debug-and-release -platform win32-g++ -qt-sql-mysql
-l mysql -I C:\MySQL\MySQL51\include -L C:\MySQL\MySQL51\lib\opt}
- \o \c{mingw32-make sub-src}
+ \li \c{mingw32-make sub-src}
\endlist
This step takes a long time.
- \o Open the DOS prompt, go to
+ \li Open the DOS prompt, go to
\c{C:\Qt\4.6.2\src\plugins\sqldrivers\mysql} and run the
following command:
\list
- \o \c{qmake "INCLUDEPATH+=C:\MySQL\MySQL51\include" "LIBS+=-L. mysql" mysql.pro}
+ \li \c{qmake "INCLUDEPATH+=C:\MySQL\MySQL51\include" "LIBS+=-L. mysql" mysql.pro}
\endlist
- \o Now the following libraries are ready in \c{C:\Qt\4.6.2\plugins\sqldrivers}.
+ \li Now the following libraries are ready in \c{C:\Qt\4.6.2\plugins\sqldrivers}.
\list
- \o \c{libqsqlmysql4.a}
- \o \c{libqsqlmysqld4.a}
- \o \c{qsqlmysql4.dll}
- \o \c{qsqlmysqld4.dll}
+ \li \c{libqsqlmysql4.a}
+ \li \c{libqsqlmysqld4.a}
+ \li \c{qsqlmysql4.dll}
+ \li \c{qsqlmysqld4.dll}
\endlist
To use the SDK and QtCreator directly, copy these libraries to
your \c{C:\Qt\...\qt\plugins\sqldrivers\}, and copy
@@ -287,8 +287,8 @@
Oracle library files required to build the driver:
\list
- \i \c libclntsh.so (all versions)
- \i \c libwtc9.so (only Oracle 9)
+ \li \c libclntsh.so (all versions)
+ \li \c libwtc9.so (only Oracle 9)
\endlist
Tell \c qmake where to find the Oracle header files and shared
@@ -301,7 +301,7 @@
Instant Client Package SDK (you need to adjust the version number accordingly):
\snippet doc/src/snippets/code/doc_src_sql-driver.qdoc 7
- \bold{Note:} If you are using the Oracle Instant Client package,
+ \b{Note:} If you are using the Oracle Instant Client package,
you will need to set LD_LIBRARY_PATH when building the OCI SQL plugin
and when running an application that uses the OCI SQL plugin. You can
avoid this requirement by setting and RPATH and listing all of the
@@ -331,7 +331,7 @@
\snippet doc/src/snippets/code/doc_src_sql-driver.qdoc 9
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QODBC
\section2 QODBC for Open Database Connectivity (ODBC)
@@ -345,7 +345,7 @@
driver manager that is installed on your system. The QODBC plugin
then allows you to use these data sources in your Qt applications.
- \bold{Note:} You should use native drivers in preference to the ODBC
+ \b{Note:} You should use native drivers in preference to the ODBC
driver where they are available. ODBC support can be used as a fallback
for compliant databases if no native drivers are available.
@@ -396,7 +396,7 @@
\snippet doc/src/snippets/code/doc_src_sql-driver.cpp 10
- \bold{Note:} The value returned by the stored procedure's return statement
+ \b{Note:} The value returned by the stored procedure's return statement
is discarded.
\section3 ODBC Unicode Support
@@ -435,7 +435,7 @@
If you are not using a Microsoft compiler, replace \c nmake with \c
make in the line above.
- \bold{Note:} This database plugin is not officially supported for Windows CE.
+ \b{Note:} This database plugin is not officially supported for Windows CE.
\target QPSQL
\section2 QPSQL for PostgreSQL (Version 7.3 and Above)
@@ -496,7 +496,7 @@
Users of MinGW may wish to consult the following online document:
\l{PostgreSQL MinGW/Native Windows}.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QTDS
\section2 QTDS for Sybase Adaptive Server
@@ -515,11 +515,11 @@
Under Unix, two libraries are available which support the TDS protocol:
\list
- \i FreeTDS, a free implementation of the TDS protocol
+ \li FreeTDS, a free implementation of the TDS protocol
(\l{http://www.freetds.org}). Note that FreeTDS is not yet stable,
so some functionality may not work as expected.
- \i Sybase Open Client, available from \l{http://www.sybase.com}.
+ \li Sybase Open Client, available from \l{http://www.sybase.com}.
Note for Linux users: Get the Open Client RPM from
\l{http://linux.sybase.com}.
\endlist
@@ -545,7 +545,7 @@
are not using a Microsoft compiler, replace \c nmake with \c make in
the line above.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QDB2
\section2 QDB2 for IBM DB2 (Version 7.1 and Above)
@@ -582,7 +582,7 @@
If you are not using a Microsoft compiler, replace \c nmake
with \c make in the line above.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target QSQLITE2
\section2 QSQLITE2 for SQLite Version 2
@@ -745,7 +745,7 @@
Note that \c{C:\interbase\bin} must be in the \c PATH.
- \bold{Note:} This database plugin is not supported for Windows CE.
+ \b{Note:} This database plugin is not supported for Windows CE.
\target troubleshooting
\section1 Troubleshooting
@@ -763,16 +763,16 @@
make sure that the following requirements are met:
\list
- \i Ensure that you are using a shared Qt library; you cannot use the
+ \li Ensure that you are using a shared Qt library; you cannot use the
plugins with a static build.
- \i Ensure that the plugin is in the correct directory. You can use
+ \li Ensure that the plugin is in the correct directory. You can use
QApplication::libraryPaths() to determine where Qt looks for plugins.
- \i Ensure that the client libraries of the DBMS are available on the
+ \li Ensure that the client libraries of the DBMS are available on the
system. On Unix, run the command \c{ldd} and pass the name of the
plugin as parameter, for example \c{ldd libqsqlmysql.so}. You will
get a warning if any of the client libraries couldn't be found.
On Windows, you can use Visual Studio's dependency walker.
- \i Compile Qt with \c{QT_DEBUG_COMPONENT} defined to get very verbose
+ \li Compile Qt with \c{QT_DEBUG_COMPONENT} defined to get very verbose
debug output when loading plugins.
\endlist
diff --git a/doc/src/sql/sql-programming/sql-programming.qdoc b/doc/src/sql/sql-programming/sql-programming.qdoc
index 787b48718dd..6ebb40b7553 100644
--- a/doc/src/sql/sql-programming/sql-programming.qdoc
+++ b/doc/src/sql/sql-programming/sql-programming.qdoc
@@ -52,18 +52,18 @@
\section1 Topics:
\list
- \o \l{Database Classes}
- \o \l{Connecting to Databases}
+ \li \l{Database Classes}
+ \li \l{Connecting to Databases}
\list
- \o \l{SQL Database Drivers}
+ \li \l{SQL Database Drivers}
\endlist
- \o \l{Executing SQL Statements}
+ \li \l{Executing SQL Statements}
\list
- \o \l{Data Types for Qt-supported Database Systems}
+ \li \l{Data Types for Qt-supported Database Systems}
\endlist
- \o \l{Using the SQL Model Classes}
- \o \l{Presenting Data in a Table View}
- \o \l{Creating Data-Aware Forms}
+ \li \l{Using the SQL Model Classes}
+ \li \l{Presenting Data in a Table View}
+ \li \l{Creating Data-Aware Forms}
\endlist
\section1 Database Classes
@@ -338,12 +338,12 @@
QSqlTableModel, and QSqlRelationalTableModel.
\table
- \row \o QSqlQueryModel
- \o A read-only model based on an arbitrary SQL query.
- \row \o QSqlTableModel
- \o A read-write model that works on a single table.
- \row \o QSqlRelationalTableModel
- \o A QSqlTableModel subclass with foreign key support.
+ \row \li QSqlQueryModel
+ \li A read-only model based on an arbitrary SQL query.
+ \row \li QSqlTableModel
+ \li A read-write model that works on a single table.
+ \row \li QSqlRelationalTableModel
+ \li A QSqlTableModel subclass with foreign key support.
\endtable
These classes derive from QAbstractTableModel (which in turn
@@ -435,8 +435,8 @@
pitfalls, though:
\list
- \o Without any caching, performance may drop significantly.
- \o If you modify a primary key, the record might slip through
+ \li Without any caching, performance may drop significantly.
+ \li If you modify a primary key, the record might slip through
your fingers while you are trying to populate it.
\endlist
@@ -450,8 +450,8 @@
that \c authorid is a foreign key.
\table
- \row \o \inlineimage noforeignkeys.png
- \o \inlineimage foreignkeys.png
+ \row \li \inlineimage noforeignkeys.png
+ \li \inlineimage foreignkeys.png
\endtable
The screenshot on the left shows a plain QSqlTableModel in a
diff --git a/doc/src/widgets/addressbook-fr.qdoc b/doc/src/widgets/addressbook-fr.qdoc
index 4df19d015fe..edd53239d07 100644
--- a/doc/src/widgets/addressbook-fr.qdoc
+++ b/doc/src/widgets/addressbook-fr.qdoc
@@ -40,10 +40,10 @@
par Qt, tel que:
\list
- \o Les Widgets et leur mise en page à l'aide des layouts
- \o Les signaux et slots
- \o Les structures de données de collections
- \o Les entrées/sorties
+ \li Les Widgets et leur mise en page à l'aide des layouts
+ \li Les signaux et slots
+ \li Les structures de données de collections
+ \li Les entrées/sorties
\endlist
Si c'est votre premier contact avec Qt, lisez \l{How to Learn Qt}{Comment apprendre Qt}
@@ -54,13 +54,13 @@
Les chapitres du tutoriel:
\list 1
- \o \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur}
- \o \l{tutorials/addressbook-fr/part2}{Ajouter des adresses}
- \o \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments}
- \o \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses}
- \o \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche}
- \o \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement}
- \o \l{tutorials/addressbook-fr/part7}{Fonctionnalités avancées}
+ \li \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur}
+ \li \l{tutorials/addressbook-fr/part2}{Ajouter des adresses}
+ \li \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments}
+ \li \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses}
+ \li \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche}
+ \li \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement}
+ \li \l{tutorials/addressbook-fr/part7}{Fonctionnalités avancées}
\endlist
La petite application que nous développerons ici ne possède pas tous les éléments
@@ -99,10 +99,10 @@
Trois fichiers sont nécessaires à l'implémentation de ce carnet d'adresses:
\list
- \o \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook,
- \o \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe
+ \li \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook,
+ \li \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe
\c AddressBook
- \o \c{main.cpp} - le fichier qui contient la méthode \c main() , et
+ \li \c{main.cpp} - le fichier qui contient la méthode \c main() , et
une instance de la classe \c AddressBook.
\endlist
@@ -116,13 +116,13 @@
ou modifier le comportement d'un widget présente les avantages suivants:
\list
- \o La possibilité d'implémenter des méthodes virtuelles et des méthodes
+ \li La possibilité d'implémenter des méthodes virtuelles et des méthodes
virtuelles pures pour obtenir exactement ce que l'on souhaite, avec la possibilité
d'utiliser l'implémentation de la classe mère si besoin est.
- \o Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe,
+ \li Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe,
afin que les autres parties de l'application n'aient pas à se soucier de chacun des
widgets qui forment l'interface utilisateur.
- \o La classe fille peut être utilisée pour créer de nombreux widgets personnalisés
+ \li La classe fille peut être utilisée pour créer de nombreux widgets personnalisés
dans une même application ou bibliothèque, et le code de la classe fille peut être
réutilisé dans d'autres projets
\endlist
@@ -343,7 +343,7 @@
La méthode \c submitContact() peut être divisée en trois parties:
\list 1
- \o Nous extrayons les détails du contact depuis \c nameLine et \c addressText
+ \li Nous extrayons les détails du contact depuis \c nameLine et \c addressText
et les stockons dans des objets QString. Nous les validons pour s'assurer
que l'utilisateur n'a pas cliqué sur "Add" avec des champs de saisie
vides; sinon un message est affiché avec QMessageBox pour rappeller à
@@ -351,7 +351,7 @@
\snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1
- \o Ensuite, nous vérifions si le contact existe déjà. Si aucun contacts
+ \li Ensuite, nous vérifions si le contact existe déjà. Si aucun contacts
existant n'entre en conflit avec le nouveau, nous l'ajoutons à
\c contacts et nous affichons un QMessageBox pour informer l'utilisateur
que le contact a été ajouté.
@@ -363,7 +363,7 @@
Notre objet \c contacts est basé sur des paires clé-valeur formés par
le nom et l'adresse, nous voulons nous assurer que la \e clé est unique.
- \o Une fois que les deux vérifications précédentes ont été traitées,
+ \li Une fois que les deux vérifications précédentes ont été traitées,
nous restaurons les boutons à leur état normal à l'aide du code
suivant:
@@ -482,8 +482,8 @@
sur \c contact dans la méthode \c next(), et ensuite:
\list
- \o Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons
- \o Si l'itérateur est à la fin de \c contacts, nous changeons sa position
+ \li Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons
+ \li Si l'itérateur est à la fin de \c contacts, nous changeons sa position
jusqu'au début de \c contacts. Cela donne l'illusion que notre QMap
fonctionne comme une liste circulaire.
\endlist
@@ -497,11 +497,11 @@
itérateur sur \c contacts et ensuite:
\list
- \o Si l'itérateur est à la fin de \c contacts, on réinitialise
+ \li Si l'itérateur est à la fin de \c contacts, on réinitialise
l'affichage et on retourne.
- \o Si l'itérateur est au début de \c contacts, on change sa
+ \li Si l'itérateur est au début de \c contacts, on change sa
position jusqu'à la fin
- \o Ensuite, on décrémente l'itérateur
+ \li Ensuite, on décrémente l'itérateur
\endlist
\snippet tutorials/addressbook/part3/addressbook.cpp previous() function
@@ -538,9 +538,9 @@
Dans ce chapitre, on définit l'énumération \c Mode avec trois valeurs possibles.
\list
- \o \c{NavigationMode},
- \o \c{AddingMode}, et
- \o \c{EditingMode}.
+ \li \c{NavigationMode},
+ \li \c{AddingMode}, et
+ \li \c{EditingMode}.
\endlist
\section1 Définition de la classe AddressBook
diff --git a/doc/src/widgets/addressbook.qdoc b/doc/src/widgets/addressbook.qdoc
index 96c96df177c..27bdb0fac4e 100644
--- a/doc/src/widgets/addressbook.qdoc
+++ b/doc/src/widgets/addressbook.qdoc
@@ -47,10 +47,10 @@
components of Qt, including:
\list
- \o Widgets and layout managers
- \o Container classes
- \o Signals and slots
- \o Input and output devices
+ \li Widgets and layout managers
+ \li Container classes
+ \li Signals and slots
+ \li Input and output devices
\endlist
If you are new to Qt, we recommend reading \l{How to Learn Qt} first.
@@ -58,13 +58,13 @@
Tutorial contents:
\list 1
- \o \l{tutorials/addressbook/part1}{Designing the User Interface}
- \o \l{tutorials/addressbook/part2}{Adding Addresses}
- \o \l{tutorials/addressbook/part3}{Navigating between Entries}
- \o \l{tutorials/addressbook/part4}{Editing and Removing Addresses}
- \o \l{tutorials/addressbook/part5}{Adding a Find Function}
- \o \l{tutorials/addressbook/part6}{Loading and Saving}
- \o \l{tutorials/addressbook/part7}{Additional Features}
+ \li \l{tutorials/addressbook/part1}{Designing the User Interface}
+ \li \l{tutorials/addressbook/part2}{Adding Addresses}
+ \li \l{tutorials/addressbook/part3}{Navigating between Entries}
+ \li \l{tutorials/addressbook/part4}{Editing and Removing Addresses}
+ \li \l{tutorials/addressbook/part5}{Adding a Find Function}
+ \li \l{tutorials/addressbook/part6}{Loading and Saving}
+ \li \l{tutorials/addressbook/part7}{Additional Features}
\endlist
The tutorial source code is located in \c{examples/tutorials/addressbook}.
@@ -105,11 +105,11 @@
There are three files used to implement this address book:
\list
- \o \c{addressbook.h} - the definition file for the \c AddressBook
+ \li \c{addressbook.h} - the definition file for the \c AddressBook
class,
- \o \c{addressbook.cpp} - the implementation file for the
+ \li \c{addressbook.cpp} - the implementation file for the
\c AddressBook class, and
- \o \c{main.cpp} - the file containing a \c main() function, with
+ \li \c{main.cpp} - the file containing a \c main() function, with
an instance of \c AddressBook.
\endlist
@@ -121,13 +121,13 @@
extend or change the behavior of a widget has the following advantages:
\list
- \o We can write implementations of virtual or pure virtual functions to
+ \li We can write implementations of virtual or pure virtual functions to
obtain exactly what we need, falling back on the base class's implementation
when necessary.
- \o It allows us to encapsulate parts of the user interface within a class,
+ \li It allows us to encapsulate parts of the user interface within a class,
so that the other parts of the application don't need to know about the
individual widgets in the user interface.
- \o The subclass can be used to create multiple custom widgets in the same
+ \li The subclass can be used to create multiple custom widgets in the same
application or library, and the code for the subclass can be reused in other
projects.
\endlist
@@ -340,14 +340,14 @@
The \c submitContact() function can be divided into three parts:
\list 1
- \o We extract the contact's details from \c nameLine and \c addressText
+ \li We extract the contact's details from \c nameLine and \c addressText
and store them in QString objects. We also validate to make sure that the
user did not click \gui Submit with empty input fields; otherwise, a
QMessageBox is displayed to remind the user for a name and address.
\snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1
- \o We then proceed to check if the contact already exists. If it does not
+ \li We then proceed to check if the contact already exists. If it does not
exist, we add the contact to \c contacts and we display a QMessageBox to
inform the user that the contact has been added.
@@ -358,7 +358,7 @@
Our \c contacts object is based on key-value pairs of name and address,
hence, we want to ensure that \e key is unique.
- \o Once we have handled both cases mentioned above, we restore the push
+ \li Once we have handled both cases mentioned above, we restore the push
buttons to their normal state with the following code:
\snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3
@@ -471,9 +471,9 @@
for \c contacts and then:
\list
- \o If the iterator is not at the end of \c contacts, we increment it
+ \li If the iterator is not at the end of \c contacts, we increment it
by one.
- \o If the iterator is at the end of \c contacts, we move it to the
+ \li If the iterator is at the end of \c contacts, we move it to the
beginning of \c contacts. This gives us the illusion that our QMap is
working like a circularly-linked list.
\endlist
@@ -487,11 +487,11 @@
\c contacts and then:
\list
- \o If the iterator is at the end of \c contacts, we clear the
+ \li If the iterator is at the end of \c contacts, we clear the
display and return.
- \o If the iterator is at the beginning of \c contacts, we move it to
+ \li If the iterator is at the beginning of \c contacts, we move it to
the end.
- \o We then decrement the iterator by one.
+ \li We then decrement the iterator by one.
\endlist
\snippet tutorials/addressbook/part3/addressbook.cpp previous() function
@@ -524,9 +524,9 @@
Here we define the \c Mode enum with three different values:
\list
- \o \c{NavigationMode},
- \o \c{AddingMode}, and
- \o \c{EditingMode}.
+ \li \c{NavigationMode},
+ \li \c{AddingMode}, and
+ \li \c{EditingMode}.
\endlist
\section1 Defining the AddressBook Class
diff --git a/doc/src/widgets/modelview.qdoc b/doc/src/widgets/modelview.qdoc
index 536b5211004..fdd25def31d 100644
--- a/doc/src/widgets/modelview.qdoc
+++ b/doc/src/widgets/modelview.qdoc
@@ -55,16 +55,16 @@
such as:
\list
- \o The difference between standard and model/view widgets
- \o Adapters between forms and models
- \o Developing a simple model/view application
- \o Predefined models
- \o Intermediate topics such as:
+ \li The difference between standard and model/view widgets
+ \li Adapters between forms and models
+ \li Developing a simple model/view application
+ \li Predefined models
+ \li Intermediate topics such as:
\list
- \o Tree views
- \o Selection
- \o Delegates
- \o Debugging with model test
+ \li Tree views
+ \li Selection
+ \li Delegates
+ \li Debugging with model test
\endlist
\endlist
@@ -91,11 +91,11 @@
\table
\row
- \o Standard widgets use data that is part of the widget.
- \o \image standardwidget.png
+ \li Standard widgets use data that is part of the widget.
+ \li \image standardwidget.png
\row
- \o View classes operate on external data (the model)
- \o \image modelview.png
+ \li View classes operate on external data (the model)
+ \li \image modelview.png
\endtable
\section2 1.1 Standard Widgets
@@ -133,30 +133,30 @@
\table
\header
- \o Widget
- \o Standard Widget\br
+ \li Widget
+ \li Standard Widget\br
(an item based convenience class)
- \o Model/View View Class\br
+ \li Model/View View Class\br
(for use with external data)
\row
- \o \inlineimage listview.png
- \o \l QListWidget
- \o \l QListView
+ \li \inlineimage listview.png
+ \li \l QListWidget
+ \li \l QListView
\row
- \o \inlineimage tableview.png
- \o \l QTableWidget
- \o \l QTableView
+ \li \inlineimage tableview.png
+ \li \l QTableWidget
+ \li \l QTableView
\row
- \o \inlineimage treeview.png
- \o \l QTreeWidget
- \o \l QTreeView
+ \li \inlineimage treeview.png
+ \li \l QTreeWidget
+ \li \l QTreeView
\row
- \o \inlineimage columnview.png
- \o
- \o \l QColumnView shows a tree as a hierarchy of lists
+ \li \inlineimage columnview.png
+ \li
+ \li \l QColumnView shows a tree as a hierarchy of lists
\row
- \o \inlineimage modelview-combobox.png
- \o {2, 1} \l QComboBox can work as both a view class and also
+ \li \inlineimage modelview-combobox.png
+ \li {2, 1} \l QComboBox can work as both a view class and also
as a traditional widget
\endtable
@@ -212,8 +212,8 @@
things:
\list
- \o How many rows and columns should be displayed.
- \o What content should be printed into each cell.
+ \li How many rows and columns should be displayed.
+ \li What content should be printed into each cell.
\endlist
The model needs some code to respond to this.
@@ -271,33 +271,33 @@
\table
\header
- \o \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
- \o Meaning
- \o Type
+ \li \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
+ \li Meaning
+ \li Type
\row
- \o \l{Qt::ItemDataRole}{}Qt::DisplayRole
- \o text
- \o QString
+ \li \l{Qt::ItemDataRole}{}Qt::DisplayRole
+ \li text
+ \li QString
\row
- \o \l{Qt::ItemDataRole}{Qt::FontRole}
- \o font
- \o QFont
+ \li \l{Qt::ItemDataRole}{Qt::FontRole}
+ \li font
+ \li QFont
\row
- \o \l{Qt::ItemDataRole}{BackgroundRole}
- \o brush for the background of the cell
- \o QBrush
+ \li \l{Qt::ItemDataRole}{BackgroundRole}
+ \li brush for the background of the cell
+ \li QBrush
\row
- \o \l{Qt::ItemDataRole}{Qt::TextAlignmentRole}
- \o text alignment
- \o \l{Qt::AlignmentFlag}{enum Qt::AlignmentFlag}
+ \li \l{Qt::ItemDataRole}{Qt::TextAlignmentRole}
+ \li text alignment
+ \li \l{Qt::AlignmentFlag}{enum Qt::AlignmentFlag}
\row
- \o {1, 3} \l{Qt::ItemDataRole}{Qt::CheckStateRole}
- \o {1, 3} suppresses checkboxes with \l{QVariant}{QVariant()},
+ \li {1, 3} \l{Qt::ItemDataRole}{Qt::CheckStateRole}
+ \li {1, 3} suppresses checkboxes with \l{QVariant}{QVariant()},
sets checkboxes with \l{Qt::CheckState}{Qt::Checked}
or \l{Qt::CheckState}{Qt::Unchecked}
- \o {1, 3} \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
+ \li {1, 3} \l{Qt::ItemDataRole}{enum Qt::ItemDataRole}
\endtable
Refer to the Qt namespace documentation to learn more about the
@@ -490,27 +490,27 @@
\table
\row
- \o QStringListModel
- \o Stores a list of strings
+ \li QStringListModel
+ \li Stores a list of strings
\row
- \o QStandardItemModel
- \o Stores arbitrary hierarchical items
+ \li QStandardItemModel
+ \li Stores arbitrary hierarchical items
\row
- \o QFileSystemModel\br
+ \li QFileSystemModel\br
QDirModel
- \o Encapsulate the local file system
+ \li Encapsulate the local file system
\row
- \o QSqlQueryModel
- \o Encapsulate an SQL result set
+ \li QSqlQueryModel
+ \li Encapsulate an SQL result set
\row
- \o QSqlTableModel
- \o Encapsulates an SQL table
+ \li QSqlTableModel
+ \li Encapsulates an SQL table
\row
- \o QSqlRelationalTableModel
- \o Encapsulates an SQL table with foreign keys
+ \li QSqlRelationalTableModel
+ \li Encapsulates an SQL table with foreign keys
\row
- \o QSortFilterProxyModel
- \o Sorts and/or filters another model
+ \li QSortFilterProxyModel
+ \li Sorts and/or filters another model
\endtable
@@ -562,11 +562,11 @@
Other references to delegates in Qt Documentation:
\list
- \o \l{Spin Box Delegate Example}
- \o \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference}
- \o \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference}
- \o \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference}
- \o \l{QItemDelegate}{QItemDelegate Class Reference}
+ \li \l{Spin Box Delegate Example}
+ \li \l{QAbstractItemDelegate}{QAbstractItemDelegate Class Reference}
+ \li \l{QSqlRelationalDelegate}{QSqlRelationalDelegate Class Reference}
+ \li \l{QStyledItemDelegate}{QStyledItemDelegate Class Reference}
+ \li \l{QItemDelegate}{QItemDelegate Class Reference}
\endlist
@@ -599,16 +599,16 @@
Qt but also in several good books.
\list 1
- \o \bold{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield,
+ \li \b{C++ GUI Programming with Qt 4} / Jasmin Blanchette, Mark Summerfield,
\e{Prentice Hall, 2nd edition}, ISBN 0-13-235416-0. Also available in
- German: \bold{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung},
+ German: \b{C++ GUI Programmierung mit Qt 4: Die offizielle Einführung},
\e{Addison-Wesley}, ISBN 3-827327-29-6
- \o \bold{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin,
+ \li \b{The Book of Qt4, The Art of Building Qt Applications} / Daniel Molkentin,
\e{Open Source Press}, ISBN 1-59327-147-6.
- Translated from \bold{Qt 4, Einführung in die Applikationsentwicklung},
+ Translated from \b{Qt 4, Einführung in die Applikationsentwicklung},
\e{Open Source Press}, ISBN 3-937514-12-0.
- \o \bold{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8.
- \o \bold{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6.
+ \li \b{Foundations of Qt Development} / Johan Thelin, \e{Apress}, ISBN 1-59059-831-8.
+ \li \b{Advanced Qt Programming} / Mark Summerfield, \e{Prentice Hall}, ISBN 0-321-63590-6.
This book covers Model/View programming on more than 150 pages.
\endlist
@@ -621,157 +621,157 @@
\table
\header
- \o Example name
- \o View class used
- \o Model used
- \o Aspects covered
- \o
+ \li Example name
+ \li View class used
+ \li Model used
+ \li Aspects covered
+ \li
\row
- \o Team Leaders
- \o QListview
- \o QStringListModel
- \o
- \o Book 1, Chapter 10, Figure 10.6
+ \li Team Leaders
+ \li QListview
+ \li QStringListModel
+ \li
+ \li Book 1, Chapter 10, Figure 10.6
\row
- \o Directory Viewer
- \o QTreeView
- \o QDirModel
- \o
- \o Book 1, Chapter 10, Figure 10.7
+ \li Directory Viewer
+ \li QTreeView
+ \li QDirModel
+ \li
+ \li Book 1, Chapter 10, Figure 10.7
\row
- \o Color Names
- \o QListView
- \o QSortFilterProxyModel
+ \li Color Names
+ \li QListView
+ \li QSortFilterProxyModel
applied to QStringListModel
- \o
- \o Book 1, Chapter 10, Figure 10.8
+ \li
+ \li Book 1, Chapter 10, Figure 10.8
\row
- \o Currencies
- \o QTableView
- \o custom model based on
+ \li Currencies
+ \li QTableView
+ \li custom model based on
QAbstractTableModel
- \o Read only
- \o Book 1, Chapter 10, Figure 10.10
+ \li Read only
+ \li Book 1, Chapter 10, Figure 10.10
\row
- \o Cities
- \o QTableView
- \o Custom model based on
+ \li Cities
+ \li QTableView
+ \li Custom model based on
QAbstractTableModel
- \o Read / write
- \o Book 1, Chapter 10, Figure 10.12
+ \li Read / write
+ \li Book 1, Chapter 10, Figure 10.12
\row
- \o Boolean Parser
- \o QTreeView
- \o Custom model based on
+ \li Boolean Parser
+ \li QTreeView
+ \li Custom model based on
QAbstractItemModel
- \o Read only
- \o Book 1, Chapter 10, Figure 10.14
+ \li Read only
+ \li Book 1, Chapter 10, Figure 10.14
\row
- \o Track Editor
- \o {2, 1} QTableWidget
- \o Custom delegate providing a custom editor
- \o Book 1, Chapter 10, Figure 10.15
+ \li Track Editor
+ \li {2, 1} QTableWidget
+ \li Custom delegate providing a custom editor
+ \li Book 1, Chapter 10, Figure 10.15
\row
- \o Four directory views
- \o QListView
+ \li Four directory views
+ \li QListView
QTableView
QTreeView
- \o QDirModel
- \o Demonstrates the use of multiple views
- \o Book2, Chapter 8.2
+ \li QDirModel
+ \li Demonstrates the use of multiple views
+ \li Book2, Chapter 8.2
\row
- \o Address Book
- \o QListView
+ \li Address Book
+ \li QListView
QTableView
QTreeView
- \o Custom model based on
+ \li Custom model based on
QAbstractTableModel
- \o Read / write
- \o Book2, Chapter 8.4
+ \li Read / write
+ \li Book2, Chapter 8.4
\row
- \o Address Book with sorting
- \o
- \o QProxyModel
- \o Introducing sort and filter capabilities
- \o Book2, Chapter 8.5
+ \li Address Book with sorting
+ \li
+ \li QProxyModel
+ \li Introducing sort and filter capabilities
+ \li Book2, Chapter 8.5
\row
- \o Address Book
+ \li Address Book
with checkboxes
- \o
- \o
- \o Introducing checkboxes in model/view
- \o Book2, Chapter 8.6
+ \li
+ \li
+ \li Introducing checkboxes in model/view
+ \li Book2, Chapter 8.6
\row
- \o Address Book with transposed grid
- \o
- \o Custom proxy Model based on QAbstractProxyModel
- \o Introducing a custom model
- \o Book2, Chapter 8.7
+ \li Address Book with transposed grid
+ \li
+ \li Custom proxy Model based on QAbstractProxyModel
+ \li Introducing a custom model
+ \li Book2, Chapter 8.7
\row
- \o Address Book with drag and drop
- \o
- \o
- \o Introducing drag and drop support
- \o Book2, Chapter 8.8
+ \li Address Book with drag and drop
+ \li
+ \li
+ \li Introducing drag and drop support
+ \li Book2, Chapter 8.8
\row
- \o Address Book with custom editor
- \o
- \o
- \o Introducing custom delegates
- \o Book2, Chapter 8.9
+ \li Address Book with custom editor
+ \li
+ \li
+ \li Introducing custom delegates
+ \li Book2, Chapter 8.9
\row
- \o Views
- \o QListView
+ \li Views
+ \li QListView
QTableView
QTreeView
- \o QStandardItemModel
- \o Read only
- \o Book 3, Chapter 5, figure 5-3
+ \li QStandardItemModel
+ \li Read only
+ \li Book 3, Chapter 5, figure 5-3
\row
- \o Bardelegate
- \o QTableView
- \o
- \o Custom delegate for presentation based on QAbstractItemDelegate
- \o Book 3, Chapter 5, figure 5-5
+ \li Bardelegate
+ \li QTableView
+ \li
+ \li Custom delegate for presentation based on QAbstractItemDelegate
+ \li Book 3, Chapter 5, figure 5-5
\row
- \o Editdelegate
- \o QTableView
- \o
- \o Custom delegate for editing based on QAbstractItemDelegate
- \o Book 3, Chapter 5, figure 5-6
+ \li Editdelegate
+ \li QTableView
+ \li
+ \li Custom delegate for editing based on QAbstractItemDelegate
+ \li Book 3, Chapter 5, figure 5-6
\row
- \o Singleitemview
- \o Custom view based on QAbstractItemView
- \o
- \o Custom view
- \o Book 3,
+ \li Singleitemview
+ \li Custom view based on QAbstractItemView
+ \li
+ \li Custom view
+ \li Book 3,
Chapter 5,
figure 5-7
\row
- \o listmodel
- \o QTableView
- \o Custom Model based on QAbstractTableModel
- \o Read only
- \o Book 3, Chapter 5, Figure 5-8
+ \li listmodel
+ \li QTableView
+ \li Custom Model based on QAbstractTableModel
+ \li Read only
+ \li Book 3, Chapter 5, Figure 5-8
\row
- \o treemodel
- \o QTreeView
- \o Custom Model based on QAbstractItemModel
- \o Read only
- \o Book 3, Chapter 5, Figure 5-10
+ \li treemodel
+ \li QTreeView
+ \li Custom Model based on QAbstractItemModel
+ \li Read only
+ \li Book 3, Chapter 5, Figure 5-10
\row
- \o edit integers
- \o QListView
- \o Custom Model based on QAbstractListModel
- \o Read / write
- \o Book 3, Chapter 5, Listing 5-37, Figure 5-11
+ \li edit integers
+ \li QListView
+ \li Custom Model based on QAbstractListModel
+ \li Read / write
+ \li Book 3, Chapter 5, Listing 5-37, Figure 5-11
\row
- \o sorting
- \o QTableView
- \o QSortFilterProxyModel applied to QStringListModel
- \o Demonstrates sorting
- \o Book 3, Chapter 5, Figure 5-12
+ \li sorting
+ \li QTableView
+ \li QSortFilterProxyModel applied to QStringListModel
+ \li Demonstrates sorting
+ \li Book 3, Chapter 5, Figure 5-12
\endtable
@@ -782,108 +782,108 @@
\table
\header
- \o Example name
- \o View class used
- \o Model used
- \o Aspects covered
+ \li Example name
+ \li View class used
+ \li Model used
+ \li Aspects covered
\row
- \o Address Book
- \o QTableView
- \o QAbstractTableModel
+ \li Address Book
+ \li QTableView
+ \li QAbstractTableModel
QSortFilterProxyModel
- \o Usage of QSortFilterProxyModel to generate different
+ \li Usage of QSortFilterProxyModel to generate different
subsets from one data pool
\row
- \o Basic Sort/Filter Model
- \o QTreeView
- \o QStandardItemModel
+ \li Basic Sort/Filter Model
+ \li QTreeView
+ \li QStandardItemModel
QSortFilterProxyModel
- \o
+ \li
\row
- \o Chart
- \o Custom view
- \o QStandardItemModel
- \o Designing custom views that cooperate with selection models
+ \li Chart
+ \li Custom view
+ \li QStandardItemModel
+ \li Designing custom views that cooperate with selection models
\row
- \o Color Editor Factory
- \o {2, 1} QTableWidget
- \o Enhancing the standard delegate with a new custom editor to choose colours
+ \li Color Editor Factory
+ \li {2, 1} QTableWidget
+ \li Enhancing the standard delegate with a new custom editor to choose colours
\row
- \o Combo Widget Mapper
- \o QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox
- \o QStandardItemModel
- \o Shows how a QComboBox can serve as a view class
+ \li Combo Widget Mapper
+ \li QDataWidgetMapper to map QLineEdit, QTextEdit and QComboBox
+ \li QStandardItemModel
+ \li Shows how a QComboBox can serve as a view class
\row
- \o Custom Sort/Filter Model
- \o QTreeView
- \o QStandardItemModel
+ \li Custom Sort/Filter Model
+ \li QTreeView
+ \li QStandardItemModel
QSortFilterProxyModel
- \o Subclass QSortFilterProxyModel for advanced sorting and filtering
+ \li Subclass QSortFilterProxyModel for advanced sorting and filtering
\row
- \o Dir View
- \o QTreeView
- \o QDirModel
- \o Very small example to demonstrate how to assign a model to a view
+ \li Dir View
+ \li QTreeView
+ \li QDirModel
+ \li Very small example to demonstrate how to assign a model to a view
\row
- \o Editable Tree Model
- \o QTreeView
- \o Custom tree model
- \o Comprehensive example for working with trees, demonstrates
+ \li Editable Tree Model
+ \li QTreeView
+ \li Custom tree model
+ \li Comprehensive example for working with trees, demonstrates
editing cells and tree structure with an underlying custom
model
\row
- \o Fetch More
- \o QListView
- \o Custom list model
- \o Dynamically changing model
+ \li Fetch More
+ \li QListView
+ \li Custom list model
+ \li Dynamically changing model
\row
- \o Frozen Column
- \o QTableView
- \o QStandardItemModel
- \o
+ \li Frozen Column
+ \li QTableView
+ \li QStandardItemModel
+ \li
\row
- \o Interview
- \o Multiple
- \o Custom item model
- \o Multiple views
+ \li Interview
+ \li Multiple
+ \li Custom item model
+ \li Multiple views
\row
- \o Pixelator
- \o QTableView
- \o Custom table model
- \o Implementation of a custom delegate
+ \li Pixelator
+ \li QTableView
+ \li Custom table model
+ \li Implementation of a custom delegate
\row
- \o Puzzle
- \o QListView
- \o Custom list model
- \o Model/view with drag and drop
+ \li Puzzle
+ \li QListView
+ \li Custom list model
+ \li Model/view with drag and drop
\row
- \o Simple DOM Model
- \o QTreeView
- \o Custom tree model
- \o Read only example for a custom tree model
+ \li Simple DOM Model
+ \li QTreeView
+ \li Custom tree model
+ \li Read only example for a custom tree model
\row
- \o Simple Tree Model
- \o QTreeView
- \o Custom tree model
- \o Read only example for a custom tree model
+ \li Simple Tree Model
+ \li QTreeView
+ \li Custom tree model
+ \li Read only example for a custom tree model
\row
- \o Simple Widget Mapper
- \o QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox
- \o QStandardItemModel
- \o Basic QDataWidgetMapper usage
+ \li Simple Widget Mapper
+ \li QDataWidgetMapper to map QLineEdit, QTextEdit and QSpinBox
+ \li QStandardItemModel
+ \li Basic QDataWidgetMapper usage
\row
- \o Spin Box Delegate
- \o QTableView
- \o QStandardItemModel
- \o Custom delegate that uses a spin box as a cell editor
+ \li Spin Box Delegate
+ \li QTableView
+ \li QStandardItemModel
+ \li Custom delegate that uses a spin box as a cell editor
\row
- \o Spreadsheet
- \o {2, 1} QTableView
- \o Custom delegates
+ \li Spreadsheet
+ \li {2, 1} QTableView
+ \li Custom delegates
\row
- \o Star Delegate
- \o {2, 1} QTableWidget
- \o Comprehensive custom delegate example.
+ \li Star Delegate
+ \li {2, 1} QTableWidget
+ \li Comprehensive custom delegate example.
\endtable
A \l{Model/View Programming}{reference document} for model/view technology
diff --git a/doc/src/widgets/widgets-and-layouts/focus.qdoc b/doc/src/widgets/widgets-and-layouts/focus.qdoc
index 374d5781eef..60f05948b4e 100644
--- a/doc/src/widgets/widgets-and-layouts/focus.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/focus.qdoc
@@ -51,11 +51,11 @@
\list 1
- \o The user presses \key Tab (or \key Shift+Tab).
- \o The user clicks a widget.
- \o The user presses a keyboard shortcut.
- \o The user uses the mouse wheel.
- \o The user moves the focus to a window, and the application must
+ \li The user presses \key Tab (or \key Shift+Tab).
+ \li The user clicks a widget.
+ \li The user presses a keyboard shortcut.
+ \li The user uses the mouse wheel.
+ \li The user moves the focus to a window, and the application must
determine which widget within the window should get the focus.
\endlist
@@ -93,14 +93,14 @@
\list 1
- \o If the program can determine whether the field is needed, it can
+ \li If the program can determine whether the field is needed, it can
move focus there when the user finishes entry and presses \gui OK, or when
the user presses Enter after finishing the other fields. Alternately,
include the field in the tab order but disable it. Enable it if it
becomes appropriate in view of what the user has set in the other
fields.
- \o The label for the field can include a keyboard shortcut that moves
+ \li The label for the field can include a keyboard shortcut that moves
focus to this field.
\endlist
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc
index 313757ebec6..a74cab05095 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-cde.qdoc
@@ -38,11 +38,11 @@
\table 100%
\row
-\o \image cde-checkbox.png
+\li \image cde-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image cde-radiobutton.png
+\li \image cde-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
-\o \image cde-pushbutton.png
+\li \image cde-pushbutton.png
\image cde-toolbutton.png
\caption The QPushButton widget provides a command button.
\endtable
@@ -51,13 +51,13 @@
\table 100%
\row
-\o \image cde-groupbox.png
+\li \image cde-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image cde-tabwidget.png
+\li \image cde-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image cde-frame.png
+\li \image cde-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image cde-toolbox.png
+\li \image cde-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -65,24 +65,24 @@
\table 100%
\row
-\o \image cde-listview.png
+\li \image cde-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image cde-treeview.png
+\li \image cde-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image cde-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image cde-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image cde-progressbar.png
+\li \image cde-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image cde-label.png
+\li \image cde-label.png
The QLabel widget provides a text or image display.
-\o \image cde-lcdnumber.png
+\li \image cde-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -90,43 +90,43 @@
\table 100%
\row
-\o \image cde-lineedit.png
+\li \image cde-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image cde-dateedit.png
+\li \image cde-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image cde-timeedit.png
+\li \image cde-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image cde-datetimeedit.png
+\li \image cde-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image cde-slider.png
+\li \image cde-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image cde-combobox.png
+\li \image cde-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image cde-spinbox.png
+\li \image cde-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image cde-fontcombobox.png
+\li \image cde-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image cde-doublespinbox.png
+\li \image cde-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image cde-horizontalscrollbar.png
+\li \image cde-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image cde-dial.png
+\li \image cde-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image cde-textedit.png
+\li \image cde-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image cde-calendarwidget.png
+\li \image cde-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc
index 74cd4d4d428..bed6d0ca40b 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-cleanlooks.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image cleanlooks-pushbutton.png
+\li \image cleanlooks-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image cleanlooks-toolbutton.png
+\li \image cleanlooks-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image cleanlooks-checkbox.png
+\li \image cleanlooks-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image cleanlooks-radiobutton.png
+\li \image cleanlooks-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image cleanlooks-groupbox.png
+\li \image cleanlooks-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image cleanlooks-tabwidget.png
+\li \image cleanlooks-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image cleanlooks-frame.png
+\li \image cleanlooks-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image cleanlooks-toolbox.png
+\li \image cleanlooks-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image cleanlooks-listview.png
+\li \image cleanlooks-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image cleanlooks-treeview.png
+\li \image cleanlooks-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image cleanlooks-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image cleanlooks-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image cleanlooks-progressbar.png
+\li \image cleanlooks-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image cleanlooks-label.png
+\li \image cleanlooks-label.png
The QLabel widget provides a text or image display.
-\o \image cleanlooks-lcdnumber.png
+\li \image cleanlooks-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image cleanlooks-lineedit.png
+\li \image cleanlooks-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image cleanlooks-dateedit.png
+\li \image cleanlooks-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image cleanlooks-timeedit.png
+\li \image cleanlooks-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image cleanlooks-datetimeedit.png
+\li \image cleanlooks-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image cleanlooks-slider.png
+\li \image cleanlooks-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image cleanlooks-combobox.png
+\li \image cleanlooks-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image cleanlooks-spinbox.png
+\li \image cleanlooks-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image cleanlooks-fontcombobox.png
+\li \image cleanlooks-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image cleanlooks-doublespinbox.png
+\li \image cleanlooks-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image cleanlooks-horizontalscrollbar.png
+\li \image cleanlooks-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image cleanlooks-dial.png
+\li \image cleanlooks-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image cleanlooks-textedit.png
+\li \image cleanlooks-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image cleanlooks-calendarwidget.png
+\li \image cleanlooks-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc
index 6a7fb5f3b5b..820f0b4140c 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-gtk.qdoc
@@ -41,18 +41,18 @@
\table 100%
\row
-\o \image gtk-pushbutton.png
+\li \image gtk-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image gtk-toolbutton.png
+\li \image gtk-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image gtk-checkbox.png
+\li \image gtk-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image gtk-radiobutton.png
+\li \image gtk-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -60,13 +60,13 @@
\table 100%
\row
-\o \image gtk-groupbox.png
+\li \image gtk-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image gtk-tabwidget.png
+\li \image gtk-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image gtk-frame.png
+\li \image gtk-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image gtk-toolbox.png
+\li \image gtk-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -74,24 +74,24 @@
\table 100%
\row
-\o \image gtk-listview.png
+\li \image gtk-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image gtk-treeview.png
+\li \image gtk-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image gtk-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image gtk-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image gtk-progressbar.png
+\li \image gtk-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image gtk-label.png
+\li \image gtk-label.png
The QLabel widget provides a text or image display.
-\o \image gtk-lcdnumber.png
+\li \image gtk-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -99,43 +99,43 @@
\table 100%
\row
-\o \image gtk-lineedit.png
+\li \image gtk-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image gtk-dateedit.png
+\li \image gtk-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image gtk-timeedit.png
+\li \image gtk-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image gtk-datetimeedit.png
+\li \image gtk-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image gtk-slider.png
+\li \image gtk-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image gtk-combobox.png
+\li \image gtk-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image gtk-spinbox.png
+\li \image gtk-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image gtk-fontcombobox.png
+\li \image gtk-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image gtk-doublespinbox.png
+\li \image gtk-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image gtk-horizontalscrollbar.png
+\li \image gtk-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image gtk-dial.png
+\li \image gtk-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image gtk-textedit.png
+\li \image gtk-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image gtk-calendarwidget.png
+\li \image gtk-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc
index 6eceea114f2..488a3f7665b 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-macintosh.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image macintosh-pushbutton.png
+\li \image macintosh-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image macintosh-toolbutton.png
+\li \image macintosh-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image macintosh-checkbox.png
+\li \image macintosh-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image macintosh-radiobutton.png
+\li \image macintosh-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image macintosh-groupbox.png
+\li \image macintosh-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image macintosh-tabwidget.png
+\li \image macintosh-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image macintosh-frame.png
+\li \image macintosh-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image macintosh-toolbox.png
+\li \image macintosh-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image macintosh-listview.png
+\li \image macintosh-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image macintosh-treeview.png
+\li \image macintosh-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image macintosh-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image macintosh-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image macintosh-progressbar.png
+\li \image macintosh-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image macintosh-label.png
+\li \image macintosh-label.png
The QLabel widget provides a text or image display.
-\o \image macintosh-lcdnumber.png
+\li \image macintosh-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image macintosh-lineedit.png
+\li \image macintosh-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image macintosh-dateedit.png
+\li \image macintosh-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image macintosh-timeedit.png
+\li \image macintosh-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image macintosh-datetimeedit.png
+\li \image macintosh-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image macintosh-slider.png
+\li \image macintosh-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image macintosh-combobox.png
+\li \image macintosh-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image macintosh-spinbox.png
+\li \image macintosh-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image macintosh-fontcombobox.png
+\li \image macintosh-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image macintosh-doublespinbox.png
+\li \image macintosh-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image macintosh-horizontalscrollbar.png
+\li \image macintosh-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image macintosh-dial.png
+\li \image macintosh-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image macintosh-textedit.png
+\li \image macintosh-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image macintosh-calendarwidget.png
+\li \image macintosh-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc
index d059d2282f4..5cbffc55166 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-motif.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image motif-pushbutton.png
+\li \image motif-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image motif-toolbutton.png
+\li \image motif-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image motif-checkbox.png
+\li \image motif-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image motif-radiobutton.png
+\li \image motif-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image motif-groupbox.png
+\li \image motif-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image motif-tabwidget.png
+\li \image motif-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image motif-frame.png
+\li \image motif-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image motif-toolbox.png
+\li \image motif-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image motif-listview.png
+\li \image motif-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image motif-treeview.png
+\li \image motif-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image motif-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image motif-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image motif-progressbar.png
+\li \image motif-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image motif-label.png
+\li \image motif-label.png
The QLabel widget provides a text or image display.
-\o \image motif-lcdnumber.png
+\li \image motif-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image motif-lineedit.png
+\li \image motif-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image motif-dateedit.png
+\li \image motif-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image motif-timeedit.png
+\li \image motif-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image motif-datetimeedit.png
+\li \image motif-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image motif-slider.png
+\li \image motif-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image motif-combobox.png
+\li \image motif-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image motif-spinbox.png
+\li \image motif-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image motif-fontcombobox.png
+\li \image motif-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image motif-doublespinbox.png
+\li \image motif-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image motif-horizontalscrollbar.png
+\li \image motif-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image motif-dial.png
+\li \image motif-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image motif-textedit.png
+\li \image motif-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image motif-calendarwidget.png
+\li \image motif-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc
index 9a57bd6cbcc..359fac80189 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-plastique.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image plastique-pushbutton.png
+\li \image plastique-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image plastique-toolbutton.png
+\li \image plastique-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image plastique-checkbox.png
+\li \image plastique-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image plastique-radiobutton.png
+\li \image plastique-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image plastique-groupbox.png
+\li \image plastique-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image plastique-tabwidget.png
+\li \image plastique-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image plastique-frame.png
+\li \image plastique-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image plastique-toolbox.png
+\li \image plastique-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image plastique-listview.png
+\li \image plastique-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image plastique-treeview.png
+\li \image plastique-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image plastique-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image plastique-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image plastique-progressbar.png
+\li \image plastique-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image plastique-label.png
+\li \image plastique-label.png
The QLabel widget provides a text or image display.
-\o \image plastique-lcdnumber.png
+\li \image plastique-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image plastique-lineedit.png
+\li \image plastique-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image plastique-dateedit.png
+\li \image plastique-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image plastique-timeedit.png
+\li \image plastique-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image plastique-datetimeedit.png
+\li \image plastique-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image plastique-slider.png
+\li \image plastique-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image plastique-combobox.png
+\li \image plastique-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image plastique-spinbox.png
+\li \image plastique-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image plastique-fontcombobox.png
+\li \image plastique-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image plastique-doublespinbox.png
+\li \image plastique-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image plastique-horizontalscrollbar.png
+\li \image plastique-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image plastique-dial.png
+\li \image plastique-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image plastique-textedit.png
+\li \image plastique-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image plastique-calendarwidget.png
+\li \image plastique-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc
index 83ebce97f53..b118c845c6d 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-windows.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image windows-pushbutton.png
+\li \image windows-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image windows-toolbutton.png
+\li \image windows-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image windows-checkbox.png
+\li \image windows-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image windows-radiobutton.png
+\li \image windows-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image windows-groupbox.png
+\li \image windows-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image windows-tabwidget.png
+\li \image windows-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image windows-frame.png
+\li \image windows-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image windows-toolbox.png
+\li \image windows-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image windows-listview.png
+\li \image windows-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image windows-treeview.png
+\li \image windows-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image windows-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image windows-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image windows-progressbar.png
+\li \image windows-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image windows-label.png
+\li \image windows-label.png
The QLabel widget provides a text or image display.
-\o \image windows-lcdnumber.png
+\li \image windows-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image windows-lineedit.png
+\li \image windows-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image windows-dateedit.png
+\li \image windows-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image windows-timeedit.png
+\li \image windows-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image windows-datetimeedit.png
+\li \image windows-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image windows-slider.png
+\li \image windows-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image windows-combobox.png
+\li \image windows-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image windows-spinbox.png
+\li \image windows-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image windows-fontcombobox.png
+\li \image windows-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image windows-doublespinbox.png
+\li \image windows-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image windows-horizontalscrollbar.png
+\li \image windows-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image windows-dial.png
+\li \image windows-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image windows-textedit.png
+\li \image windows-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image windows-calendarwidget.png
+\li \image windows-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc
index e54a4dc3998..db1a7cee901 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-windowsvista.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image windowsvista-pushbutton.png
+\li \image windowsvista-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image windowsvista-toolbutton.png
+\li \image windowsvista-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image windowsvista-checkbox.png
+\li \image windowsvista-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image windowsvista-radiobutton.png
+\li \image windowsvista-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image windowsvista-groupbox.png
+\li \image windowsvista-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image windowsvista-tabwidget.png
+\li \image windowsvista-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image windowsvista-frame.png
+\li \image windowsvista-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image windowsvista-toolbox.png
+\li \image windowsvista-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image windowsvista-listview.png
+\li \image windowsvista-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image windowsvista-treeview.png
+\li \image windowsvista-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image windowsvista-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image windowsvista-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image windowsvista-progressbar.png
+\li \image windowsvista-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image windowsvista-label.png
+\li \image windowsvista-label.png
The QLabel widget provides a text or image display.
-\o \image windowsvista-lcdnumber.png
+\li \image windowsvista-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image windowsvista-lineedit.png
+\li \image windowsvista-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image windowsvista-dateedit.png
+\li \image windowsvista-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image windowsvista-timeedit.png
+\li \image windowsvista-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image windowsvista-datetimeedit.png
+\li \image windowsvista-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image windowsvista-slider.png
+\li \image windowsvista-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image windowsvista-combobox.png
+\li \image windowsvista-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image windowsvista-spinbox.png
+\li \image windowsvista-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image windowsvista-fontcombobox.png
+\li \image windowsvista-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image windowsvista-doublespinbox.png
+\li \image windowsvista-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image windowsvista-horizontalscrollbar.png
+\li \image windowsvista-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image windowsvista-dial.png
+\li \image windowsvista-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image windowsvista-textedit.png
+\li \image windowsvista-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image windowsvista-calendarwidget.png
+\li \image windowsvista-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc b/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc
index 3753402c5ab..2ade5681e2c 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery-windowsxp.qdoc
@@ -38,18 +38,18 @@
\table 100%
\row
-\o \image windowsxp-pushbutton.png
+\li \image windowsxp-pushbutton.png
\caption The QPushButton widget provides a command button.
-\o \image windowsxp-toolbutton.png
+\li \image windowsxp-toolbutton.png
\caption The QToolButton class provides a quick-access button to commands
or options, usually used inside a QToolBar.
\endtable
\table 100%
\row
-\o \image windowsxp-checkbox.png
+\li \image windowsxp-checkbox.png
\caption The QCheckBox widget provides a checkbox with a text label.
-\o \image windowsxp-radiobutton.png
+\li \image windowsxp-radiobutton.png
\caption The QRadioButton widget provides a radio button with a text or pixmap label.
\endtable
@@ -57,13 +57,13 @@
\table 100%
\row
-\o \image windowsxp-groupbox.png
+\li \image windowsxp-groupbox.png
The The QGroupBox widget provides a group box frame with a title.
-\o \image windowsxp-tabwidget.png
+\li \image windowsxp-tabwidget.png
The QTabWidget class provides a stack of tabbed widgets.
-\o \image windowsxp-frame.png
+\li \image windowsxp-frame.png
The QFrame widget provides a simple decorated container for other widgets.
-\o \image windowsxp-toolbox.png
+\li \image windowsxp-toolbox.png
The QToolBox class provides a column of tabbed widget items.
\endtable
@@ -71,24 +71,24 @@
\table 100%
\row
-\o \image windowsxp-listview.png
+\li \image windowsxp-listview.png
The QListView class provides a default model/view implementation of a list/icon view. The QListWidget class provides a classic item-based list/icon view.
-\o \image windowsxp-treeview.png
+\li \image windowsxp-treeview.png
The QTreeView class provides a default model/view implementation of a tree view. The QTreeWidget class provides a classic item-based tree view.
-\o \image windowsxp-tableview.png
- The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\o
-\o
+\li \image windowsxp-tableview.png
+ The QTableView class provides a default model/view implementation of a table view. The QTableWidget class provides a classic item-based table view.\li
+\li
\endtable
\section2 Display Widgets
\table 100%
\row
-\o \image windowsxp-progressbar.png
+\li \image windowsxp-progressbar.png
The QProgressBar widget provides a horizontal progress bar.
-\o \image windowsxp-label.png
+\li \image windowsxp-label.png
The QLabel widget provides a text or image display.
-\o \image windowsxp-lcdnumber.png
+\li \image windowsxp-lcdnumber.png
The QLCDNumber widget displays a number with LCD-like digits.
\endtable
@@ -96,43 +96,43 @@
\table 100%
\row
-\o \image windowsxp-lineedit.png
+\li \image windowsxp-lineedit.png
The QLineEdit widget is a one-line text editor.
-\o \image windowsxp-dateedit.png
+\li \image windowsxp-dateedit.png
The QDateEdit class provides a widget for editing dates.
-\o \image windowsxp-timeedit.png
+\li \image windowsxp-timeedit.png
The QTimeEdit class provides a widget for editing times.
-\o \image windowsxp-datetimeedit.png
+\li \image windowsxp-datetimeedit.png
The QDateTimeEdit class provides a widget for editing dates and times.
\endtable
\table 100%
\row
-\o \image windowsxp-slider.png
+\li \image windowsxp-slider.png
The QSlider widget provides a vertical or horizontal slider.
-\o \image windowsxp-combobox.png
+\li \image windowsxp-combobox.png
The QComboBox widget is a combined button and pop-up list.
-\o \image windowsxp-spinbox.png
+\li \image windowsxp-spinbox.png
The QSpinBox class provides a spin box widget.
\endtable
\table 100%
\row
-\o \image windowsxp-fontcombobox.png
+\li \image windowsxp-fontcombobox.png
The QFontComboBox widget is a specialized combobox that enables fonts to be selected from a pop-up list containing previews of available fonts.
-\o \image windowsxp-doublespinbox.png
+\li \image windowsxp-doublespinbox.png
The QDoubleSpinBox class provides a spin box widget that allows double precision floating point numbers to be entered.
-\o \image windowsxp-horizontalscrollbar.png
+\li \image windowsxp-horizontalscrollbar.png
The QScrollBar widget provides a vertical or horizontal scroll bar. Here, we show a scroll bar with horizontal orientation.
\endtable
\table 100%
\row
-\o \image windowsxp-dial.png
+\li \image windowsxp-dial.png
The QDial class provides a rounded range control (like a speedometer or potentiometer).
-\o \image windowsxp-textedit.png
+\li \image windowsxp-textedit.png
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
-\o \image windowsxp-calendarwidget.png
+\li \image windowsxp-calendarwidget.png
The QCalendarWidget class provides a monthly calendar widget that can be used to select dates.
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/gallery.qdoc b/doc/src/widgets/widgets-and-layouts/gallery.qdoc
index d82eda48051..a2f4db5a7b9 100644
--- a/doc/src/widgets/widgets-and-layouts/gallery.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/gallery.qdoc
@@ -36,15 +36,15 @@
\table
\row
- \o \image plastique-tabwidget.png Plastique Style Widget Gallery
+ \li \image plastique-tabwidget.png Plastique Style Widget Gallery
\caption \l{Plastique Style Widget Gallery}
The Plastique style is provided by QPlastiqueStyle.
- \o \image windowsxp-tabwidget.png Windows XP Style Widget Gallery
+ \li \image windowsxp-tabwidget.png Windows XP Style Widget Gallery
\caption \l{Windows XP Style Widget Gallery}
The Windows XP style is provided by QWindowsXPStyle.
- \o \image windows-tabwidget.png Windows Style Widget Gallery
+ \li \image windows-tabwidget.png Windows Style Widget Gallery
\caption \l{Windows Style Widget Gallery}
The Windows style is provided by QWindowsStyle.
@@ -52,15 +52,15 @@
\table
\row
- \o \image macintosh-tabwidget.png Macintosh Style Widget Gallery
+ \li \image macintosh-tabwidget.png Macintosh Style Widget Gallery
\caption \l{Macintosh Style Widget Gallery}
The Macintosh style is provided by QMacStyle.
- \o \image cleanlooks-tabwidget.png Cleanlooks Style Widget Gallery
+ \li \image cleanlooks-tabwidget.png Cleanlooks Style Widget Gallery
\caption \l{Cleanlooks Style Widget Gallery}
The Cleanlooks style is provided by QCleanlooksStyle.
- \o \image windowsvista-tabwidget.png Windows Vista Style Widget Gallery
+ \li \image windowsvista-tabwidget.png Windows Vista Style Widget Gallery
\caption \l{Windows Vista Style Widget Gallery}
The Windows Vista style is provided by QWindowsVistaStyle.
@@ -68,15 +68,15 @@
\table
\row
- \o \image gtk-tabwidget.png GTK Style Widget Gallery
+ \li \image gtk-tabwidget.png GTK Style Widget Gallery
\caption \l{GTK Style Widget Gallery}
The GTK style is provided by QGtkStyle.
- \o \image motif-tabwidget.png Motif Style Widget Gallery
+ \li \image motif-tabwidget.png Motif Style Widget Gallery
\caption \l{Motif Style Widget Gallery}
The Motif style is provided by QMotifStyle.
- \o \image cde-tabwidget.png CDE Style Widget Gallery
+ \li \image cde-tabwidget.png CDE Style Widget Gallery
\caption \l{CDE Style Widget Gallery}
The Common Desktop Environment style is provided by QCDEStyle.
diff --git a/doc/src/widgets/widgets-and-layouts/layout.qdoc b/doc/src/widgets/widgets-and-layouts/layout.qdoc
index ccc15ef8059..6e1a5f70e13 100644
--- a/doc/src/widgets/widgets-and-layouts/layout.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/layout.qdoc
@@ -63,15 +63,15 @@
is set on a widget in this way, it takes charge of the following tasks:
\list
- \o Positioning of child widgets.
- \o Sensible default sizes for windows.
- \o Sensible minimum sizes for windows.
- \o Resize handling.
- \o Automatic updates when contents change:
+ \li Positioning of child widgets.
+ \li Sensible default sizes for windows.
+ \li Sensible minimum sizes for windows.
+ \li Resize handling.
+ \li Automatic updates when contents change:
\list
- \o Font size, text or other contents of child widgets.
- \o Hiding or showing a child widget.
- \o Removal of child widgets.
+ \li Font size, text or other contents of child widgets.
+ \li Hiding or showing a child widget.
+ \li Removal of child widgets.
\endlist
\endlist
@@ -95,19 +95,19 @@
create more complex layouts, you can nest layout managers inside each other.
\list
- \o A QHBoxLayout lays out widgets in a horizontal row, from left to
+ \li A QHBoxLayout lays out widgets in a horizontal row, from left to
right (or right to left for right-to-left languages).
\image qhboxlayout-with-5-children.png
- \o A QVBoxLayout lays out widgets in a vertical column, from top to
+ \li A QVBoxLayout lays out widgets in a vertical column, from top to
bottom.
\image qvboxlayout-with-5-children.png
- \o A QGridLayout lays out widgets in a two-dimensional grid. Widgets
+ \li A QGridLayout lays out widgets in a two-dimensional grid. Widgets
can occupy multiple cells.
\image qgridlayout-with-5-children.png
- \o A QFormLayout lays out widgets in a 2-column descriptive label-
+ \li A QFormLayout lays out widgets in a 2-column descriptive label-
field style.
\image qformlayout-with-6-children.png
\endlist
@@ -176,26 +176,26 @@
When you add widgets to a layout, the layout process works as follows:
\list 1
- \o All the widgets will initially be allocated an amount of space in
+ \li All the widgets will initially be allocated an amount of space in
accordance with their QWidget::sizePolicy() and
QWidget::sizeHint().
- \o If any of the widgets have stretch factors set, with a value
+ \li If any of the widgets have stretch factors set, with a value
greater than zero, then they are allocated space in proportion to
their stretch factor (explained below).
- \o If any of the widgets have stretch factors set to zero they will
+ \li If any of the widgets have stretch factors set to zero they will
only get more space if no other widgets want the space. Of these,
space is allocated to widgets with an
\l{QSizePolicy::Expanding}{Expanding} size policy first.
- \o Any widgets that are allocated less space than their minimum size
+ \li Any widgets that are allocated less space than their minimum size
(or minimum size hint if no minimum size is specified) are
allocated this minimum size they require. (Widgets don't have to
have a minimum size or minimum size hint in which case the stretch
factor is their determining factor.)
- \o Any widgets that are allocated more space than their maximum size
+ \li Any widgets that are allocated more space than their maximum size
are allocated the maximum size space they require. (Widgets do not
have to have a maximum size in which case the stretch factor is
their determining factor.)
@@ -231,11 +231,11 @@
following mechanisms:
\list
- \o Reimplement QWidget::sizeHint() to return the preferred size of the
+ \li Reimplement QWidget::sizeHint() to return the preferred size of the
widget.
- \o Reimplement QWidget::minimumSizeHint() to return the smallest size
+ \li Reimplement QWidget::minimumSizeHint() to return the smallest size
the widget can have.
- \o Call QWidget::setSizePolicy() to specify the space requirements of
+ \li Call QWidget::setSizePolicy() to specify the space requirements of
the widget.
\endlist
@@ -304,14 +304,14 @@
To write your own layout class, you must define the following:
\list
- \o A data structure to store the items handled by the layout. Each
+ \li A data structure to store the items handled by the layout. Each
item is a \link QLayoutItem QLayoutItem\endlink. We will use a
QList in this example.
- \o \l{QLayout::}{addItem()}, how to add items to the layout.
- \o \l{QLayout::}{setGeometry()}, how to perform the layout.
- \o \l{QLayout::}{sizeHint()}, the preferred size of the layout.
- \o \l{QLayout::}{itemAt()}, how to iterate over the layout.
- \o \l{QLayout::}{takeAt()}, how to remove items from the layout.
+ \li \l{QLayout::}{addItem()}, how to add items to the layout.
+ \li \l{QLayout::}{setGeometry()}, how to perform the layout.
+ \li \l{QLayout::}{sizeHint()}, the preferred size of the layout.
+ \li \l{QLayout::}{itemAt()}, how to iterate over the layout.
+ \li \l{QLayout::}{takeAt()}, how to remove items from the layout.
\endlist
In most cases, you will also implement \l{QLayout::}{minimumSize()}.
@@ -376,16 +376,16 @@
\section2 Further Notes
\list
- \o This custom layout does not handle height for width.
- \o We ignore QLayoutItem::isEmpty(); this means that the layout will
+ \li This custom layout does not handle height for width.
+ \li We ignore QLayoutItem::isEmpty(); this means that the layout will
treat hidden widgets as visible.
- \o For complex layouts, speed can be greatly increased by caching
+ \li For complex layouts, speed can be greatly increased by caching
calculated values. In that case, implement
QLayoutItem::invalidate() to mark the cached data is dirty.
- \o Calling QLayoutItem::sizeHint(), etc. may be expensive. So, you
+ \li Calling QLayoutItem::sizeHint(), etc. may be expensive. So, you
should store the value in a local variable if you need it again
later within in the same function.
- \o You should not call QLayoutItem::setGeometry() twice on the same
+ \li You should not call QLayoutItem::setGeometry() twice on the same
item in the same function. This call can be very expensive if the
item has several child widgets, because the layout manager must do
a complete layout every time. Instead, calculate the geometry and
diff --git a/doc/src/widgets/widgets-and-layouts/styles.qdoc b/doc/src/widgets/widgets-and-layouts/styles.qdoc
index febe1a8345d..b9e3a303339 100644
--- a/doc/src/widgets/widgets-and-layouts/styles.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/styles.qdoc
@@ -93,10 +93,10 @@
bar. Most draw functions now take four arguments:
\list
- \o an enum value specifying which graphical element to draw
- \o a QStyleOption specifying how and where to render that element
- \o a QPainter that should be used to draw the element
- \o a QWidget on which the drawing is performed (optional)
+ \li an enum value specifying which graphical element to draw
+ \li a QStyleOption specifying how and where to render that element
+ \li a QPainter that should be used to draw the element
+ \li a QWidget on which the drawing is performed (optional)
\endlist
When a widget asks a style to draw an element, it provides the style
@@ -309,11 +309,11 @@
following parameters:
\list
- \o the enum value of the element to draw
- \o a QStyleOption which contains the information needed to
+ \li the enum value of the element to draw
+ \li a QStyleOption which contains the information needed to
draw the element.
- \o a QPainter with which to draw the element.
- \o a pointer to a QWidget, typically the widget
+ \li a QPainter with which to draw the element.
+ \li a pointer to a QWidget, typically the widget
that the element is painted on.
\endlist
@@ -337,27 +337,27 @@
typically takes the same arguments.
\list
- \o The \l{QStyle::}{subElementRect()} function takes a
+ \li The \l{QStyle::}{subElementRect()} function takes a
\l{QStyle::}{SubElement} enum value, and calculates a bounding
rectangle for a sub element. The style uses this function to
know where to draw the different parts of an element. This is
mainly done for reuse. If you create a new style, you can use
the same location of sub elements as the super class.
- \o The \l{QStyle::}{subControlRect()} function is used to
+ \li The \l{QStyle::}{subControlRect()} function is used to
calculate bounding rectangles for sub controls in complex
controls. When you implement a new style, you reimplement \c
subControlRect() and calculate the rectangles that are different
from the super class.
- \o The \l{QStyle::}{pixelMetric()} function returns a pixel
+ \li The \l{QStyle::}{pixelMetric()} function returns a pixel
metric, which is a style dependent size given in screen
pixels. It takes a value of the \l{QStyle::}{PixelMetric} enum
and returns the correct measure. Note that pixel metrics do
not necessarily have to be static measures, but can be
calculated with, for example, the style option.
- \o The \l{QStyle::}{hitTestComplexControl()} function returns the
+ \li The \l{QStyle::}{hitTestComplexControl()} function returns the
sub control that the mouse pointer is over in a complex control.
Usually, this is simply a matter of using
\l{QStyle::}{subControlRect()} to get the bounding rectangles of
@@ -588,35 +588,35 @@
\table 90%
\header
- \o State flag
- \o Set
+ \li State flag
+ \li Set
\row
- \o State_Sunken
- \o Yes
+ \li State_Sunken
+ \li Yes
\row
- \o State_NoChange
- \o No
+ \li State_NoChange
+ \li No
\row
- \o State_On
- \o Yes
+ \li State_On
+ \li Yes
\row
- \o State_Off
- \o No
+ \li State_Off
+ \li No
\row
- \o State_MouseOver
- \o Yes
+ \li State_MouseOver
+ \li Yes
\row
- \o State_Enabled
- \o Yes
+ \li State_Enabled
+ \li Yes
\row
- \o State_HasFocus
- \o Yes
+ \li State_HasFocus
+ \li Yes
\row
- \o State_KeyboardFocusChange
- \o No
+ \li State_KeyboardFocusChange
+ \li No
\row
- \o State_Active
- \o Yes
+ \li State_Active
+ \li Yes
\endtable
The QCheckBox paints itself in QWidget::paintEvent() with
@@ -714,16 +714,16 @@
The following is given for each widget:
\list
- \o A table with the members (variables, etc.) of its style option.
- \o A table over the state flags (QStyle::StateFlag) that
+ \li A table with the members (variables, etc.) of its style option.
+ \li A table over the state flags (QStyle::StateFlag) that
can be set on the widget and when the states are set.
- \o Its element tree (see section \l{The Style Elements}).
- \o An image of the widget in which the elements are outlined.
+ \li Its element tree (see section \l{The Style Elements}).
+ \li An image of the widget in which the elements are outlined.
\omit This is not written yet - probably never will be
either
- \o List of style hints that should be checked for the
+ \li List of style hints that should be checked for the
widget.
- \o List of standard pixmaps that could be used by the
+ \li List of standard pixmaps that could be used by the
elements.
\endomit
\endlist
@@ -737,7 +737,7 @@
Our approach on styling center on the drawing of the widgets. The
calculations of sub elements rectangles, sub controls, and pixel
- metrics used \bold during drawing is only listed as contents in
+ metrics used \b during drawing is only listed as contents in
the element trees. Note that there are rectangles and pixel
metrics that are only used by widgets. This leaves these
calculations untreated in the walkthrough. For instance, the
@@ -778,53 +778,53 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Enabled
- \o Set if the widget is not disabled (see
+ \li State_Enabled
+ \li Set if the widget is not disabled (see
QWidget::setEnabled())
\row
- \o State_Focus
- \o Set if the widget has focus (see
+ \li State_Focus
+ \li Set if the widget has focus (see
QWidget::hasFocus())
\row
- \o State_KeyobordFocusChange
- \o Set when the user changes focus with the keyboard
+ \li State_KeyobordFocusChange
+ \li Set when the user changes focus with the keyboard
(see Qt::WA_KeyboardFocusChange)
\row
- \o State_MouseOver
- \o Set if the mouse cursor is over the widget
+ \li State_MouseOver
+ \li Set if the mouse cursor is over the widget
\row
- \o State_Active
- \o Set if the widget is a child of the active window.
+ \li State_Active
+ \li Set if the widget is a child of the active window.
\row
- \o State_HasEditFocus
- \o Set if the widget has the edit focus
+ \li State_HasEditFocus
+ \li Set if the widget has the edit focus
\endtable
The other common members for widgets are:
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o rect
- \o The bounding rectangle of the element to draw. This
+ \li rect
+ \li The bounding rectangle of the element to draw. This
is set to the widget bounding rectangle
(QWidget::rect()).
\row
- \o direction
- \o The layout direction; a value of the
+ \li direction
+ \li The layout direction; a value of the
Qt::LayoutDirection enum.
\row
- \o palette
- \o The QPalette to use when drawing the element. This
+ \li palette
+ \li The QPalette to use when drawing the element. This
is set to the widgets palette (QWidget::palette()).
\row
- \o fontMetrics
- \o The QFontMetrics to use when drawing text on the
+ \li fontMetrics
+ \li The QFontMetrics to use when drawing text on the
widget.
\endtable
@@ -885,38 +885,38 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Sunken
- \o Button is down or menu is pressed shown
+ \li State_Sunken
+ \li Button is down or menu is pressed shown
\row
- \o State_On
- \o Button is checked
+ \li State_On
+ \li Button is checked
\row
- \o State_Raised
- \o Button is not flat and not pressed down
+ \li State_Raised
+ \li Button is not flat and not pressed down
\endtable
Other members of QStyleOptionButton is:
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o features
- \o Flags of the QStyleOptionButton::ButtonFeatures enum,
+ \li features
+ \li Flags of the QStyleOptionButton::ButtonFeatures enum,
which describes various button properties (see enum)
\row
- \o icon
- \o The buttons QIcon (if any)
+ \li icon
+ \li The buttons QIcon (if any)
\row
- \o iconSize
- \o The QSize of the icon
+ \li iconSize
+ \li The QSize of the icon
\row
- \o text
- \o a QString with the buttons text
+ \li text
+ \li a QString with the buttons text
\endtable
\section3 Check and Radio Buttons
@@ -933,21 +933,21 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_sunken
- \o The box is pressed down
+ \li State_sunken
+ \li The box is pressed down
\row
- \o State_NoChange
- \o The box is partially checked (for tristate
+ \li State_NoChange
+ \li The box is partially checked (for tristate
checkboxes.)
\row
- \o State_On
- \o The box is checked
+ \li State_On
+ \li The box is checked
\row
- \o State_Off
- \o The box is unchecked
+ \li State_Off
+ \li The box is unchecked
\endtable
See \l{Push Buttons} for a table over other members in the
@@ -1017,17 +1017,17 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Sunken
- \o The tab is pressed on with the mouse.
+ \li State_Sunken
+ \li The tab is pressed on with the mouse.
\row
- \o State_Selected
- \o If it is the current tab.
+ \li State_Selected
+ \li If it is the current tab.
\row
- \o State_HasFocus
- \o The tab bar has focus and the tab is selected
+ \li State_HasFocus
+ \li The tab bar has focus and the tab is selected
\endtable
Note that individual tabs may be disabled even if the tab bar
@@ -1037,38 +1037,38 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o cornerWidgets
- \o Is flags of the CornerWidget enum, which indicate
+ \li cornerWidgets
+ \li Is flags of the CornerWidget enum, which indicate
if and which corner widgets the tab bar has.
\row
- \o icon
- \o The QIcon of the tab
+ \li icon
+ \li The QIcon of the tab
\row
- \o iconSize
- \o The QSize of the icon
+ \li iconSize
+ \li The QSize of the icon
\row
- \o position
- \o A TabPosition enum value that indicates the tabs
+ \li position
+ \li A TabPosition enum value that indicates the tabs
position on the bar relative to the other tabs.
\row
- \o row
- \o holds which row the tab is in
+ \li row
+ \li holds which row the tab is in
\row
- \o selectedPosition
- \o A value of the SelectedPosition enum that indicates
+ \li selectedPosition
+ \li A value of the SelectedPosition enum that indicates
whether the selected tab is adjacent to or is the
tab.
\row
- \o shape
- \o A value of the QTabBar::Shape enum indication
+ \li shape
+ \li A value of the QTabBar::Shape enum indication
whether the tab has rounded or triangular corners
and the orientation of the tab.
\row
- \o text
- \o The tab text
+ \li text
+ \li The tab text
\endtable
The frame for tab widgets use QStyleOptionTabWidgetFrame as
@@ -1077,26 +1077,26 @@
\table 90%
\header
- \o Member
- \o content
+ \li Member
+ \li content
\row
- \o leftCornerWidgetSize
- \o The QSize of the left corner widget (if any).
+ \li leftCornerWidgetSize
+ \li The QSize of the left corner widget (if any).
\row
- \o rightCornerWidgetSize
- \o The QSize of the right corner widget (if any).
+ \li rightCornerWidgetSize
+ \li The QSize of the right corner widget (if any).
\row
- \o lineWidth
- \o holds the line with for drawing the panel.
+ \li lineWidth
+ \li holds the line with for drawing the panel.
\row
- \o midLineWith
- \o this value is currently always 0.
+ \li midLineWith
+ \li this value is currently always 0.
\row
- \o shape
- \o The shape of the tabs on the tab bar.
+ \li shape
+ \li The shape of the tabs on the tab bar.
\row
- \o tabBarSize
- \o The QSize of the tab bar.
+ \li tabBarSize
+ \li The QSize of the tab bar.
\endtable
\section3 Scroll Bars
@@ -1130,11 +1130,11 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Horizontal
- \o The scroll bar is horizontal
+ \li State_Horizontal
+ \li The scroll bar is horizontal
\endtable
The style option of QScrollBar is QStyleOptionSlider. Its
@@ -1144,43 +1144,43 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o maximum
- \o the maximum value of the scroll bar
+ \li maximum
+ \li the maximum value of the scroll bar
\row
- \o minimum
- \o the minimum value of the scroll bar
+ \li minimum
+ \li the minimum value of the scroll bar
\row
- \o notchTarget
- \o the number of pixels between notches
+ \li notchTarget
+ \li the number of pixels between notches
\row
- \o orientation
- \o a value of the Qt::Orientation enum that specifies
+ \li orientation
+ \li a value of the Qt::Orientation enum that specifies
whether the scroll bar is vertical or horizontal
\row
- \o pageStep
- \o the number to increase or decrease the sliders
+ \li pageStep
+ \li the number to increase or decrease the sliders
value (relative to the size of the slider and its value
range) on page steps.
\row
- \o singleStep
- \o the number to increase or decrease the sliders
+ \li singleStep
+ \li the number to increase or decrease the sliders
value on single (or line) steps
\row
- \o sliderValue
- \o The value of the slider
+ \li sliderValue
+ \li The value of the slider
\row
- \o sliderPosition
- \o the position of the slider handle. This is the same
+ \li sliderPosition
+ \li the position of the slider handle. This is the same
as \c sliderValue if the scroll bar is
QAbstractSlider::tracking. If not, the scroll
bar does not update its value before the mouse
releases the handle.
\row
- \o upsideDown
- \o holds the direction in which the scroll bar
+ \li upsideDown
+ \li holds the direction in which the scroll bar
increases its value. This is used instead of
QStyleOption::direction for all abstract sliders.
\endtable
@@ -1207,42 +1207,42 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o maximum
- \o the maximum value of the slider
+ \li maximum
+ \li the maximum value of the slider
\row
- \o minimum
- \o the minimum value of the slider
+ \li minimum
+ \li the minimum value of the slider
\row
- \o notchTarget
- \o this is the number of pixels between each notch
+ \li notchTarget
+ \li this is the number of pixels between each notch
\row
- \o orientation
- \o a Qt::Orientation enum value that gives whether the
+ \li orientation
+ \li a Qt::Orientation enum value that gives whether the
slider is vertical or horizontal.
\row
- \o pageStep
- \o a number in slider value to increase or decrease
+ \li pageStep
+ \li a number in slider value to increase or decrease
for page steps
\row
- \o singleStep
- \o the number to increase or decrease the sliders
+ \li singleStep
+ \li the number to increase or decrease the sliders
value on single (or line) steps.
\row
- \o sliderValue
- \o the value of the slider.
+ \li sliderValue
+ \li the value of the slider.
\row
- \o sliderPosition
- \o the position of the slider given as a slider value.
+ \li sliderPosition
+ \li the position of the slider given as a slider value.
This will be equal to the \c sliderValue if the
slider is \l{QAbstractSlider::}{tracking}; if
not, the sliders value will not change until the handle is
released with the mouse.
\row
- \o upsideDown
- \o this member is used instead of QStyleOption::direction
+ \li upsideDown
+ \li this member is used instead of QStyleOption::direction
for all abstract sliders.
\endtable
@@ -1270,11 +1270,11 @@
\table 90%
\header
- \o State
- \o State Set When
+ \li State
+ \li State Set When
\row
- \o State_Sunken
- \o Is set if one of the sub controls CC_SpinUp or
+ \li State_Sunken
+ \li Is set if one of the sub controls CC_SpinUp or
CC_SpinDown is pressed on with the mouse.
\endtable
@@ -1282,19 +1282,19 @@
\table 90%
\header
- \o Property
- \o Function
+ \li Property
+ \li Function
\row
- \o frame
- \o boolean that is true if the spin box is to draw a
+ \li frame
+ \li boolean that is true if the spin box is to draw a
frame.
\row
- \o buttonSymbols
- \o Value of the ButtonSymbols enum that decides the
+ \li buttonSymbols
+ \li Value of the ButtonSymbols enum that decides the
symbol on the up/down buttons.
\row
- \o stepEnabled
- \o A value of the StepEnabled indication which of the
+ \li stepEnabled
+ \li A value of the StepEnabled indication which of the
spin box buttons are pressed down.
\endtable
@@ -1326,21 +1326,21 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o icon
- \o The title bars icon
+ \li icon
+ \li The title bars icon
\row
- \o text
- \o the text for the title bar's label
+ \li text
+ \li the text for the title bar's label
\row
- \o windowFlags
- \o flags of the Qt::WindowFlag enum. The window flags
+ \li windowFlags
+ \li flags of the Qt::WindowFlag enum. The window flags
used by QMdiArea for window management.
\row
- \o titleBarState
- \o this is the QWidget::windowState() of the window
+ \li titleBarState
+ \li this is the QWidget::windowState() of the window
that contains the title bar.
\endtable
@@ -1374,44 +1374,44 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Selected
- \o The box is not editable and has focus
+ \li State_Selected
+ \li The box is not editable and has focus
\row
- \o State_Sunken
- \o SC_ComboBoxArrow is active
+ \li State_Sunken
+ \li SC_ComboBoxArrow is active
\row
- \o State_on
- \o The container (list) of the box is visible
+ \li State_on
+ \li The container (list) of the box is visible
\endtable
The style options other members are:
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o currentIcon
- \o the icon of the current (selected) item of the
+ \li currentIcon
+ \li the icon of the current (selected) item of the
combo box.
\row
- \o currentText
- \o the text of the current item in the box.
+ \li currentText
+ \li the text of the current item in the box.
\row
- \o editable
- \o holds whether the combo box is editable or not
+ \li editable
+ \li holds whether the combo box is editable or not
\row
- \o frame
- \o holds whether the combo box has a frame or not
+ \li frame
+ \li holds whether the combo box has a frame or not
\row
- \o iconSize
- \o the size of the current items icon.
+ \li iconSize
+ \li the size of the current items icon.
\row
- \o popupRect
- \o the bounding rectangle of the combo box's popup
+ \li popupRect
+ \li the bounding rectangle of the combo box's popup
list.
\endtable
@@ -1438,42 +1438,42 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_On
- \o The check box is checked
+ \li State_On
+ \li The check box is checked
\row
- \o State_Sunken
- \o The checkbox is pressed down
+ \li State_Sunken
+ \li The checkbox is pressed down
\row
- \o State_Off
- \o The check box is unchecked (or there is no check box)
+ \li State_Off
+ \li The check box is unchecked (or there is no check box)
\endtable
The remaining members of QStyleOptionGroupBox are:
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o features
- \o flags of the QStyleOptionFrameV2::FrameFeatures
+ \li features
+ \li flags of the QStyleOptionFrameV2::FrameFeatures
enum describing the frame of the group box.
\row
- \o lineWidth
- \o the line width with which to draw the panel. This
+ \li lineWidth
+ \li the line width with which to draw the panel. This
is always 1.
\row
- \o text
- \o the text of the group box.
+ \li text
+ \li the text of the group box.
\row
- \o textAlignment
- \o the alignment of the group box title
+ \li textAlignment
+ \li the alignment of the group box title
\row
- \o textColor
- \o the QColor of the text
+ \li textColor
+ \li the QColor of the text
\endtable
\section3 Splitters
@@ -1487,11 +1487,11 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Horizontal
- \o Set if it is a horizontal splitter
+ \li State_Horizontal
+ \li Set if it is a horizontal splitter
\endtable
QSplitter does not use \l{QStyleOption::}{initFrom()} to set up its
@@ -1517,36 +1517,36 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o minimum
- \o The minimum value of the bar
+ \li minimum
+ \li The minimum value of the bar
\row
- \o maximum
- \o The maximum value of the bar
+ \li maximum
+ \li The maximum value of the bar
\row
- \o progress
- \o The current value of the bar
+ \li progress
+ \li The current value of the bar
\row
- \o textAlignment
- \o How the text is aligned in the label
+ \li textAlignment
+ \li How the text is aligned in the label
\row
- \o textVisible
- \o Whether the label is drawn
+ \li textVisible
+ \li Whether the label is drawn
\row
- \o text
- \o The label text
+ \li text
+ \li The label text
\row
- \o orientation
- \o Progress bars can be vertical or horizontal
+ \li orientation
+ \li Progress bars can be vertical or horizontal
\row
- \o invertedAppearance
- \o The progress is inverted (i.e., right to left in a
+ \li invertedAppearance
+ \li The progress is inverted (i.e., right to left in a
horizontal bar)
\row
- \o bottomToTop
- \o Boolean that if true, turns the label of vertical
+ \li bottomToTop
+ \li Boolean that if true, turns the label of vertical
progress bars 90 degrees.
\endtable
@@ -1578,58 +1578,58 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_AutoRise
- \o the tool button has the autoRise property set
+ \li State_AutoRise
+ \li the tool button has the autoRise property set
\row
- \o State_raised
- \o the button is not sunken (i.e., by being checked or
+ \li State_raised
+ \li the button is not sunken (i.e., by being checked or
pressed on with the mouse).
\row
- \o State_Sunken
- \o the button is down
+ \li State_Sunken
+ \li the button is down
\row
- \o State_On
- \o the button is checkable and checked.
+ \li State_On
+ \li the button is checkable and checked.
\endtable
QStyleOptionToolButton also contains the following members:
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o arrowType
- \o a Qt::ArrowType enum value, which contains the
+ \li arrowType
+ \li a Qt::ArrowType enum value, which contains the
direction of the buttons arrow (if an arrow is to
be used in place of an icon)
\row
- \o features
- \o flags of the QStyleOptionToolButton::ButtonFeature
+ \li features
+ \li flags of the QStyleOptionToolButton::ButtonFeature
enum describing if the button has an arrow, a menu,
and/or has a popup-delay.
\row
- \o font
- \o the QFont of the buttons label
+ \li font
+ \li the QFont of the buttons label
\row
- \o icon
- \o the QIcon of the tool button
+ \li icon
+ \li the QIcon of the tool button
\row
- \o iconSize
- \o the icon size of the button's icon
+ \li iconSize
+ \li the icon size of the button's icon
\row
- \o pos
- \o the position of the button, as given by
+ \li pos
+ \li the position of the button, as given by
QWidget::pos()
\row
- \o text
- \o the text of the button
+ \li text
+ \li the text of the button
\row
- \o toolButtonStyle
- \o a Qt::ToolButtonStyle enum value which decides
+ \li toolButtonStyle
+ \li a Qt::ToolButtonStyle enum value which decides
whether the button shows the icon, the text, or both.
\endtable
@@ -1677,29 +1677,29 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o features
- \o Holds whether the bar is movable in a value of the
+ \li features
+ \li Holds whether the bar is movable in a value of the
ToolBarFeature, which is either Movable or None.
\row
- \o lineWidth
- \o The width of the tool bar frame.
+ \li lineWidth
+ \li The width of the tool bar frame.
\row
- \o midLineWidth
- \o This variable is currently not used and is always
+ \li midLineWidth
+ \li This variable is currently not used and is always
0.
\row
- \o positionOfLine
- \o The position of the toolbar line within the toolbar
+ \li positionOfLine
+ \li The position of the toolbar line within the toolbar
area to which it belongs.
\row
- \o positionWithinLine
- \o The position of the toolbar within the toolbar line.
+ \li positionWithinLine
+ \li The position of the toolbar within the toolbar line.
\row
- \o toolBarArea
- \o The toolbar area in which the toolbar lives.
+ \li toolBarArea
+ \li The toolbar area in which the toolbar lives.
\endtable
\section3 Menus
@@ -1740,61 +1740,61 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Selected
- \o The mouse is over the action and the action is not
+ \li State_Selected
+ \li The mouse is over the action and the action is not
a separator.
\row
- \o State_Sunken
- \o The mouse is pressed down on the menu item.
+ \li State_Sunken
+ \li The mouse is pressed down on the menu item.
\row
- \o State_DownArrow
- \o Set if the menu item is a menu scroller and it scrolls
+ \li State_DownArrow
+ \li Set if the menu item is a menu scroller and it scrolls
the menu downwards.
\endtable
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o checkType
- \o A value of the \l{QStyleOptionMenuItem::}{CheckType} enum,
+ \li checkType
+ \li A value of the \l{QStyleOptionMenuItem::}{CheckType} enum,
which is either NotCheckable, Exclusive, or
NonExclusive.
\row
- \o checked
- \o Boolean that is true if the menu item is checked.
+ \li checked
+ \li Boolean that is true if the menu item is checked.
\row
- \o font
- \o The QFont to use for the menu item's text.
+ \li font
+ \li The QFont to use for the menu item's text.
\row
- \o icon
- \o the QIcon of the menu item.
+ \li icon
+ \li the QIcon of the menu item.
\row
- \o maxIconWidth
- \o The maximum width allowed for the icon
+ \li maxIconWidth
+ \li The maximum width allowed for the icon
\row
- \o menuHasChecableItem
- \o Boolean which is true if at least one item in the
+ \li menuHasChecableItem
+ \li Boolean which is true if at least one item in the
menu is checkable.
\row
- \o menuItemType
- \o The type of the menu item. This a value of the
+ \li menuItemType
+ \li The type of the menu item. This a value of the
\l{QStyleOptionMenuItem::}{MenuItemType}.
\row
- \o menuRect
- \o The bounding rectangle for the QMenu that the menu
+ \li menuRect
+ \li The bounding rectangle for the QMenu that the menu
item lives in.
\row
- \o tabWidth
- \o This is the distance between the text of the menu
+ \li tabWidth
+ \li This is the distance between the text of the menu
item and the shortcut.
\row
- \o text
- \o The text of the menu item.
+ \li text
+ \li The text of the menu item.
\endtable
The setup of the style option for CE_MenuTearOff and
@@ -1825,18 +1825,18 @@
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o menuRect
- \o the bounding rectangle of the entire menu bar to
+ \li menuRect
+ \li the bounding rectangle of the entire menu bar to
which the item belongs.
\row
- \o text
- \o the text of the item
+ \li text
+ \li the text of the item
\row
- \o icon
- \o the icon of the menu item (it is not common that
+ \li icon
+ \li the icon of the menu item (it is not common that
styles draw this icon)
\endtable
@@ -1874,44 +1874,44 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o icon
- \o the icon of the header (for section that is being
+ \li icon
+ \li the icon of the header (for section that is being
drawn).
\row
- \o iconAlignment
- \o the alignment (Qt::Alignment) of the icon in the header.
+ \li iconAlignment
+ \li the alignment (Qt::Alignment) of the icon in the header.
\row
- \o orientation
- \o a Qt::Orientation value deciding whether the header
+ \li orientation
+ \li a Qt::Orientation value deciding whether the header
is the horizontal header above the view or the
vertical header on the left.
\row
- \o position
- \o a QStyleOptionHeader::SectionPosition value
+ \li position
+ \li a QStyleOptionHeader::SectionPosition value
giving the header section's position relative to
the other sections.
\row
- \o section
- \o holds the section that is being drawn.
+ \li section
+ \li holds the section that is being drawn.
\row
- \o selectedPosition
- \o a QStyleOptionHeader::SelectedPosition value giving
+ \li selectedPosition
+ \li a QStyleOptionHeader::SelectedPosition value giving
the selected section's position relative to the
section that is being painted.
\row
- \o sortIndicator
- \o a QStyleOptionHeader::SortIndicator value that
+ \li sortIndicator
+ \li a QStyleOptionHeader::SortIndicator value that
describes the direction in which the section's sort
indicator should be drawn.
\row
- \o text
- \o the text of the currently drawn section.
+ \li text
+ \li the text of the currently drawn section.
\row
- \o textAlignment
- \o the Qt::Alignment of the text within the
+ \li textAlignment
+ \li the Qt::Alignment of the text within the
headersection.
\endtable
@@ -1927,22 +1927,22 @@
\table 90%
\header
- \o State
- \o Set When
+ \li State
+ \li Set When
\row
- \o State_Sibling
- \o the node in the tree has a sibling (i.e., there is
+ \li State_Sibling
+ \li the node in the tree has a sibling (i.e., there is
another node in the same column).
\row
- \o State_Item
- \o this branch indicator has an item.
+ \li State_Item
+ \li this branch indicator has an item.
\row
- \o State_Children
- \o the branch has children (i.e., a new sub-tree can
+ \li State_Children
+ \li the branch has children (i.e., a new sub-tree can
be opened at the branch).
\row
- \o State_Open
- \o the branch indicator has an opened sub-tree.
+ \li State_Open
+ \li the branch indicator has an opened sub-tree.
\endtable
The tree view (and tree widget) use the style to draw the branches
@@ -1986,14 +1986,14 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o icon
- \o the icon on the toolbox tab
+ \li icon
+ \li the icon on the toolbox tab
\row
- \o text
- \o the text on the toolbox tab
+ \li text
+ \li the text on the toolbox tab
\endtable
\section3 Size Grip
@@ -2014,11 +2014,11 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o corner
- \o a Qt::Corner value that describe which corner in a
+ \li corner
+ \li a Qt::Corner value that describe which corner in a
window (or equivalent) the grip is located.
\endtable
@@ -2038,15 +2038,15 @@
\table
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o opaque
- \o boolean that is true if the rubber band must be
+ \li opaque
+ \li boolean that is true if the rubber band must be
drawn in an opaque style (i.e., color)
\row
- \o shape
- \o a QRubberBand::Shape enum value that holds the
+ \li shape
+ \li a QRubberBand::Shape enum value that holds the
shape of the band (which is either a rectangle or a
line)
\endtable
@@ -2076,24 +2076,24 @@
\table 90%
\header
- \o Member
- \o Content
+ \li Member
+ \li Content
\row
- \o closeable
- \o boolean that holds whether the dock window can be
+ \li closeable
+ \li boolean that holds whether the dock window can be
closed
\row
- \o floatable
- \o boolean that holds whether the dock window can
+ \li floatable
+ \li boolean that holds whether the dock window can
float (i.e., detach from the main window in which
it lives)
\row
- \o movable
- \o boolean that holds whether the window is movable
+ \li movable
+ \li boolean that holds whether the window is movable
(i.e., can move to other dock widget areas)
\row
- \o title
- \o the title text of the dock window
+ \li title
+ \li the title text of the dock window
\endtable
For the buttons, QStyleOptionButton is used (see \l{Tool Buttons}
diff --git a/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc b/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc
index a0a8652eaf2..eaedb847c88 100644
--- a/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/stylesheet.qdoc
@@ -51,12 +51,12 @@
Topics:
\list
- \i \l{Overview}
- \i \l{The Style Sheet Syntax}
- \i \l{Qt Designer Integration}
- \i \l{Customizing Qt Widgets Using Style Sheets}
- \i \l{Qt Style Sheets Reference}
- \i \l{Qt Style Sheets Examples}
+ \li \l{Overview}
+ \li \l{The Style Sheet Syntax}
+ \li \l{Qt Designer Integration}
+ \li \l{Customizing Qt Widgets Using Style Sheets}
+ \li \l{Qt Style Sheets Reference}
+ \li \l{Qt Style Sheets Examples}
\endlist
\target overview
@@ -111,17 +111,17 @@
will.
\table
- \row \o \inlineimage stylesheet-coffee-xp.png
- \o \inlineimage stylesheet-pagefold.png
- \row \o Coffee theme running on Windows XP
- \o Pagefold theme running on Windows XP
+ \row \li \inlineimage stylesheet-coffee-xp.png
+ \li \inlineimage stylesheet-pagefold.png
+ \row \li Coffee theme running on Windows XP
+ \li Pagefold theme running on Windows XP
\endtable
\table
- \row \o \inlineimage stylesheet-coffee-cleanlooks.png
- \o \inlineimage stylesheet-pagefold-mac.png
- \row \o Coffee theme running on Ubuntu Linux
- \o Pagefold theme running on Mac OS X
+ \row \li \inlineimage stylesheet-coffee-cleanlooks.png
+ \li \inlineimage stylesheet-pagefold-mac.png
+ \row \li Coffee theme running on Ubuntu Linux
+ \li Pagefold theme running on Mac OS X
\endtable
When a style sheet is active, the QStyle returned by QWidget::style()
@@ -199,24 +199,24 @@
\table 100%
\header
- \o Selector
- \o Example
- \o Explanation
+ \li Selector
+ \li Example
+ \li Explanation
\row
- \o Universal Selector
- \o \c *
- \o Matches all widgets.
+ \li Universal Selector
+ \li \c *
+ \li Matches all widgets.
\row
- \o Type Selector
- \o \c QPushButton
- \o Matches instances of QPushButton and of its subclasses.
+ \li Type Selector
+ \li \c QPushButton
+ \li Matches instances of QPushButton and of its subclasses.
\row
- \o Property Selector
- \o \c{QPushButton[flat="false"]}
- \o Matches instances of QPushButton that are not
+ \li Property Selector
+ \li \c{QPushButton[flat="false"]}
+ \li Matches instances of QPushButton that are not
\l{QPushButton::}{flat}. You may use this selector to test
for any Qt \l{Qt's Property System}{property} that supports
QVariant::toString() (see the \l{QVariant::}{toString()}
@@ -237,29 +237,29 @@
unset the style sheet and set it again.
\row
- \o Class Selector
- \o \c .QPushButton
- \o Matches instances of QPushButton, but not of its subclasses.
+ \li Class Selector
+ \li \c .QPushButton
+ \li Matches instances of QPushButton, but not of its subclasses.
This is equivalent to \c{*[class~="QPushButton"]}.
\row
- \o ID \target ID Selector
+ \li ID \target ID Selector
Selector
- \o \c{QPushButton#okButton}
- \o Matches all QPushButton instances whose
+ \li \c{QPushButton#okButton}
+ \li Matches all QPushButton instances whose
\l{QObject::objectName}{object name} is \c okButton.
\row
- \o Descendant Selector
- \o \c{QDialog QPushButton}
- \o Matches all instances of QPushButton that are descendants
+ \li Descendant Selector
+ \li \c{QDialog QPushButton}
+ \li Matches all instances of QPushButton that are descendants
(children, grandchildren, etc.) of a QDialog.
\row
- \o Child Selector
- \o \c{QDialog > QPushButton}
- \o Matches all instances of QPushButton that are direct
+ \li Child Selector
+ \li \c{QDialog > QPushButton}
+ \li Matches all instances of QPushButton that are direct
children of a QDialog.
\endtable
@@ -329,7 +329,7 @@
Sub-Control} for a realistic example.
\note With complex widgets such as QComboBox and QScrollBar, if one
- property or sub-control is customized, \bold{all} the other properties or
+ property or sub-control is customized, \b{all} the other properties or
sub-controls must be customized as well.
\section1 Pseudo-States
@@ -436,10 +436,10 @@
\e{A selector's specificity is calculated as follows:}
\list
- \o \e{count the number of ID attributes in the selector (= a)}
- \o \e{count the number of other attributes and pseudo-classes in the selector (= b)}
- \o \e{count the number of element names in the selector (= c)}
- \o \e{ignore pseudo-elements [i.e., \l{subcontrols}].}
+ \li \e{count the number of ID attributes in the selector (= a)}
+ \li \e{count the number of other attributes and pseudo-classes in the selector (= b)}
+ \li \e{count the number of element names in the selector (= c)}
+ \li \e{ignore pseudo-elements [i.e., \l{subcontrols}].}
\endlist
\e{Concatenating the three numbers a-b-c (in a number system with a
@@ -495,7 +495,7 @@
In classic CSS, when font and color of an item is not explicitly set,
it gets automatically inherited from the parent. When using Qt Style Sheets,
- a widget does \bold{not} automatically inherit its font and color setting
+ a widget does \b{not} automatically inherit its font and color setting
from its parent widget.
For example, consider a QPushButton inside a QGroupBox:
@@ -589,11 +589,11 @@
\image stylesheet-boxmodel.png
\list
- \o The margin falls outside the border.
- \o The border is drawn between the margin and the padding.
- \o The padding falls inside the border, between the border and
+ \li The margin falls outside the border.
+ \li The border is drawn between the margin and the padding.
+ \li The padding falls inside the border, between the border and
the actual contents.
- \o The content is what is left from the original widget or
+ \li The content is what is left from the original widget or
subcontrol once we have removed the margin, the border, and
the padding.
\endlist
@@ -636,10 +636,10 @@
The steps to render a rule are as follows:
\list
- \o Set clip for entire rendering operation (border-radius)
- \o Draw the background (background-image)
- \o Draw the border (border-image, border)
- \o Draw overlay image (image)
+ \li Set clip for entire rendering operation (border-radius)
+ \li Draw the background (background-image)
+ \li Draw the border (border-image, border)
+ \li Draw overlay image (image)
\endlist
\target sub controls
@@ -650,9 +650,9 @@
followed by the down-arrow sub-control. A QComboBox is thus rendered as
follows:
\list
- \o Render the QComboBox { } rule
- \o Render the QComboBox::drop-down { } rule
- \o Render the QComboBox::down-arrow { } rule
+ \li Render the QComboBox { } rule
+ \li Render the QComboBox::drop-down { } rule
+ \li Render the QComboBox::down-arrow { } rule
\endlist
Sub-controls share a parent-child relationship. In the case of QComboBox,
@@ -666,7 +666,7 @@
Once positioned, sub-controls can be styled using the \l{box model}.
\note With complex widgets such as QComboBox and QScrollBar, if one
- property or sub-control is customized, \bold{all} the other properties or
+ property or sub-control is customized, \b{all} the other properties or
sub-controls must be customized as well.
*/
@@ -691,12 +691,12 @@
\table 100%
\header
- \o Widget
- \o How to Style
+ \li Widget
+ \li How to Style
\row
- \o QAbstractScrollArea \target qabstractscrollarea-widget
- \o Supports the \l{box model}.
+ \li QAbstractScrollArea \target qabstractscrollarea-widget
+ \li Supports the \l{box model}.
All derivatives of QAbstractScrollArea, including QTextEdit,
and QAbstractItemView (all item view classes), support
@@ -711,8 +711,8 @@
{Customizing QAbstractScrollArea} for an example.
\row
- \o QCheckBox \target qcheckbox-widget
- \o Supports the \l{box model}. The check indicator can be
+ \li QCheckBox \target qcheckbox-widget
+ \li Supports the \l{box model}. The check indicator can be
styled using the \l{#indicator-sub}{::indicator}
subcontrol. By default, the indicator is placed in the Top
Left corner of the Contents rectangle of the widget.
@@ -725,15 +725,15 @@
{Customizing QCheckBox} for an example.
\row
- \o QColumnView \target qcolumnview-widget
- \o The grip can be styled be using the \l{image-prop}{image} property.
+ \li QColumnView \target qcolumnview-widget
+ \li The grip can be styled be using the \l{image-prop}{image} property.
The arrow indicators can by styled using the
\l{left-arrow-sub}{::left-arrow} subcontrol and the
\l{right-arrow-sub}{::right-arrow} subcontrol.
\row
- \o QComboBox \target qcombobox-widget
- \o The frame around the combobox can be styled using the
+ \li QComboBox \target qcombobox-widget
+ \li The frame around the combobox can be styled using the
\l{box model}. The drop-down button can be styled using
the \l{#drop-down-sub}{::drop-down} subcontrol. By default, the
drop-down button is placed in the top right corner of the padding
@@ -746,16 +746,16 @@
for an example.
\row
- \o QDateEdit \target qdateedit-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QDateEdit \target qdateedit-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QDateTimeEdit \target qdatetimeedit-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QDateTimeEdit \target qdatetimeedit-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QDialog \target qdialog-widget
- \o Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
+ \li QDialog \target qdialog-widget
+ \li Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
\l{#background-clip-prop}{background-clip} and
\l{#background-origin-prop}{background-origin} properties.
@@ -763,13 +763,13 @@
widget.
\row
- \o QDialogButtonBox \target qdialogbuttonbox-widget
- \o The layout of buttons can be altered using the
+ \li QDialogButtonBox \target qdialogbuttonbox-widget
+ \li The layout of buttons can be altered using the
\l{#button-layout-prop}{button-layout} property.
\row
- \o QDockWidget \target qdockwidget-widget
- \o Supports styling of the title bar and the title bar buttons when docked.
+ \li QDockWidget \target qdockwidget-widget
+ \li Supports styling of the title bar and the title bar buttons when docked.
The dock widget border can be styled using the \l{#border-prop}{border}
property. The \l{#title-sub}{::title} subcontrol can be used to customize
@@ -792,12 +792,12 @@
{Customizing QDockWidget} for an example.
\row
- \o QDoubleSpinBox \target qdoublespinbox-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QDoubleSpinBox \target qdoublespinbox-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QFrame \target qframe-widget
- \o Supports the \l{box model}.
+ \li QFrame \target qframe-widget
+ \li Supports the \l{box model}.
Since 4.3, setting a stylesheet on a QLabel automatically
sets the QFrame::frameStyle property to QFrame::StyledPanel.
@@ -806,8 +806,8 @@
for an example.
\row
- \o QGroupBox \target qgroupbox-widget
- \o Supports the \l{box model}. The title can be styled using the
+ \li QGroupBox \target qgroupbox-widget
+ \li Supports the \l{box model}. The title can be styled using the
\l{#title-sub}{::title} subcontrol. By default, the title is placed
depending on QGroupBox::textAlignment.
@@ -821,8 +821,8 @@
for an example.
\row
- \o QHeaderView \target qheaderview-widget
- \o Supports the \l{box model}. The sections of the header view are
+ \li QHeaderView \target qheaderview-widget
+ \li Supports the \l{box model}. The sections of the header view are
styled using the \l{#section-sub}{::section} sub control. The
\c{section} Sub-control supports the \l{#middle-ps}{:middle},
\l{#first-ps}{:first}, \l{#last-ps}{:last},
@@ -839,8 +839,8 @@
for an example.
\row
- \o QLabel \target qlabel-widget
- \o Supports the \l{box model}. Does not support the
+ \li QLabel \target qlabel-widget
+ \li Supports the \l{box model}. Does not support the
\l{#hover-ps}{:hover} pseudo-state.
Since 4.3, setting a stylesheet on a QLabel automatically
@@ -850,8 +850,8 @@
example (a QLabel derives from QFrame).
\row
- \o QLineEdit \target qlineedit-widget
- \o Support the \l{box model}.
+ \li QLineEdit \target qlineedit-widget
+ \li Support the \l{box model}.
The color and background of the selected item is styled using
\l{#selection-color-prop}{selection-color} and
@@ -866,8 +866,8 @@
for an example.
\row
- \o QListView \target qlistview-widget
- \o Supports the \l{box model}. When
+ \li QListView \target qlistview-widget
+ \li Supports the \l{box model}. When
\l{QAbstractItemView::alternatingRowColors}{alternating row colors}
is enabled, the alternating colors can be styled using the
\l{#alternate-background-color-prop}{alternate-background-color}
@@ -891,12 +891,12 @@
{Customzing QListView} for an example.
\row
- \o QListWidget \target qlistwidget-widget
- \o See \l{#qlistview-widget}{QListView}.
+ \li QListWidget \target qlistwidget-widget
+ \li See \l{#qlistview-widget}{QListView}.
\row
- \o QMainWindow \target qmainwindow-widget
- \o Supports styling of the separator
+ \li QMainWindow \target qmainwindow-widget
+ \li Supports styling of the separator
The separator in a QMainWindow when using QDockWidget is styled
using the \l{#separator-sub}{::separator} subcontrol.
@@ -905,8 +905,8 @@
for an example.
\row
- \o QMenu \target qmenu-widget
- \o Supports the \l{box model}.
+ \li QMenu \target qmenu-widget
+ \li Supports the \l{box model}.
Individual items are styled using the \l{#item-sub}{::item}
subcontrol. In addition to the usually supported pseudo states,
@@ -933,8 +933,8 @@
for an example.
\row
- \o QMenuBar \target qmenubar-widget
- \o Supports the \l{box model}. The \l{#spacing-prop}{spacing}
+ \li QMenuBar \target qmenubar-widget
+ \li Supports the \l{box model}. The \l{#spacing-prop}{spacing}
property specifies the spacing between menu items.
Individual items are styled using the \l{#item-sub}{::item}
subcontrol.
@@ -946,14 +946,14 @@
for an example.
\row
- \o QMessageBox \target qmessagebox-widget
- \o The \l{#messagebox-text-interaction-flags-prop}
+ \li QMessageBox \target qmessagebox-widget
+ \li The \l{#messagebox-text-interaction-flags-prop}
{messagebox-text-interaction-flags} property can be used to alter
the interaction with text in the message box.
\row
- \o QProgressBar \target qprogressbar-widget
- \o Supports the \l{box model}. The chunks of the progress bar
+ \li QProgressBar \target qprogressbar-widget
+ \li Supports the \l{box model}. The chunks of the progress bar
can be styled using the \l{#chunk-sub}{::chunk} subcontrol.
The chunk is displayed on the Contents rectangle of the widget.
@@ -967,8 +967,8 @@
for an example.
\row
- \o QPushButton \target qpushbutton-widget
- \o Supports the \l{box model}. Supports the \l{#default-ps}{:default},
+ \li QPushButton \target qpushbutton-widget
+ \li Supports the \l{box model}. Supports the \l{#default-ps}{:default},
\l{#flat-ps}{:flat}, \l{#checked-ps}{:checked} pseudo states.
For QPushButton with a menu, the menu indicator is styled
@@ -988,8 +988,8 @@
for an example.
\row
- \o QRadioButton \target qradiobutton-widget
- \o Supports the \l{box model}. The check indicator can be
+ \li QRadioButton \target qradiobutton-widget
+ \li Supports the \l{box model}. The check indicator can be
styled using the \l{#indicator-sub}{::indicator}
subcontrol. By default, the indicator is placed in the Top
Left corner of the Contents rectangle of the widget.
@@ -1002,8 +1002,8 @@
{Customizing QRadioButton} for an example.
\row
- \o QScrollBar \target qscrollbar-widget
- \o Supports the \l{box model}. The Contents rectangle of the widget
+ \li QScrollBar \target qscrollbar-widget
+ \li Supports the \l{box model}. The Contents rectangle of the widget
is considered to be the groove over which the slider moves. The extent
of the QScrollBar (i.e the width or the height depending on the orientation)
is set using the \l{#width-prop}{width} or \l{#height-prop}{height} property
@@ -1037,8 +1037,8 @@
for an example.
\row
- \o QSizeGrip \target qsizegrip-widget
- \o Supports the \l{#width-prop}{width},
+ \li QSizeGrip \target qsizegrip-widget
+ \li Supports the \l{#width-prop}{width},
\l{#height-prop}{height}, and \l{#image-prop}{image}
properties.
@@ -1046,8 +1046,8 @@
for an example.
\row
- \o QSlider \target qslider-widget
- \o Supports the \l{box model}. For horizontal slides, the
+ \li QSlider \target qslider-widget
+ \li Supports the \l{box model}. For horizontal slides, the
\l{min-width-prop}{min-width} and \l{height-prop}{height}
properties must be provided. For vertical sliders, the
\l{min-height-prop}{min-height} and \l{width-prop}{width}
@@ -1064,8 +1064,8 @@
for an example.
\row
- \o QSpinBox \target qspinbox-widget
- \o The frame of the spin box can be styled using the \l{box
+ \li QSpinBox \target qspinbox-widget
+ \li The frame of the spin box can be styled using the \l{box
model}.
The up button and arrow can be styled using the
@@ -1090,16 +1090,16 @@
for an example.
\row
- \o QSplitter \target qsplitter-widget
- \o Supports the \l{box model}. The handle of the splitter
+ \li QSplitter \target qsplitter-widget
+ \li Supports the \l{box model}. The handle of the splitter
is styled using the \l{#handle-sub}{::handle} subcontrol.
See \l{Qt Style Sheets Examples#Customizing QSplitter}{Customizing QSplitter}
for an example.
\row
- \o QStatusBar \target qstatusbar-widget
- \o Supports only the \l{Qt Style Sheets Reference#background-prop}
+ \li QStatusBar \target qstatusbar-widget
+ \li Supports only the \l{Qt Style Sheets Reference#background-prop}
{background} property.
The frame for individual items can be style using the
\l{#item-sub}{::item} subcontrol.
@@ -1108,8 +1108,8 @@
for an example.
\row
- \o QTabBar \target qtabbar-widget
- \o Individual tabs may be styled using the \l{#tab-sub}{::tab} subcontrol.
+ \li QTabBar \target qtabbar-widget
+ \li Individual tabs may be styled using the \l{#tab-sub}{::tab} subcontrol.
Close buttons using the \l{#close-button-sub}{::close-button}
The tabs support the
\l{#only-one-ps}{:only-one}, \l{#first-ps}{:first},
@@ -1143,8 +1143,8 @@
for an example.
\row
- \o QTabWidget \target qtabwidget-widget
- \o The frame of the tab widget is styled using the
+ \li QTabWidget \target qtabwidget-widget
+ \li The frame of the tab widget is styled using the
\l{#pane-sub}{::pane} subcontrol. The left and right
corners are styled using the \l{#left-corner-sub}{::left-corner}
and \l{#right-corner-sub}{::right-corner} respectively.
@@ -1163,8 +1163,8 @@
{Customizing QTabWidget} for an example.
\row
- \o QTableView \target qtableview-widget
- \o Supports the \l{box model}. When
+ \li QTableView \target qtableview-widget
+ \li Supports the \l{box model}. When
\l{QAbstractItemView::alternatingRowColors}{alternating row colors}
is enabled, the alternating colors can be styled using the
\l{#alternate-background-color-prop}{alternate-background-color}
@@ -1194,12 +1194,12 @@
{Customzing QTableView} for an example.
\row
- \o QTableWidget \target qtablewidget-widget
- \o See \l{#qtableview-widget}{QTableView}.
+ \li QTableWidget \target qtablewidget-widget
+ \li See \l{#qtableview-widget}{QTableView}.
\row
- \o QTextEdit \target qtextedit-widget
- \o Supports the \l{box model}.
+ \li QTextEdit \target qtextedit-widget
+ \li Supports the \l{box model}.
The color and background of selected text is styled using
\l{#selection-color-prop}{selection-color} and
@@ -1210,12 +1210,12 @@
style scrollable backgrounds.
\row
- \o QTimeEdit \target qtimeedit-widget
- \o See \l{#qspinbox-widget}{QSpinBox}.
+ \li QTimeEdit \target qtimeedit-widget
+ \li See \l{#qspinbox-widget}{QSpinBox}.
\row
- \o QToolBar \target qtoolbar-widget
- \o Supports the \l{box model}.
+ \li QToolBar \target qtoolbar-widget
+ \li Supports the \l{box model}.
The \l{#top-ps}{:top}, \l{#left-ps}{:left}, \l{#right-ps}{:right},
\l{#bottom-ps}{:bottom} pseudo states depending on the area in
@@ -1236,8 +1236,8 @@
for an example.
\row
- \o QToolButton \target qtoolbutton-widget
- \o Supports the \l{box model}.
+ \li QToolButton \target qtoolbutton-widget
+ \li Supports the \l{box model}.
If the QToolButton has a menu, is
\l{#menu-indicator-sub}{::menu-indicator} subcontrol can be used to
@@ -1266,8 +1266,8 @@
for an example.
\row
- \o QToolBox \target qtoolbox-widget
- \o Supports the \l{box model}.
+ \li QToolBox \target qtoolbox-widget
+ \li Supports the \l{box model}.
The individual tabs can by styled using the
\l{#tab-sub}{::tab} subcontrol. The tabs support the
@@ -1278,16 +1278,16 @@
\l{#selected-ps}{:selected} pseudo states.
\row
- \o QToolTip \target qtooltip-widget
- \o Supports the \l{box model}. The \l{#opacity-prop}{opacity}
+ \li QToolTip \target qtooltip-widget
+ \li Supports the \l{box model}. The \l{#opacity-prop}{opacity}
property controls the opacity of the tooltip.
See \l{Qt Style Sheets Examples#Customizing QFrame}{Customizing QFrame}
for an example (a QToolTip is a QFrame).
\row
- \o QTreeView \target qtreeview-widget
- \o Supports the \l{box model}. When
+ \li QTreeView \target qtreeview-widget
+ \li Supports the \l{box model}. When
\l{QAbstractItemView::alternatingRowColors}{alternating row colors}
is enabled, the alternating colors can be styled using the
\l{#alternate-background-color-prop}{alternate-background-color}
@@ -1317,12 +1317,12 @@
for an example to style the branches.
\row
- \o QTreeWidget \target qtreewidget-widget
- \o See \l{#qtreeview-widget}{QTreeView}.
+ \li QTreeWidget \target qtreewidget-widget
+ \li See \l{#qtreeview-widget}{QTreeView}.
\row
- \o QWidget \target qwidget-widget
- \o Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
+ \li QWidget \target qwidget-widget
+ \li Supports only the \l{Qt Style Sheets Reference#background-prop}{background},
\l{#background-clip-prop}{background-clip} and
\l{#background-origin-prop}{background-origin} properties.
@@ -1348,14 +1348,14 @@
\table 100%
\header
- \o Property
- \o Type
- \o Description
+ \li Property
+ \li Type
+ \li Description
\row
- \o \bold{\c alternate-background-color} \target alternate-background-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The \l{QAbstractItemView::alternatingRowColors}
+ \li \b{\c alternate-background-color} \target alternate-background-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The \l{QAbstractItemView::alternatingRowColors}
{alternate background color} used in QAbstractItemView subclasses.
If this property is not set, the default value is
@@ -1370,9 +1370,9 @@
\l{#selection-background-color-prop}{selection-background-color}.
\row
- \o \bold{\c background} \target background-prop
- \o \l{#Background}{Background}
- \o Shorthand notation for setting the background. Equivalent
+ \li \b{\c background} \target background-prop
+ \li \l{#Background}{Background}
+ \li Shorthand notation for setting the background. Equivalent
to specifying \c background-color, \c background-image, \c
background-repeat, and/or \c background-position.
@@ -1404,18 +1404,18 @@
and \l{#alternate-background-color-prop}{alternate-background-color}.
\row
- \o \c background-color \target background-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The background color used for the widget.
+ \li \c background-color \target background-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The background color used for the widget.
Examples:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 36
\row
- \o \c background-image \target background-image-prop
- \o \l{#Url}{Url}
- \o The background image used for the widget. Semi-transparent
+ \li \c background-image \target background-image-prop
+ \li \l{#Url}{Url}
+ \li The background image used for the widget. Semi-transparent
parts of the image let the \c background-color shine
through.
@@ -1424,9 +1424,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 37
\row
- \o \c background-repeat \target background-repeat-prop
- \o \l{#Repeat}{Repeat}
- \o Whether and how the background image is repeated to fill
+ \li \c background-repeat \target background-repeat-prop
+ \li \l{#Repeat}{Repeat}
+ \li Whether and how the background image is repeated to fill
the \c background-origin rectangle.
If this property is not specified, the background image
@@ -1437,9 +1437,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 38
\row
- \o \c background-position
- \o \l{#Alignment}{Alignment}
- \o The alignment of the background image within the \c
+ \li \c background-position
+ \li \l{#Alignment}{Alignment}
+ \li The alignment of the background image within the \c
background-origin rectangle.
If this property is not specified, the alignment is \c
@@ -1450,9 +1450,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 39
\row
- \o \bold{\c background-attachment} \target background-attachment-prop
- \o \l{#Attachment}{Attachment}
- \o Determines whether the background-image in a QAbstractScrollArea
+ \li \b{\c background-attachment} \target background-attachment-prop
+ \li \l{#Attachment}{Attachment}
+ \li Determines whether the background-image in a QAbstractScrollArea
is scrolled or fixed with respect to the viewport.
By default, the background-image scrolls with the viewport.
@@ -1463,9 +1463,9 @@
See also \l{Qt Style Sheets Reference#background-prop}{background}
\row
- \o \bold{\c background-clip} \target background-clip-prop
- \o \l{#Origin}{Origin}
- \o The widget's rectangle, in which the \c background is drawn.
+ \li \b{\c background-clip} \target background-clip-prop
+ \li \l{#Origin}{Origin}
+ \li The widget's rectangle, in which the \c background is drawn.
This property specifies the rectangle to which the \c background-color
and \c background-image are clipped.
@@ -1487,9 +1487,9 @@
\l{#background-origin-prop}{background-origin} and \l{The Box Model}.
\row
- \o \bold{\c background-origin} \target background-origin-prop
- \o \l{#Origin}{Origin}
- \o The widget's background rectangle, to use in conjunction
+ \li \b{\c background-origin} \target background-origin-prop
+ \li \l{#Origin}{Origin}
+ \li The widget's background rectangle, to use in conjunction
with \c background-position and \c background-image.
This property is supported by QAbstractItemView
@@ -1509,9 +1509,9 @@
\l{The Box Model}.
\row
- \o \bold{\c border} \target border-prop
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's border. Equivalent
+ \li \b{\c border} \target border-prop
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's border. Equivalent
to specifying \c border-color, \c border-style, and/or
\c border-width.
@@ -1526,38 +1526,38 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 43
\row
- \o \c border-top
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's top border.
+ \li \c border-top
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's top border.
Equivalent to specifying \c border-top-color, \c
border-top-style, and/or \c border-top-width.
\row
- \o \c border-right
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's right border.
+ \li \c border-right
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's right border.
Equivalent to specifying \c border-right-color, \c
border-right-style, and/or \c border-right-width.
\row
- \o \c border-bottom
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's bottom border.
+ \li \c border-bottom
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's bottom border.
Equivalent to specifying \c border-bottom-color, \c
border-bottom-style, and/or \c border-bottom-width.
\row
- \o \c border-left
- \o \l{#Border}{Border}
- \o Shorthand notation for setting the widget's left border.
+ \li \c border-left
+ \li \l{#Border}{Border}
+ \li Shorthand notation for setting the widget's left border.
Equivalent to specifying \c border-left-color, \c
border-left-style, and/or \c border-left-width.
\row
- \o \bold{\c border-color} \target border-attrs
+ \li \b{\c border-color} \target border-attrs
\target border-color-prop
- \o \l{#Box Colors}{Box Colors}
- \o The color of all the border's edges. Equivalent to
+ \li \l{#Box Colors}{Box Colors}
+ \li The color of all the border's edges. Equivalent to
specifying \c border-top-color, \c border-right-color, \c
border-bottom-color, and \c border-left-color.
@@ -1580,29 +1580,29 @@
\l{#border-image-prop}{border-image}, and \l{The Box Model}.
\row
- \o \c border-top-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's top edge.
+ \li \c border-top-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's top edge.
\row
- \o \c border-right-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's right edge.
+ \li \c border-right-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's right edge.
\row
- \o \c border-bottom-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's bottom edge.
+ \li \c border-bottom-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's bottom edge.
\row
- \o \c border-left-color
- \o \l{#Brush}{Brush} \BR
- \o The color of the border's left edge.
+ \li \c border-left-color
+ \li \l{#Brush}{Brush} \BR
+ \li The color of the border's left edge.
\row
- \o \bold{\c border-image} \target border-image-prop
- \o \l{#Border Image}{Border Image}
- \o The image used to fill the border. The image is cut into
+ \li \b{\c border-image} \target border-image-prop
+ \li \l{#Border Image}{Border Image}
+ \li The image used to fill the border. The image is cut into
nine parts and stretched appropriately if necessary. See
\l{#Border Image}{Border Image} for details.
@@ -1618,9 +1618,9 @@
\l{The Box Model}.
\row
- \o \bold{\c border-radius} \target border-radius-prop
- \o \l{#Radius}{Radius}
- \o The radius of the border's corners. Equivalent to
+ \li \b{\c border-radius} \target border-radius-prop
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's corners. Equivalent to
specifying \c border-top-left-radius, \c
border-top-right-radius, \c border-bottom-right-radius,
and \c border-bottom-left-radius.
@@ -1644,32 +1644,32 @@
\l{The Box Model}.
\row
- \o \c border-top-left-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's top-left corner.
+ \li \c border-top-left-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's top-left corner.
\row
- \o \c border-top-right-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's top-right corner.
+ \li \c border-top-right-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's top-right corner.
\row
- \o \c border-bottom-right-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's bottom-right corner. Setting
+ \li \c border-bottom-right-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's bottom-right corner. Setting
this property to a positive value results in a rounded
corner.
\row
- \o \c border-bottom-left-radius
- \o \l{#Radius}{Radius}
- \o The radius of the border's bottom-left corner. Setting this
+ \li \c border-bottom-left-radius
+ \li \l{#Radius}{Radius}
+ \li The radius of the border's bottom-left corner. Setting this
property to a positive value results in a rounded corner.
\row
- \o \bold{\c border-style} \target border-style-prop
- \o \l {Border Style}
- \o The style of all the border's edges.
+ \li \b{\c border-style} \target border-style-prop
+ \li \l {Border Style}
+ \li The style of all the border's edges.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -1688,29 +1688,29 @@
\l{#border-image-prop}{border-image}, and \l{The Box Model}.
\row
- \o \c border-top-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's top edge.
+ \li \c border-top-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's top edge.
\row
- \o \c border-right-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's right edge/
+ \li \c border-right-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's right edge/
\row
- \o \c border-bottom-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's bottom edge.
+ \li \c border-bottom-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's bottom edge.
\row
- \o \c border-left-style
- \o \l{#Border Style}{Border Style}
- \o The style of the border's left edge.
+ \li \c border-left-style
+ \li \l{#Border Style}{Border Style}
+ \li The style of the border's left edge.
\row
- \o \bold{\c border-width} \target border-width-prop
- \o \l{#Box Lengths}{Box Lengths}
- \o The width of the border. Equivalent to setting \c
+ \li \b{\c border-width} \target border-width-prop
+ \li \l{#Box Lengths}{Box Lengths}
+ \li The width of the border. Equivalent to setting \c
border-top-width, \c border-right-width, \c
border-bottom-width, and \c border-left-width.
@@ -1731,29 +1731,29 @@
\l{The Box Model}.
\row
- \o \c border-top-width
- \o \l{#Length}{Length}
- \o The width of the border's top edge.
+ \li \c border-top-width
+ \li \l{#Length}{Length}
+ \li The width of the border's top edge.
\row
- \o \c border-right-width
- \o \l{#Length}{Length}
- \o The width of the border's right edge.
+ \li \c border-right-width
+ \li \l{#Length}{Length}
+ \li The width of the border's right edge.
\row
- \o \c border-bottom-width
- \o \l{#Length}{Length}
- \o The width of the border's bottom edge.
+ \li \c border-bottom-width
+ \li \l{#Length}{Length}
+ \li The width of the border's bottom edge.
\row
- \o \c border-left-width
- \o \l{#Length}{Length}
- \o The width of the border's left edge.
+ \li \c border-left-width
+ \li \l{#Length}{Length}
+ \li The width of the border's left edge.
\row
- \o \bold{\c bottom} \target bottom-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c bottom} \target bottom-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset up;
specifying \tt{bottom: \e{y}} is then equivalent to
specifying \tt{\l{Qt Style Sheets Reference#top-prop}{top}: -\e{y}}.
@@ -1772,9 +1772,9 @@
\l{Qt Style Sheets Reference#top-prop}{top}.
\row
- \o \bold{\c button-layout} \target button-layout-prop
- \o \l{#Number}{Number}
- \o The layout of buttons in a QDialogButtonBox or
+ \li \b{\c button-layout} \target button-layout-prop
+ \li \l{#Number}{Number}
+ \li The layout of buttons in a QDialogButtonBox or
a QMessageBox. The possible values are 0
(\l{QDialogButtonBox::}{WinLayout}), 1
(\l{QDialogButtonBox::}{MacLayout}), 2
@@ -1790,9 +1790,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 49
\row
- \o \bold{\c color} \target color-prop
- \o \l{#Brush}{Brush} \BR
- \o The color used to render text.
+ \li \b{\c color} \target color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The color used to render text.
This property is supported by all widgets that respect
the \l QWidget::palette.
@@ -1809,9 +1809,9 @@
\l{#selection-color-prop}{selection-color}.
\row
- \o \bold{\c dialogbuttonbox-buttons-have-icons}
- \o \l{#Boolean}{Boolean}
- \o Whether the buttons in a QDialogButtonBox show icons
+ \li \b{\c dialogbuttonbox-buttons-have-icons}
+ \li \l{#Boolean}{Boolean}
+ \li Whether the buttons in a QDialogButtonBox show icons
If this property is set to 1, the buttons of a QDialogButtonBox
show icons; if it is set to 0, the icons are not shown.
@@ -1827,9 +1827,9 @@
\omit
\row
- \o \bold{\c etch-disabled-text}*
- \o \l{#Boolean}{Boolean}
- \o Whether disabled text is drawn etched.
+ \li \b{\c etch-disabled-text}*
+ \li \l{#Boolean}{Boolean}
+ \li Whether disabled text is drawn etched.
If this property is not specified, it defaults to the
value specified by the current style for the
@@ -1841,9 +1841,9 @@
\endomit
\row
- \o \bold{\c font} \target font-prop
- \o \l{#Font}{Font}
- \o Shorthand notation for setting the text's font. Equivalent
+ \li \b{\c font} \target font-prop
+ \li \l{#Font}{Font}
+ \li Shorthand notation for setting the text's font. Equivalent
to specifying \c font-family, \c font-size, \c font-style,
and/or \c font-weight.
@@ -1858,18 +1858,18 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 53
\row
- \o \c font-family
- \o String
- \o The font family.
+ \li \c font-family
+ \li String
+ \li The font family.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 54
\row
- \o \c font-size
- \o \l{#Font Size}{Font Size}
- \o The font size. In this version of Qt, only pt and px metrics are
+ \li \c font-size
+ \li \l{#Font Size}{Font Size}
+ \li The font size. In this version of Qt, only pt and px metrics are
supported.
Example:
@@ -1877,23 +1877,23 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 55
\row
- \o \c font-style
- \o \l {Font Style}
- \o The font style.
+ \li \c font-style
+ \li \l {Font Style}
+ \li The font style.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 56
\row
- \o \c font-weight
- \o \l{#Font Weight}{Font Weight}
- \o The weight of the font.
+ \li \c font-weight
+ \li \l{#Font Weight}{Font Weight}
+ \li The weight of the font.
\row
- \o \bold{\c gridline-color}* \target gridline-color-prop
- \o \l{#Color}{Color} \BR
- \o The color of the grid line in a QTableView.
+ \li \b{\c gridline-color}* \target gridline-color-prop
+ \li \l{#Color}{Color} \BR
+ \li The color of the grid line in a QTableView.
If this property is not specified, it defaults to the
value specified by the current style for the
@@ -1904,9 +1904,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 57
\row
- \o \bold{\c height} \target height-prop
- \o \l{#Length}{Length}
- \o The height of a \l{subcontrol} (or in some case, a widget).
+ \li \b{\c height} \target height-prop
+ \li \l{#Length}{Length}
+ \li The height of a \l{subcontrol} (or in some case, a widget).
If this property is not specified, it defaults to a value
that depends on the subcontrol/widget and on the current style.
@@ -1923,27 +1923,27 @@
See also \l{#width-prop}{width}.
\row
- \o \bold{\c icon-size} \target icon-size-prop
- \o \l{#Length}{Length}
- \o The width and height of the icon in a widget.
+ \li \b{\c icon-size} \target icon-size-prop
+ \li \l{#Length}{Length}
+ \li The width and height of the icon in a widget.
The icon size of the following widgets can be set using this
property.
\list
- \i QCheckBox
- \i QListView
- \i QPushButton
- \i QRadioButton
- \i QTabBar
- \i QToolBar
- \i QToolBox
- \i QTreeView
+ \li QCheckBox
+ \li QListView
+ \li QPushButton
+ \li QRadioButton
+ \li QTabBar
+ \li QToolBar
+ \li QToolBox
+ \li QTreeView
\endlist
\row
- \o \bold{\c image}* \target image-prop
- \o \l{#Url}{Url}+
- \o The image that is drawn in the contents rectangle of a
+ \li \b{\c image}* \target image-prop
+ \li \l{#Url}{Url}+
+ \li The image that is drawn in the contents rectangle of a
\l{subcontrol}.
The image property accepts a list of \l{#Url}{Url}s or
@@ -1969,15 +1969,15 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 59
\row
- \o \bold{\c image-position} \target image-position-prop
- \o \l{#Alignment}{alignment}
- \o In Qt 4.3 and later, the alignment of the image image's position can be specified
+ \li \b{\c image-position} \target image-position-prop
+ \li \l{#Alignment}{alignment}
+ \li In Qt 4.3 and later, the alignment of the image image's position can be specified
using relative or absolute position.
\row
- \o \bold{\c left} \target left-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c left} \target left-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset to
the right.
@@ -1996,9 +1996,9 @@
\l{#bottom-prop}{bottom}.
\row
- \o \bold{\c lineedit-password-character*} \target lineedit-password-character-prop
- \o \l{#Number}{Number}
- \o The QLineEdit password character as a Unicode number.
+ \li \b{\c lineedit-password-character*} \target lineedit-password-character-prop
+ \li \l{#Number}{Number}
+ \li The QLineEdit password character as a Unicode number.
If this property is not specified, it defaults to the
value specified by the current style for the
@@ -2009,9 +2009,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 61
\row
- \o \bold{\c margin} \target margin-prop
- \o \l {Box Lengths}
- \o The widget's margins. Equivalent to specifying \c
+ \li \b{\c margin} \target margin-prop
+ \li \l {Box Lengths}
+ \li The widget's margins. Equivalent to specifying \c
margin-top, \c margin-right, \c margin-bottom, and \c
margin-left.
@@ -2031,29 +2031,29 @@
\l{#spacing-prop}{spacing}, and \l{The Box Model}.
\row
- \o \c margin-top
- \o \l{#Length}{Length}
- \o The widget's top margin.
+ \li \c margin-top
+ \li \l{#Length}{Length}
+ \li The widget's top margin.
\row
- \o \c margin-right
- \o \l{#Length}{Length}
- \o The widget's right margin.
+ \li \c margin-right
+ \li \l{#Length}{Length}
+ \li The widget's right margin.
\row
- \o \c margin-bottom
- \o \l{#Length}{Length}
- \o The widget's bottom margin.
+ \li \c margin-bottom
+ \li \l{#Length}{Length}
+ \li The widget's bottom margin.
\row
- \o \c margin-left
- \o \l{#Length}{Length}
- \o The widget's left margin.
+ \li \c margin-left
+ \li \l{#Length}{Length}
+ \li The widget's left margin.
\row
- \o \bold{\c max-height} \target max-height-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's maximum height.
+ \li \b{\c max-height} \target max-height-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's maximum height.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2071,9 +2071,9 @@
See also \l{#max-width-prop}{max-width}.
\row
- \o \bold{\c max-width} \target max-width-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's maximum width.
+ \li \b{\c max-width} \target max-width-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's maximum width.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2092,9 +2092,9 @@
\row
- \o \bold{\c messagebox-text-interaction-flags*} \target messagebox-text-interaction-flags-prop
- \o \l{#Number}{Number}
- \o The interaction behavior for text in a message box.
+ \li \b{\c messagebox-text-interaction-flags*} \target messagebox-text-interaction-flags-prop
+ \li \l{#Number}{Number}
+ \li The interaction behavior for text in a message box.
Possible values are based on Qt::TextInteractionFlags.
If this property is not specified, it defaults to the
@@ -2107,9 +2107,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 65
\row
- \o \bold{\c min-height} \target min-height-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's minimum height.
+ \li \b{\c min-height} \target min-height-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's minimum height.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2130,9 +2130,9 @@
See also \l{#min-width-prop}{min-width}.
\row
- \o \bold{\c min-width} \target min-width-prop
- \o \l{#Length}{Length}
- \o The widget's or a subcontrol's minimum width.
+ \li \b{\c min-width} \target min-width-prop
+ \li \l{#Length}{Length}
+ \li The widget's or a subcontrol's minimum width.
This property is supported by QAbstractItemView
subclasses, QAbstractSpinBox subclasses, QCheckBox,
@@ -2153,9 +2153,9 @@
See also \l{#min-height-prop}{min-height}.
\row
- \o \bold{\c opacity*} \target opacity-prop
- \o \l{#Number}{Number}
- \o The opacity for a widget. Possible values are from 0
+ \li \b{\c opacity*} \target opacity-prop
+ \li \l{#Number}{Number}
+ \li The opacity for a widget. Possible values are from 0
(transparent) to 255 (opaque). For the moment, this is
only supported for \l{QToolTip}{tooltips}.
@@ -2168,9 +2168,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 68
\row
- \o \bold{\c padding} \target padding-prop
- \o \l{#Box Lengths}{Box Lengths}
- \o The widget's padding. Equivalent to specifying \c
+ \li \b{\c padding} \target padding-prop
+ \li \l{#Box Lengths}{Box Lengths}
+ \li The widget's padding. Equivalent to specifying \c
padding-top, \c padding-right, \c padding-bottom, and \c
padding-left.
@@ -2190,37 +2190,37 @@
\l{#spacing-prop}{spacing}, and \l{The Box Model}.
\row
- \o \c padding-top
- \o \l{#Length}{Length}
- \o The widget's top padding.
+ \li \c padding-top
+ \li \l{#Length}{Length}
+ \li The widget's top padding.
\row
- \o \c padding-right
- \o \l{#Length}{Length}
- \o The widget's right padding.
+ \li \c padding-right
+ \li \l{#Length}{Length}
+ \li The widget's right padding.
\row
- \o \c padding-bottom
- \o \l{#Length}{Length}
- \o The widget's bottom padding.
+ \li \c padding-bottom
+ \li \l{#Length}{Length}
+ \li The widget's bottom padding.
\row
- \o \c padding-left
- \o \l{#Length}{Length}
- \o The widget's left padding.
+ \li \c padding-left
+ \li \l{#Length}{Length}
+ \li The widget's left padding.
\row
- \o \bold{\c paint-alternating-row-colors-for-empty-area}
+ \li \b{\c paint-alternating-row-colors-for-empty-area}
\target paint-alternating-row-colors-for-empty-area-prop
- \o \c bool
- \o Whether the QTreeView paints alternating row colors for the empty
+ \li \c bool
+ \li Whether the QTreeView paints alternating row colors for the empty
area (i.e the area where there are no items)
\row
- \o \bold{\c position} \target position-prop
- \o \c relative \BR
+ \li \b{\c position} \target position-prop
+ \li \c relative \BR
| \c absolute
- \o Whether offsets specified using \l{Qt Style Sheets Reference#left-prop}{left},
+ \li Whether offsets specified using \l{Qt Style Sheets Reference#left-prop}{left},
\l{#right-prop}{right}, \l{Qt Style Sheets Reference#top-prop}{top}, and
\l{#bottom-prop}{bottom} are relative or absolute
coordinates.
@@ -2229,9 +2229,9 @@
relative.
\row
- \o \bold{\c right} \target right-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c right} \target right-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset to
the left; specifying \tt{right: \e{x}} is then equivalent
to specifying \tt{\l{Qt Style Sheets Reference#left-prop}{left}: -\e{x}}.
@@ -2249,9 +2249,9 @@
\l{#bottom-prop}{bottom}.
\row
- \o \bold{\c selection-background-color*} \target selection-background-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The background of selected text or items.
+ \li \b{\c selection-background-color*} \target selection-background-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The background of selected text or items.
This property is supported by all widgets that respect
the \l QWidget::palette and that show selection text.
@@ -2268,9 +2268,9 @@
\l{Qt Style Sheets Reference#background-prop}{background}.
\row
- \o \bold{\c selection-color*} \target selection-color-prop
- \o \l{#Brush}{Brush} \BR
- \o The foreground of selected text or items.
+ \li \b{\c selection-color*} \target selection-color-prop
+ \li \l{#Brush}{Brush} \BR
+ \li The foreground of selected text or items.
This property is supported by all widgets that respect
the \l QWidget::palette and that show selection text.
@@ -2288,9 +2288,9 @@
and \l{#color-prop}{color}.
\row
- \o \bold{\c show-decoration-selected*} \target show-decoration-selected-prop
- \o \l{#Boolean}{Boolean}
- \o Controls whether selections in a QListView cover the
+ \li \b{\c show-decoration-selected*} \target show-decoration-selected-prop
+ \li \l{#Boolean}{Boolean}
+ \li Controls whether selections in a QListView cover the
entire row or just the extent of the text.
If this property is not specified, it defaults to the
@@ -2303,9 +2303,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 73
\row
- \o \bold{\c spacing*} \target spacing-prop
- \o \l{#Length}{Length}
- \o Internal spacing in the widget.
+ \li \b{\c spacing*} \target spacing-prop
+ \li \l{#Length}{Length}
+ \li Internal spacing in the widget.
This property is supported by QCheckBox, checkable
\l{QGroupBox}es, QMenuBar, and QRadioButton.
@@ -2321,9 +2321,9 @@
\l{#margin-prop}{margin}.
\row
- \o \bold{\c subcontrol-origin*} \target subcontrol-origin-prop
- \o \l{#Origin}{Origin}
- \o The origin rectangle of the \l subcontrol within the
+ \li \b{\c subcontrol-origin*} \target subcontrol-origin-prop
+ \li \l{#Origin}{Origin}
+ \li The origin rectangle of the \l subcontrol within the
parent element.
If this property is not specified, the default is \c
@@ -2337,9 +2337,9 @@
\l{Qt Style Sheets Reference#subcontrol-position-prop}{subcontrol-position}.
\row
- \o \bold{\c subcontrol-position*} \target subcontrol-position-prop
- \o \l{#Alignment}{Alignment}
- \o The alignment of the \l subcontrol within the origin
+ \li \b{\c subcontrol-position*} \target subcontrol-position-prop
+ \li \l{#Alignment}{Alignment}
+ \li The alignment of the \l subcontrol within the origin
rectangle specified by \l{Qt Style Sheets Reference#subcontrol-origin-prop}
{subcontrol-origin}.
@@ -2354,9 +2354,9 @@
\l{Qt Style Sheets Reference#subcontrol-origin-prop}{subcontrol-origin}.
\row
- \o \bold{\c text-align} \target text-align-prop
- \o \l{#Alignment}{Alignment}
- \o The alignment of text and icon within the contents of the widget.
+ \li \b{\c text-align} \target text-align-prop
+ \li \l{#Alignment}{Alignment}
+ \li The alignment of text and icon within the contents of the widget.
If this value is not specified, it defaults to the value
that depends on the native style.
@@ -2369,17 +2369,17 @@
and QProgressBar.
\row
- \o \bold{\c text-decoration}
- \o \c none \BR
+ \li \b{\c text-decoration}
+ \li \c none \BR
\c underline \BR
\c overline \BR
\c line-through
- \o Additional text effects
+ \li Additional text effects
\row
- \o \bold{\c top} \target top-prop
- \o \l{#Length}{Length}
- \o If \l{#position-prop}{position} is \c relative (the
+ \li \b{\c top} \target top-prop
+ \li \l{#Length}{Length}
+ \li If \l{#position-prop}{position} is \c relative (the
default), moves a \l{subcontrol} by a certain offset
down.
@@ -2398,9 +2398,9 @@
\l{#bottom-prop}{bottom}.
\row
- \o \bold{\c width} \target width-prop
- \o \l{#Length}{Length}
- \o The width of a \l{subcontrol} (or a widget in some cases).
+ \li \b{\c width} \target width-prop
+ \li \l{#Length}{Length}
+ \li The width of a \l{subcontrol} (or a widget in some cases).
If this property is not specified, it defaults to a value
that depends on the subcontrol/widget and on the current style.
@@ -2430,222 +2430,222 @@
\table 100%
\header
- \o Name
- \o QStyle::StandardPixmap
+ \li Name
+ \li QStyle::StandardPixmap
\row
- \o backward-icon
- \o QStyle::SP_ArrowBack
+ \li backward-icon
+ \li QStyle::SP_ArrowBack
\row
- \o cd-icon
- \o QStyle::SP_DriveCDIcon
+ \li cd-icon
+ \li QStyle::SP_DriveCDIcon
\row
- \o computer-icon
- \o QStyle::SP_ComputerIcon
+ \li computer-icon
+ \li QStyle::SP_ComputerIcon
\row
- \o desktop-icon
- \o QStyle::SP_DesktopIcon
+ \li desktop-icon
+ \li QStyle::SP_DesktopIcon
\row
- \o dialog-apply-icon
- \o QStyle::SP_DialogApplyButton
+ \li dialog-apply-icon
+ \li QStyle::SP_DialogApplyButton
\row
- \o dialog-cancel-icon
- \o QStyle::SP_DialogCancelButton
+ \li dialog-cancel-icon
+ \li QStyle::SP_DialogCancelButton
\row
- \o dialog-close-icon
- \o QStyle::SP_DialogCloseButton
+ \li dialog-close-icon
+ \li QStyle::SP_DialogCloseButton
\row
- \o dialog-discard-icon
- \o QStyle::SP_DialogDiscardButton
+ \li dialog-discard-icon
+ \li QStyle::SP_DialogDiscardButton
\row
- \o dialog-help-icon
- \o QStyle::SP_DialogHelpButton
+ \li dialog-help-icon
+ \li QStyle::SP_DialogHelpButton
\row
- \o dialog-no-icon
- \o QStyle::SP_DialogNoButton
+ \li dialog-no-icon
+ \li QStyle::SP_DialogNoButton
\row
- \o dialog-ok-icon
- \o QStyle::SP_DialogOkButton
+ \li dialog-ok-icon
+ \li QStyle::SP_DialogOkButton
\row
- \o dialog-open-icon
- \o QStyle::SP_DialogOpenButton
+ \li dialog-open-icon
+ \li QStyle::SP_DialogOpenButton
\row
- \o dialog-reset-icon
- \o QStyle::SP_DialogResetButton
+ \li dialog-reset-icon
+ \li QStyle::SP_DialogResetButton
\row
- \o dialog-save-icon
- \o QStyle::SP_DialogSaveButton
+ \li dialog-save-icon
+ \li QStyle::SP_DialogSaveButton
\row
- \o dialog-yes-icon
- \o QStyle::SP_DialogYesButton
+ \li dialog-yes-icon
+ \li QStyle::SP_DialogYesButton
\row
- \o directory-closed-icon
- \o QStyle::SP_DirClosedIcon
+ \li directory-closed-icon
+ \li QStyle::SP_DirClosedIcon
\row
- \o directory-icon
- \o QStyle::SP_DirIcon
+ \li directory-icon
+ \li QStyle::SP_DirIcon
\row
- \o directory-link-icon
- \o QStyle::SP_DirLinkIcon
+ \li directory-link-icon
+ \li QStyle::SP_DirLinkIcon
\row
- \o directory-open-icon
- \o QStyle::SP_DirOpenIcon
+ \li directory-open-icon
+ \li QStyle::SP_DirOpenIcon
\row
- \o dockwidget-close-icon
- \o QStyle::SP_DockWidgetCloseButton
+ \li dockwidget-close-icon
+ \li QStyle::SP_DockWidgetCloseButton
\row
- \o downarrow-icon
- \o QStyle::SP_ArrowDown
+ \li downarrow-icon
+ \li QStyle::SP_ArrowDown
\row
- \o dvd-icon
- \o QStyle::SP_DriveDVDIcon
+ \li dvd-icon
+ \li QStyle::SP_DriveDVDIcon
\row
- \o file-icon
- \o QStyle::SP_FileIcon
+ \li file-icon
+ \li QStyle::SP_FileIcon
\row
- \o file-link-icon
- \o QStyle::SP_FileLinkIcon
+ \li file-link-icon
+ \li QStyle::SP_FileLinkIcon
\omit
\row
- \o filedialog-backward-icon
- \o QStyle::SP_FileDialogBack
+ \li filedialog-backward-icon
+ \li QStyle::SP_FileDialogBack
\endomit
\row
- \o filedialog-contentsview-icon
- \o QStyle::SP_FileDialogContentsView
+ \li filedialog-contentsview-icon
+ \li QStyle::SP_FileDialogContentsView
\row
- \o filedialog-detailedview-icon
- \o QStyle::SP_FileDialogDetailedView
+ \li filedialog-detailedview-icon
+ \li QStyle::SP_FileDialogDetailedView
\row
- \o filedialog-end-icon
- \o QStyle::SP_FileDialogEnd
+ \li filedialog-end-icon
+ \li QStyle::SP_FileDialogEnd
\row
- \o filedialog-infoview-icon
- \o QStyle::SP_FileDialogInfoView
+ \li filedialog-infoview-icon
+ \li QStyle::SP_FileDialogInfoView
\row
- \o filedialog-listview-icon
- \o QStyle::SP_FileDialogListView
+ \li filedialog-listview-icon
+ \li QStyle::SP_FileDialogListView
\row
- \o filedialog-new-directory-icon
- \o QStyle::SP_FileDialogNewFolder
+ \li filedialog-new-directory-icon
+ \li QStyle::SP_FileDialogNewFolder
\row
- \o filedialog-parent-directory-icon
- \o QStyle::SP_FileDialogToParent
+ \li filedialog-parent-directory-icon
+ \li QStyle::SP_FileDialogToParent
\row
- \o filedialog-start-icon
- \o QStyle::SP_FileDialogStart
+ \li filedialog-start-icon
+ \li QStyle::SP_FileDialogStart
\row
- \o floppy-icon
- \o QStyle::SP_DriveFDIcon
+ \li floppy-icon
+ \li QStyle::SP_DriveFDIcon
\row
- \o forward-icon
- \o QStyle::SP_ArrowForward
+ \li forward-icon
+ \li QStyle::SP_ArrowForward
\row
- \o harddisk-icon
- \o QStyle::SP_DriveHDIcon
+ \li harddisk-icon
+ \li QStyle::SP_DriveHDIcon
\row
- \o home-icon
- \o QStyle::SP_DirHomeIcon
+ \li home-icon
+ \li QStyle::SP_DirHomeIcon
\row
- \o leftarrow-icon
- \o QStyle::SP_ArrowLeft
+ \li leftarrow-icon
+ \li QStyle::SP_ArrowLeft
\row
- \o messagebox-critical-icon
- \o QStyle::SP_MessageBoxCritical
+ \li messagebox-critical-icon
+ \li QStyle::SP_MessageBoxCritical
\row
- \o messagebox-information-icon
- \o QStyle::SP_MessageBoxInformation
+ \li messagebox-information-icon
+ \li QStyle::SP_MessageBoxInformation
\row
- \o messagebox-question-icon
- \o QStyle::SP_MessageBoxQuestion
+ \li messagebox-question-icon
+ \li QStyle::SP_MessageBoxQuestion
\row
- \o messagebox-warning-icon
- \o QStyle::SP_MessageBoxWarning
+ \li messagebox-warning-icon
+ \li QStyle::SP_MessageBoxWarning
\row
- \o network-icon
- \o QStyle::SP_DriveNetIcon
+ \li network-icon
+ \li QStyle::SP_DriveNetIcon
\row
- \o rightarrow-icon
- \o QStyle::SP_ArrowRight
+ \li rightarrow-icon
+ \li QStyle::SP_ArrowRight
\row
- \o titlebar-contexthelp-icon
- \o QStyle::SP_TitleBarContextHelpButton
+ \li titlebar-contexthelp-icon
+ \li QStyle::SP_TitleBarContextHelpButton
\row
- \o titlebar-maximize-icon
- \o QStyle::SP_TitleBarMaxButton
+ \li titlebar-maximize-icon
+ \li QStyle::SP_TitleBarMaxButton
\row
- \o titlebar-menu-icon
- \o QStyle::SP_TitleBarMenuButton
+ \li titlebar-menu-icon
+ \li QStyle::SP_TitleBarMenuButton
\row
- \o titlebar-minimize-icon
- \o QStyle::SP_TitleBarMinButton
+ \li titlebar-minimize-icon
+ \li QStyle::SP_TitleBarMinButton
\row
- \o titlebar-normal-icon
- \o QStyle::SP_TitleBarNormalButton
+ \li titlebar-normal-icon
+ \li QStyle::SP_TitleBarNormalButton
\row
- \o titlebar-shade-icon
- \o QStyle::SP_TitleBarShadeButton
+ \li titlebar-shade-icon
+ \li QStyle::SP_TitleBarShadeButton
\row
- \o titlebar-unshade-icon
- \o QStyle::SP_TitleBarUnshadeButton
+ \li titlebar-unshade-icon
+ \li QStyle::SP_TitleBarUnshadeButton
\row
- \o trash-icon
- \o QStyle::SP_TrashIcon
+ \li trash-icon
+ \li QStyle::SP_TrashIcon
\row
- \o uparrow-icon
- \o QStyle::SP_ArrowUp
+ \li uparrow-icon
+ \li QStyle::SP_ArrowUp
\endtable
@@ -2656,59 +2656,59 @@
\table 100%
\header
- \o Type
- \o Syntax
- \o Description
+ \li Type
+ \li Syntax
+ \li Description
\row
- \o \bold Alignment \target Alignment
- \o \{ \c top \BR
+ \li \b Alignment \target Alignment
+ \li \{ \c top \BR
| \c bottom \BR
| \c left \BR
| \c right \BR
| \c center \}*
- \o Horizontal and/or vertical alignment.
+ \li Horizontal and/or vertical alignment.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 80
\row
- \o \bold Attachment \target Attachment
- \o \{ \c scroll \BR
+ \li \b Attachment \target Attachment
+ \li \{ \c scroll \BR
| \c fixed \}*
- \o Scroll or fixed attachment.
+ \li Scroll or fixed attachment.
\row
- \o \bold Background \target Background
- \o \{ \l{#Brush}{Brush} \BR
+ \li \b Background \target Background
+ \li \{ \l{#Brush}{Brush} \BR
| \l{#Url}{Url} \BR
| \l{#Repeat}{Repeat} \BR
| \l{#Alignment}{Alignment} \}*
- \o A sequence of \l{#Brush}{Brush}, \l{#Url}{Url},
+ \li A sequence of \l{#Brush}{Brush}, \l{#Url}{Url},
\l{#Repeat}{Repeat}, and \l{#Alignment}{Alignment}.
\row
- \o \bold Boolean \target Boolean
- \o 0 | 1
- \o True (\c 1) or false (\c 0).
+ \li \b Boolean \target Boolean
+ \li 0 | 1
+ \li True (\c 1) or false (\c 0).
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 81
\row
- \o \bold Border \target Border
- \o \{ \l{#Border Style}{Border Style} \BR
+ \li \b Border \target Border
+ \li \{ \l{#Border Style}{Border Style} \BR
| \l{#Length}{Length} \BR
| \l{#Brush}{Brush} \}*
- \o Shorthand border property.
+ \li Shorthand border property.
\row
- \o \bold{Border Image} \target Border Image
- \o \c none \BR
+ \li \b{Border Image} \target Border Image
+ \li \c none \BR
| \l{Url} \l{Number}\{4\} \BR (\c stretch | \c repeat){0,2}
- \o A border image is an image that is composed of nine parts
+ \li A border image is an image that is composed of nine parts
(top left, top center, top right, center left, center,
center right, bottom left, bottom center, and bottom
right). When a border of a certain size is required, the
@@ -2721,8 +2721,8 @@
{CSS3 Draft Specification} for details.
\row
- \o \bold{Border Style} \target Border Style
- \o \c dashed \BR
+ \li \b{Border Style} \target Border Style
+ \li \c dashed \BR
| \c dot-dash \BR
| \c dot-dot-dash \BR
| \c dotted \BR
@@ -2733,14 +2733,14 @@
| \c ridge \BR
| \c solid \BR
| \c none
- \o Specifies the pattern used to draw a border.
+ \li Specifies the pattern used to draw a border.
See the \l{http://www.w3.org/TR/css3-background/#border-style}
{CSS3 Draft Specification} for details.
\row
- \o \bold{Box Colors} \target Box Colors
- \o \l{#Brush}{Brush}\{1,4\}
- \o One to four occurrences of \l{#Brush}{Brush}, specifying the top,
+ \li \b{Box Colors} \target Box Colors
+ \li \l{#Brush}{Brush}\{1,4\}
+ \li One to four occurrences of \l{#Brush}{Brush}, specifying the top,
right, bottom, and left edges of a box, respectively. If
the left color is not specified, it is taken to be the
same as the right color. If the bottom color is not
@@ -2753,9 +2753,9 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 82
\row
- \o \bold{Box Lengths} \target Box Lengths
- \o \l{#Length}{Length}\{1,4\}
- \o One to four occurrences of \l{#Length}{Length}, specifying the
+ \li \b{Box Lengths} \target Box Lengths
+ \li \l{#Length}{Length}\{1,4\}
+ \li One to four occurrences of \l{#Length}{Length}, specifying the
top, right, bottom, and left edges of a box,
respectively. If the left length is not specified, it is
taken to be the same as the right length. If the bottom
@@ -2768,21 +2768,21 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 83
\row
- \o \bold{Brush} \target Brush
- \o \l{#Color}{Color} \BR
+ \li \b{Brush} \target Brush
+ \li \l{#Color}{Color} \BR
| \l{Gradient} \BR
| \l{PaletteRole}
- \o Specifies a Color or a Gradient or an entry in the Palette.
+ \li Specifies a Color or a Gradient or an entry in the Palette.
\row
- \o \bold{Color} \target Color
- \o \tt{rgb(\e{r}, \e{g}, \e{b})} \BR
+ \li \b{Color} \target Color
+ \li \tt{rgb(\e{r}, \e{g}, \e{b})} \BR
| \tt{rgba(\e{r}, \e{g}, \e{b}, \e{a})} \BR
| \tt{hsv(\e{h}, \e{s}, \e{v})} \BR
| \tt{hsva(\e{h}, \e{s}, \e{v}, \e{a})} \BR
| \tt{#\e{rrggbb}} \BR
| \l{QColor::setNamedColor()}{Color Name} \BR
- \o Specifies a color as RGB (red, green, blue) or RGBA
+ \li Specifies a color as RGB (red, green, blue) or RGBA
(red, green, blue, alpha) or HSV (hue, saturation, value) or HSVA
(hue, saturation, value, alpha) or a named color. The \c rgb() or \c rgba()
syntax can be used with integer values between 0 and 255, or with
@@ -2798,45 +2798,45 @@
\l{http://www.w3.org/TR/CSS21/syndata.html#color-units}{here}.
\row
- \o \bold{Font} \target Font
- \o (\l{#Font Style}{Font Style} | \l{#Font Weight}{Font Weight}){0,2} \l{#Font Size}{Font Size} String
- \o Shorthand font property.
+ \li \b{Font} \target Font
+ \li (\l{#Font Style}{Font Style} | \l{#Font Weight}{Font Weight}){0,2} \l{#Font Size}{Font Size} String
+ \li Shorthand font property.
\row
- \o \bold{Font Size} \target Font Size
- \o \l{Length}
- \o The size of a font.
+ \li \b{Font Size} \target Font Size
+ \li \l{Length}
+ \li The size of a font.
\row
- \o \bold{Font Style} \target Font Style
- \o \c normal \BR
+ \li \b{Font Style} \target Font Style
+ \li \c normal \BR
| \c italic \BR
| \c oblique
- \o The style of a font.
+ \li The style of a font.
\row
- \o \bold{Font Weight} \target Font Weight
- \o \c normal \BR
+ \li \b{Font Weight} \target Font Weight
+ \li \c normal \BR
| \c bold \BR
| \c 100 \BR
| \c 200 \BR
... \BR
| \c 900
- \o The weight of a font.
+ \li The weight of a font.
\row
- \o \bold{Gradient} \target Gradient
- \o \c qlineargradient \BR
+ \li \b{Gradient} \target Gradient
+ \li \c qlineargradient \BR
| \c qradialgradient \BR
| \c qconicalgradient
- \o Specifies gradient fills. There are three types of gradient fills:
+ \li Specifies gradient fills. There are three types of gradient fills:
\list
- \o \e{Linear} gradients interpolate colors between start and
+ \li \e{Linear} gradients interpolate colors between start and
end points.
- \o \e{Radial} gradients interpolate colors between a focal
+ \li \e{Radial} gradients interpolate colors between a focal
point and end points on a circle surrounding it.
- \o \e{Conical} gradients interpolate colors around a center
+ \li \e{Conical} gradients interpolate colors around a center
point.
\endlist
@@ -2855,18 +2855,18 @@
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 85
\row
- \o \bold{Icon} \target Icon
- \o (\l{#Url}{Url} (\c disabled | \c active | \c normal | \c selected)?
+ \li \b{Icon} \target Icon
+ \li (\l{#Url}{Url} (\c disabled | \c active | \c normal | \c selected)?
(\c on | \c off)? )*
- \o A list of url, QIcon::Mode and QIcon::State.
+ \li A list of url, QIcon::Mode and QIcon::State.
Example:
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 86
\row
- \o \bold{Length} \target Length
- \o \l{#Number}{Number} (\c px | \c pt | \c em | \c ex)?
- \o A number followed by a measurement unit. The CSS standard recommends
+ \li \b{Length} \target Length
+ \li \l{#Number}{Number} (\c px | \c pt | \c em | \c ex)?
+ \li A number followed by a measurement unit. The CSS standard recommends
that user agents must
\l{http://www.w3.org/TR/CSS21/syndata.html#illegalvalues}{ignore}
a declaration with an illegal value. In Qt, it is mandatory to
@@ -2875,32 +2875,32 @@
in most contexts. The supported units are:
\list
- \o \c px: pixels
- \o \c pt: the size of one point (i.e., 1/72 of an inch)
- \o \c em: the em width of the font (i.e., the width of 'M')
- \o \c ex: the ex width of the font (i.e., the height of 'x')
+ \li \c px: pixels
+ \li \c pt: the size of one point (i.e., 1/72 of an inch)
+ \li \c em: the em width of the font (i.e., the width of 'M')
+ \li \c ex: the ex width of the font (i.e., the height of 'x')
\endlist
\row
- \o \bold{Number} \target Number
- \o A decimal integer or a real number
- \o Examples: \c 0, \c 18, \c +127, \c -255, \c 12.34, \c -.5,
+ \li \b{Number} \target Number
+ \li A decimal integer or a real number
+ \li Examples: \c 0, \c 18, \c +127, \c -255, \c 12.34, \c -.5,
\c 0009.
\row
- \o \bold{Origin} \target Origin
- \o \c margin \BR
+ \li \b{Origin} \target Origin
+ \li \c margin \BR
| \c border \BR
| \c padding \BR
| \c content
- \o Indicates which of four rectangles to use.
+ \li Indicates which of four rectangles to use.
\list
- \o \c margin: The margin rectangle. The margin falls outside the border.
- \o \c border: The border rectangle. This is where any border is drawn.
- \o \c padding: The padding rectangle. Unlike the margins,
+ \li \c margin: The margin rectangle. The margin falls outside the border.
+ \li \c border: The border rectangle. This is where any border is drawn.
+ \li \c padding: The padding rectangle. Unlike the margins,
padding is located inside the border.
- \o \c content: The content rectangle. This specifies where
+ \li \c content: The content rectangle. This specifies where
the actual contents go, excluding any
padding, border, or margin.
\endlist
@@ -2908,8 +2908,8 @@
See also \l{The Box Model}.
\row
- \o \bold{PaletteRole} \target PaletteRole
- \o \c alternate-base \BR
+ \li \b{PaletteRole} \target PaletteRole
+ \li \c alternate-base \BR
| \c base \BR
| \c bright-text \BR
| \c button \BR
@@ -2926,40 +2926,40 @@
| \c text \BR
| \c window \BR
| \c window-text \BR
- \o These values correspond the \l{QPalette::ColorRole}{Color roles}
+ \li These values correspond the \l{QPalette::ColorRole}{Color roles}
in the widget's QPalette.
For example,
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 87
\row
- \o \bold{Radius} \target Radius
- \o \l{#Length}{Length}\{1, 2\}
- \o One or two occurrences of \l{#Length}{Length}. If only one length is
+ \li \b{Radius} \target Radius
+ \li \l{#Length}{Length}\{1, 2\}
+ \li One or two occurrences of \l{#Length}{Length}. If only one length is
specified, it is used as the radius of the quarter circle
defining the corner. If two lengths are specified, the
first length is the horizontal radius of a quarter
ellipse, whereas the second length is the vertical radius.
\row
- \o \bold{Repeat} \target Repeat
- \o \c repeat-x \BR
+ \li \b{Repeat} \target Repeat
+ \li \c repeat-x \BR
| \c repeat-y \BR
| \c repeat \BR
| \c no-repeat
- \o A value indicating the nature of repetition.
+ \li A value indicating the nature of repetition.
\list
- \o \c repeat-x: Repeat horizontally.
- \o \c repeat-y: Repeat vertically.
- \o \c repeat: Repeat horizontally and vertically.
- \o \c no-repeat: Don't repeat.
+ \li \c repeat-x: Repeat horizontally.
+ \li \c repeat-y: Repeat vertically.
+ \li \c repeat: Repeat horizontally and vertically.
+ \li \c no-repeat: Don't repeat.
\endlist
\row
- \o \bold{Url} \target Url
- \o \tt{url(\e{filename})}
- \o \tt{\e{filename}} is the name of a file on the local disk
+ \li \b{Url} \target Url
+ \li \tt{url(\e{filename})}
+ \li \tt{\e{filename}} is the name of a file on the local disk
or stored using \l{the Qt Resource System}. Setting an
image implicitly sets the width and height of the element.
@@ -2971,218 +2971,218 @@
\table 100%
\header
- \o Pseudo-State
- \o Description
+ \li Pseudo-State
+ \li Description
- \row \o \c :active \target active
- \o This state is set when the widget resides in an active window.
+ \row \li \c :active \target active
+ \li This state is set when the widget resides in an active window.
\row
- \o \c :adjoins-item \target adjoins-item-ps
- \o This state is set when the \l{#branch-sub}{::branch} of a QTreeView
+ \li \c :adjoins-item \target adjoins-item-ps
+ \li This state is set when the \l{#branch-sub}{::branch} of a QTreeView
is adjacent to an item.
\row
- \o \c :alternate \target alternate-ps
- \o This state is set for every alternate row whe painting the row of
+ \li \c :alternate \target alternate-ps
+ \li This state is set for every alternate row whe painting the row of
a QAbstractItemView when QAbstractItemView::alternatingRowColors()
is set to true.
\row
- \o \c :bottom \target bottom-ps
- \o The item is positioned at the bottom. For example, a QTabBar
+ \li \c :bottom \target bottom-ps
+ \li The item is positioned at the bottom. For example, a QTabBar
that has its tabs positioned at the bottom.
\row
- \o \c :checked \target checked-ps
- \o The item is checked. For example, the
+ \li \c :checked \target checked-ps
+ \li The item is checked. For example, the
\l{QAbstractButton::checked}{checked} state of QAbstractButton.
\row
- \o \c :closable \target closable-ps
- \o The items can be closed. For example, the QDockWidget has the
+ \li \c :closable \target closable-ps
+ \li The items can be closed. For example, the QDockWidget has the
QDockWidget::DockWidgetClosable feature turned on.
\row
- \o \c :closed \target closed-ps
- \o The item is in the closed state. For example, an non-expanded
+ \li \c :closed \target closed-ps
+ \li The item is in the closed state. For example, an non-expanded
item in a QTreeView
\row
- \o \c :default \target default-ps
- \o The item is the default. For example, a
+ \li \c :default \target default-ps
+ \li The item is the default. For example, a
\l{QPushButton::default}{default} QPushButton or a default action
in a QMenu.
\row
- \o \c :disabled \target disabled-ps
- \o The item is \l{QWidget::enabled}{disabled}.
+ \li \c :disabled \target disabled-ps
+ \li The item is \l{QWidget::enabled}{disabled}.
\row
- \o \c :editable \target editable-ps
- \o The QComboBox is editable.
+ \li \c :editable \target editable-ps
+ \li The QComboBox is editable.
\row
- \o \c :edit-focus \target edit-focus-ps
- \o The item has edit focus (See QStyle::State_HasEditFocus). This state
+ \li \c :edit-focus \target edit-focus-ps
+ \li The item has edit focus (See QStyle::State_HasEditFocus). This state
is available only for Qt Extended applications.
\row
- \o \c :enabled \target enabled-ps
- \o The item is \l{QWidget::enabled}{enabled}.
+ \li \c :enabled \target enabled-ps
+ \li The item is \l{QWidget::enabled}{enabled}.
\row
- \o \c :exclusive \target exclusive-ps
- \o The item is part of an exclusive item group. For example, a menu
+ \li \c :exclusive \target exclusive-ps
+ \li The item is part of an exclusive item group. For example, a menu
item in a exclusive QActionGroup.
\row
- \o \c :first \target first-ps
- \o The item is the first (in a list). For example, the first
+ \li \c :first \target first-ps
+ \li The item is the first (in a list). For example, the first
tab in a QTabBar.
\row
- \o \c :flat \target flat-ps
- \o The item is flat. For example, a
+ \li \c :flat \target flat-ps
+ \li The item is flat. For example, a
\l{QPushButton::flat}{flat} QPushButton.
\row
- \o \c :floatable \target floatable-ps
- \o The items can be floated. For example, the QDockWidget has the
+ \li \c :floatable \target floatable-ps
+ \li The items can be floated. For example, the QDockWidget has the
QDockWidget::DockWidgetFloatable feature turned on.
\row
- \o \c :focus \target focus-ps
- \o The item has \l{QWidget::hasFocus()}{input focus}.
+ \li \c :focus \target focus-ps
+ \li The item has \l{QWidget::hasFocus()}{input focus}.
\row
- \o \c :has-children \target has-children-ps
- \o The item has children. For example, an item in a
+ \li \c :has-children \target has-children-ps
+ \li The item has children. For example, an item in a
QTreeView that has child items.
\row
- \o \c :has-siblings \target has-siblings-ps
- \o The item has siblings. For example, an item in a
+ \li \c :has-siblings \target has-siblings-ps
+ \li The item has siblings. For example, an item in a
QTreeView that siblings.
\row
- \o \c :horizontal \target horizontal-ps
- \o The item has horizontal orientation
+ \li \c :horizontal \target horizontal-ps
+ \li The item has horizontal orientation
\row
- \o \c :hover \target hover-ps
- \o The mouse is hovering over the item.
+ \li \c :hover \target hover-ps
+ \li The mouse is hovering over the item.
\row
- \o \c :indeterminate \target indeterminate-ps
- \o The item has indeterminate state. For example, a QCheckBox
+ \li \c :indeterminate \target indeterminate-ps
+ \li The item has indeterminate state. For example, a QCheckBox
or QRadioButton is \l{Qt::PartiallyChecked}{partially checked}.
\row
- \o \c :last \target last-ps
- \o The item is the last (in a list). For example, the last
+ \li \c :last \target last-ps
+ \li The item is the last (in a list). For example, the last
tab in a QTabBar.
\row
- \o \c :left \target left-ps
- \o The item is positioned at the left. For example, a QTabBar
+ \li \c :left \target left-ps
+ \li The item is positioned at the left. For example, a QTabBar
that has its tabs positioned at the left.
\row
- \o \c :maximized \target maximized-ps
- \o The item is maximized. For example, a maximized QMdiSubWindow.
+ \li \c :maximized \target maximized-ps
+ \li The item is maximized. For example, a maximized QMdiSubWindow.
\row
- \o \c :middle \target middle-ps
- \o The item is in the middle (in a list). For example, a tab
+ \li \c :middle \target middle-ps
+ \li The item is in the middle (in a list). For example, a tab
that is not in the beginning or the end in a QTabBar.
\row
- \o \c :minimized \target minimized-ps
- \o The item is minimized. For example, a minimized QMdiSubWindow.
+ \li \c :minimized \target minimized-ps
+ \li The item is minimized. For example, a minimized QMdiSubWindow.
\row
- \o \c :movable \target movable-ps
- \o The item can be moved around. For example, the QDockWidget has the
+ \li \c :movable \target movable-ps
+ \li The item can be moved around. For example, the QDockWidget has the
QDockWidget::DockWidgetMovable feature turned on.
\row
- \o \c :no-frame \target no-frame-ps
- \o The item has no frame. For example, a frameless QSpinBox
+ \li \c :no-frame \target no-frame-ps
+ \li The item has no frame. For example, a frameless QSpinBox
or QLineEdit.
\row
- \o \c :non-exclusive \target non-exclusive-ps
- \o The item is part of a non-exclusive item group. For example, a menu
+ \li \c :non-exclusive \target non-exclusive-ps
+ \li The item is part of a non-exclusive item group. For example, a menu
item in a non-exclusive QActionGroup.
\row
- \o \c :off \target off-ps
- \o For items that can be toggled, this applies to items
+ \li \c :off \target off-ps
+ \li For items that can be toggled, this applies to items
in the "off" state.
\row
- \o \c :on \target on-ps
- \o For items that can be toggled, this applies to widgets
+ \li \c :on \target on-ps
+ \li For items that can be toggled, this applies to widgets
in the "on" state.
\row
- \o \c :only-one \target only-one-ps
- \o The item is the only one (in a list). For example, a lone tab
+ \li \c :only-one \target only-one-ps
+ \li The item is the only one (in a list). For example, a lone tab
in a QTabBar.
\row
- \o \c :open \target open-ps
- \o The item is in the open state. For example, an expanded
+ \li \c :open \target open-ps
+ \li The item is in the open state. For example, an expanded
item in a QTreeView, or a QComboBox or QPushButton with
an open menu.
\row
- \o \c :next-selected \target next-selected-ps
- \o The next item (in a list) is selected. For example, the
+ \li \c :next-selected \target next-selected-ps
+ \li The next item (in a list) is selected. For example, the
selected tab of a QTabBar is next to this item.
\row
- \o \c :pressed \target pressed-ps
- \o The item is being pressed using the mouse.
+ \li \c :pressed \target pressed-ps
+ \li The item is being pressed using the mouse.
\row
- \o \c :previous-selected \target previous-selected-ps
- \o The previous item (in a list) is selected. For example, a
+ \li \c :previous-selected \target previous-selected-ps
+ \li The previous item (in a list) is selected. For example, a
tab in a QTabBar that is next to the selected tab.
\row
- \o \c :read-only \target read-only-ps
- \o The item is marked read only or non-editable. For example,
+ \li \c :read-only \target read-only-ps
+ \li The item is marked read only or non-editable. For example,
a read only QLineEdit or a non-editable QComboBox.
\row
- \o \c :right \target right-ps
- \o The item is positioned at the right. For example, a QTabBar
+ \li \c :right \target right-ps
+ \li The item is positioned at the right. For example, a QTabBar
that has its tabs positioned at the right.
\row
- \o \c :selected \target selected-ps
- \o The item is selected. For example, the selected tab in
+ \li \c :selected \target selected-ps
+ \li The item is selected. For example, the selected tab in
a QTabBar or the selected item in a QMenu.
\row
- \o \c :top \target top-ps
- \o The item is positioned at the top. For example, a QTabBar
+ \li \c :top \target top-ps
+ \li The item is positioned at the top. For example, a QTabBar
that has its tabs positioned at the top.
\row
- \o \c :unchecked \target unchecked-ps
- \o The item is
+ \li \c :unchecked \target unchecked-ps
+ \li The item is
\l{QAbstractButton::checked}{unchecked}.
\row
- \o \c :vertical \target vertical-ps
- \o The item has vertical orientation.
+ \li \c :vertical \target vertical-ps
+ \li The item has vertical orientation.
\row
- \o \c :window \target window-ps
- \o The widget is a window (i.e top level widget)
+ \li \c :window \target window-ps
+ \li The widget is a window (i.e top level widget)
\endtable
@@ -3193,162 +3193,162 @@
\table 100%
\header
- \o Sub-Control
- \o Description
+ \li Sub-Control
+ \li Description
\row
- \o \c ::add-line \target add-line-sub
- \o The button to add a line of a QScrollBar.
+ \li \c ::add-line \target add-line-sub
+ \li The button to add a line of a QScrollBar.
\row
- \o \c ::add-page \target add-page-sub
- \o The region between the handle (slider) and the \l{#add-line-sub}{add-line}
+ \li \c ::add-page \target add-page-sub
+ \li The region between the handle (slider) and the \l{#add-line-sub}{add-line}
of a QScrollBar.
\row
- \o \c ::branch \target branch-sub
- \o The branch indicator of a QTreeView.
+ \li \c ::branch \target branch-sub
+ \li The branch indicator of a QTreeView.
\row
- \o \c ::chunk \target chunk-sub
- \o The progress chunk of a QProgressBar.
+ \li \c ::chunk \target chunk-sub
+ \li The progress chunk of a QProgressBar.
\row
- \o \c ::close-button \target close-button-sub
- \o The close button of a QDockWidget or tabs of QTabBar
+ \li \c ::close-button \target close-button-sub
+ \li The close button of a QDockWidget or tabs of QTabBar
\row
- \o \c ::corner \target corner-sub
- \o The corner between two scrollbars in a QAbstractScrollArea
+ \li \c ::corner \target corner-sub
+ \li The corner between two scrollbars in a QAbstractScrollArea
\row
- \o \c ::down-arrow \target down-arrow-sub
- \o The down arrow of a QComboBox, QHeaderView (sort indicator),
+ \li \c ::down-arrow \target down-arrow-sub
+ \li The down arrow of a QComboBox, QHeaderView (sort indicator),
QScrollBar or QSpinBox.
\row
- \o \c ::down-button \target down-button-sub
- \o The down button of a QScrollBar or a QSpinBox.
+ \li \c ::down-button \target down-button-sub
+ \li The down button of a QScrollBar or a QSpinBox.
\row
- \o \c ::drop-down \target drop-down-sub
- \o The drop-down button of a QComboBox.
+ \li \c ::drop-down \target drop-down-sub
+ \li The drop-down button of a QComboBox.
\row
- \o \c ::float-button \target float-button-sub
- \o The float button of a QDockWidget
+ \li \c ::float-button \target float-button-sub
+ \li The float button of a QDockWidget
\row
- \o \c ::groove \target groove-sub
- \o The groove of a QSlider.
+ \li \c ::groove \target groove-sub
+ \li The groove of a QSlider.
\row
- \o \c ::indicator \target indicator-sub
- \o The indicator of a QAbstractItemView, a QCheckBox, a QRadioButton,
+ \li \c ::indicator \target indicator-sub
+ \li The indicator of a QAbstractItemView, a QCheckBox, a QRadioButton,
a checkable QMenu item or a checkable QGroupBox.
\row
- \o \c ::handle \target handle-sub
- \o The handle (slider) of a QScrollBar, a QSplitter, or a QSlider.
+ \li \c ::handle \target handle-sub
+ \li The handle (slider) of a QScrollBar, a QSplitter, or a QSlider.
\row
- \o \c ::icon \target icon-sub
- \o The icon of a QAbstractItemView or a QMenu.
+ \li \c ::icon \target icon-sub
+ \li The icon of a QAbstractItemView or a QMenu.
\row
- \o \c ::item \target item-sub
- \o An item of a QAbstractItemView, a QMenuBar, a QMenu, or
+ \li \c ::item \target item-sub
+ \li An item of a QAbstractItemView, a QMenuBar, a QMenu, or
a QStatusBar.
\row
- \o \c ::left-arrow \target left-arrow-sub
- \o The left arrow of a QScrollBar.
+ \li \c ::left-arrow \target left-arrow-sub
+ \li The left arrow of a QScrollBar.
\row
- \o \c ::left-corner \target left-corner-sub
- \o The left corner of a QTabWidget. For example, this control can be
+ \li \c ::left-corner \target left-corner-sub
+ \li The left corner of a QTabWidget. For example, this control can be
used to control position the left corner widget in a QTabWidget.
\row
- \o \c ::menu-arrow \target menu-arrow-sub
- \o The arrow of a QToolButton with a menu.
+ \li \c ::menu-arrow \target menu-arrow-sub
+ \li The arrow of a QToolButton with a menu.
\row
- \o \c ::menu-button \target menu-button-sub
- \o The menu button of a QToolButton.
+ \li \c ::menu-button \target menu-button-sub
+ \li The menu button of a QToolButton.
\row
- \o \c ::menu-indicator \target menu-indicator-sub
- \o The menu indicator of a QPushButton.
+ \li \c ::menu-indicator \target menu-indicator-sub
+ \li The menu indicator of a QPushButton.
\row
- \o \c ::right-arrow \target right-arrow-sub
- \o The right arrow of a QMenu or a QScrollBar.
+ \li \c ::right-arrow \target right-arrow-sub
+ \li The right arrow of a QMenu or a QScrollBar.
\row
- \o \c ::pane \target pane-sub
- \o The pane (frame) of a QTabWidget.
+ \li \c ::pane \target pane-sub
+ \li The pane (frame) of a QTabWidget.
\row
- \o \c ::right-corner \target right-corner-sub
- \o The right corner of a QTabWidget. For example, this control can be
+ \li \c ::right-corner \target right-corner-sub
+ \li The right corner of a QTabWidget. For example, this control can be
used to control the position the right corner widget in a QTabWidget.
\row
- \o \c ::scroller \target scroller-sub
- \o The scroller of a QMenu or QTabBar.
+ \li \c ::scroller \target scroller-sub
+ \li The scroller of a QMenu or QTabBar.
\row
- \o \c ::section \target section-sub
- \o The section of a QHeaderView.
+ \li \c ::section \target section-sub
+ \li The section of a QHeaderView.
\row
- \o \c ::separator \target separator-sub
- \o The separator of a QMenu or in a QMainWindow.
+ \li \c ::separator \target separator-sub
+ \li The separator of a QMenu or in a QMainWindow.
\row
- \o \c ::sub-line \target sub-line-sub
- \o The button to subtract a line of a QScrollBar.
+ \li \c ::sub-line \target sub-line-sub
+ \li The button to subtract a line of a QScrollBar.
\row
- \o \c ::sub-page \target sub-page-sub
- \o The region between the handle (slider) and the \l{#sub-line-sub}{sub-line}
+ \li \c ::sub-page \target sub-page-sub
+ \li The region between the handle (slider) and the \l{#sub-line-sub}{sub-line}
of a QScrollBar.
\row
- \o \c ::tab \target tab-sub
- \o The tab of a QTabBar or QToolBox.
+ \li \c ::tab \target tab-sub
+ \li The tab of a QTabBar or QToolBox.
\row
- \o \c ::tab-bar \target tab-bar-sub
- \o The tab bar of a QTabWidget. This subcontrol exists only to
+ \li \c ::tab-bar \target tab-bar-sub
+ \li The tab bar of a QTabWidget. This subcontrol exists only to
control the position of the QTabBar inside the QTabWidget. To
style the tabs using the \l{#tab-sub}{::tab} subcontrol.
\row
- \o \c ::tear \target tear-sub
- \o The tear indicator of a QTabBar.
+ \li \c ::tear \target tear-sub
+ \li The tear indicator of a QTabBar.
\row
- \o \c ::tearoff \target tearoff-sub
- \o The tear-off indicator of a QMenu.
+ \li \c ::tearoff \target tearoff-sub
+ \li The tear-off indicator of a QMenu.
\row
- \o \c ::text \target text-ps
- \o The text of a QAbstractItemView.
+ \li \c ::text \target text-ps
+ \li The text of a QAbstractItemView.
\row
- \o \c ::title \target title-sub
- \o The title of a QGroupBox or a QDockWidget.
+ \li \c ::title \target title-sub
+ \li The title of a QGroupBox or a QDockWidget.
\row
- \o \c ::up-arrow \target up-arrow-sub
- \o The up arrow of a QHeaderView (sort indicator), QScrollBar
+ \li \c ::up-arrow \target up-arrow-sub
+ \li The up arrow of a QHeaderView (sort indicator), QScrollBar
or a QSpinBox.
\row
- \o \c ::up-button \target up-button-sub
- \o The up button of a QSpinBox.
+ \li \c ::up-button \target up-button-sub
+ \li The up button of a QSpinBox.
\endtable
@@ -3441,11 +3441,11 @@
What happened is this:
\list
- \o We have made a request that cannot be satisfied using the
+ \li We have made a request that cannot be satisfied using the
native styles alone (e.g., the Windows XP theme engine doesn't
let us specify the background color of a button).
- \o Therefore, the button is rendered using style sheets.
- \o We haven't specified any values for
+ \li Therefore, the button is rendered using style sheets.
+ \li We haven't specified any values for
\l{Qt Style Sheets Reference#border-width-prop}{border-width} and
\l{Qt Style Sheets Reference#border-style-prop}{border-style}, so by default we obtain
a 0-pixel wide border of style \c none.
@@ -3836,18 +3836,18 @@
There are three types of QToolButtons.
\list
- \i The QToolButton has no menu. In this case, the QToolButton is styled
+ \li The QToolButton has no menu. In this case, the QToolButton is styled
exactly like QPushButton. See
\l{#Customizing QPushButton}{Customizing QPushButton} for an
example.
- \i The QToolButton has a menu and has the QToolButton::popupMode set to
+ \li The QToolButton has a menu and has the QToolButton::popupMode set to
QToolButton::DelayedPopup or QToolButton::InstantPopup. In this case,
the QToolButton is styled exactly like a QPushButton with a menu.
See \l{#Customizing QPushButton}{Customizing QPushButton} for an
example of the usage of the menu-indicator pseudo state.
- \i The QToolButton has its QToolButton::popupMode set to
+ \li The QToolButton has its QToolButton::popupMode set to
QToolButton::MenuButtonPopup. In this case, we style it as follows:
\endlist
@@ -3885,17 +3885,17 @@
\table
\row
- \o \inlineimage stylesheet-vline.png
- \o \inlineimage stylesheet-branch-more.png
- \o \inlineimage stylesheet-branch-end.png
- \o \inlineimage stylesheet-branch-closed.png
- \o \inlineimage stylesheet-branch-open.png
+ \li \inlineimage stylesheet-vline.png
+ \li \inlineimage stylesheet-branch-more.png
+ \li \inlineimage stylesheet-branch-end.png
+ \li \inlineimage stylesheet-branch-closed.png
+ \li \inlineimage stylesheet-branch-open.png
\row
- \o vline.png
- \o branch-more.png
- \o branch-end.png
- \o branch-closed.png
- \o branch-open.png
+ \li vline.png
+ \li branch-more.png
+ \li branch-end.png
+ \li branch-closed.png
+ \li branch-open.png
\endtable
\snippet doc/src/snippets/code/doc_src_stylesheet.qdoc 158
@@ -3948,16 +3948,16 @@
\table
\row
- \o \inlineimage stylesheet-border-image-stretched.png
+ \li \inlineimage stylesheet-border-image-stretched.png
\row
- \o With borders
+ \li With borders
\endtable
\table
\row
- \o \inlineimage stylesheet-border-image-wrong.png
+ \li \inlineimage stylesheet-border-image-wrong.png
\row
- \o Without borders
+ \li Without borders
\endtable
*/
diff --git a/doc/src/widgets/widgets-and-layouts/widgets.qdoc b/doc/src/widgets/widgets-and-layouts/widgets.qdoc
index a84f12e70f4..e80b0fbec0c 100644
--- a/doc/src/widgets/widgets-and-layouts/widgets.qdoc
+++ b/doc/src/widgets/widgets-and-layouts/widgets.qdoc
@@ -58,8 +58,8 @@
\table
\row
- \o \image qgridlayout-with-5-children.png
- \o \image qformlayout-with-6-children.png
+ \li \image qgridlayout-with-5-children.png
+ \li \image qformlayout-with-6-children.png
\endtable
\l{Qt Designer Manual}{\QD} is a powerful tool for interactively creating and
@@ -74,9 +74,9 @@
\table
\row
- \o \image windowsxp-tabwidget.png
- \o \image plastique-tabwidget.png
- \o \image macintosh-tabwidget.png
+ \li \image windowsxp-tabwidget.png
+ \li \image plastique-tabwidget.png
+ \li \image macintosh-tabwidget.png
\endtable
\l{Qt Style Sheets} are a powerful mechanism that allows you to customize the
@@ -94,13 +94,13 @@
\table
\row
- \o \image windows-label.png
- \o \image windowsvista-pushbutton.png
- \o \image gtk-progressbar.png
+ \li \image windows-label.png
+ \li \image windowsvista-pushbutton.png
+ \li \image gtk-progressbar.png
\row
- \o \image plastique-combobox.png
- \o \image macintosh-radiobutton.png
- \o \image cde-lineedit.png
+ \li \image plastique-combobox.png
+ \li \image macintosh-radiobutton.png
+ \li \image cde-lineedit.png
\endtable
\annotatedlist basicwidgets
@@ -112,17 +112,17 @@
\table
\row
- \o \image windowsxp-treeview.png
- \o \image gtk-calendarwidget.png
- \o \image qundoview.png
+ \li \image windowsxp-treeview.png
+ \li \image gtk-calendarwidget.png
+ \li \image qundoview.png
\endtable
\annotatedlist advanced
\table
\row
- \o \image windowsvista-tabwidget.png
- \o \image macintosh-groupbox.png
+ \li \image windowsvista-tabwidget.png
+ \li \image macintosh-groupbox.png
\endtable
\section2 Organizer Widgets
diff --git a/doc/src/widgets/widgets-tutorial.qdoc b/doc/src/widgets/widgets-tutorial.qdoc
index 1d010651e5e..735a7ebc54d 100644
--- a/doc/src/widgets/widgets-tutorial.qdoc
+++ b/doc/src/widgets/widgets-tutorial.qdoc
@@ -78,13 +78,13 @@
the \c main() function.
\list
- \o \l {tutorials/widgets/toplevel} {Creating a window}
+ \li \l {tutorials/widgets/toplevel} {Creating a window}
- \o \l {tutorials/widgets/childwidget} {Creating child widgets}
+ \li \l {tutorials/widgets/childwidget} {Creating child widgets}
- \o \l {tutorials/widgets/windowlayout} {Using layouts}
+ \li \l {tutorials/widgets/windowlayout} {Using layouts}
- \o \l {tutorials/widgets/nestedlayouts} {Nested layouts}
+ \li \l {tutorials/widgets/nestedlayouts} {Nested layouts}
\endlist
\section1 Real world widget examples
@@ -103,14 +103,14 @@
\list 1
- \o From a command prompt, enter the directory containing the
+ \li From a command prompt, enter the directory containing the
example you have modified.
- \o Type \c qmake and press \key{Return}. If this doesn't work,
+ \li Type \c qmake and press \key{Return}. If this doesn't work,
make sure that the executable is on your path, or enter its
full location.
- \o On Linux/Unix and Mac OS X, type \c make and press
+ \li On Linux/Unix and Mac OS X, type \c make and press
\key{Return}; on Windows with Visual Studio, type \c nmake and
press \key{Return}.
@@ -137,8 +137,8 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/toplevel/main.cpp main program
- \o \inlineimage widgets-tutorial-toplevel.png
+ \li \snippet tutorials/widgets/toplevel/main.cpp main program
+ \li \inlineimage widgets-tutorial-toplevel.png
\endtable
\enddiv
@@ -159,8 +159,8 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/childwidget/main.cpp main program
- \o \inlineimage widgets-tutorial-childwidget.png
+ \li \snippet tutorials/widgets/childwidget/main.cpp main program
+ \li \inlineimage widgets-tutorial-childwidget.png
\endtable
\enddiv
@@ -181,8 +181,8 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/windowlayout/main.cpp main program
- \o \inlineimage widgets-tutorial-windowlayout.png
+ \li \snippet tutorials/widgets/windowlayout/main.cpp main program
+ \li \inlineimage widgets-tutorial-windowlayout.png
\endtable
\enddiv
@@ -219,9 +219,9 @@
\div {class="qt-code"}
\table
\row
- \o \snippet tutorials/widgets/nestedlayouts/main.cpp first part
+ \li \snippet tutorials/widgets/nestedlayouts/main.cpp first part
\snippet tutorials/widgets/nestedlayouts/main.cpp last part
- \o \inlineimage widgets-tutorial-nestedlayouts.png
+ \li \inlineimage widgets-tutorial-nestedlayouts.png
\endtable
\enddiv
diff --git a/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc b/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc
index 1517116c05a..3a2efb06a25 100644
--- a/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc
+++ b/doc/src/widgets/windows-and-dialogs/mainwindow.qdoc
@@ -94,13 +94,13 @@
most common usage transparently.
\list
- \o \bold{Including the window frame:}
+ \li \b{Including the window frame:}
\l{QWidget::x()}{x()},
\l{QWidget::y()}{y()},
\l{QWidget::frameGeometry()}{frameGeometry()},
\l{QWidget::pos()}{pos()}, and
\l{QWidget::move()}{move()}.
- \o \bold{Excluding the window frame:}
+ \li \b{Excluding the window frame:}
\l{QWidget::geometry()}{geometry()},
\l{QWidget::width()}{width()},
\l{QWidget::height()}{height()},
@@ -169,17 +169,17 @@
associated user interface components:
\list
- \o QMainWindow remains the central class around which applications
+ \li QMainWindow remains the central class around which applications
can be built. The interface to this class has been simplified, and
much of the functionality previously included in this class is now
present in the companion QDockWidget and QToolBar classes.
- \o QDockWidget provides a widget that can be used to create
+ \li QDockWidget provides a widget that can be used to create
detachable tool palettes or helper windows. Dock widgets keep track
of their own properties, and they can be moved, closed, and floated
as external windows.
- \o QToolBar provides a generic toolbar widget that can hold a
+ \li QToolBar provides a generic toolbar widget that can hold a
number of different action-related widgets, such as buttons,
drop-down menus, comboboxes, and spin boxes. The emphasis on a
unified action model in Qt 4 means that toolbars cooperate well
diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp
index 8e7c04e9f07..d807bb63d91 100644
--- a/examples/animation/moveblocks/main.cpp
+++ b/examples/animation/moveblocks/main.cpp
@@ -50,7 +50,7 @@ public:
{
}
- StateSwitchEvent(int rand)
+ explicit StateSwitchEvent(int rand)
: QEvent(Type(StateSwitchType)),
m_rand(rand)
{
diff --git a/examples/opengl/cube/cube.pro b/examples/opengl/cube/cube.pro
index ef6f5260676..98a3082340a 100644
--- a/examples/opengl/cube/cube.pro
+++ b/examples/opengl/cube/cube.pro
@@ -1,9 +1,3 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2010-06-23T12:55:35
-#
-#-------------------------------------------------
-
QT += core gui widgets
TARGET = cube
@@ -12,7 +6,6 @@ TEMPLATE = app
SOURCES += main.cpp
contains(QT_CONFIG, opengl) {
- message(Building with OpenGL support.)
QT += opengl
SOURCES += mainwidget.cpp \
@@ -29,8 +22,6 @@ contains(QT_CONFIG, opengl) {
OTHER_FILES += \
vshader.glsl \
fshader.glsl
-} else {
- message(OpenGL support is not available.)
}
diff --git a/examples/sql/sqlbrowser/browser.cpp b/examples/sql/sqlbrowser/browser.cpp
index 3aa330e2270..eaaec25b16e 100644
--- a/examples/sql/sqlbrowser/browser.cpp
+++ b/examples/sql/sqlbrowser/browser.cpp
@@ -52,6 +52,12 @@ Browser::Browser(QWidget *parent)
table->addAction(insertRowAction);
table->addAction(deleteRowAction);
+ table->addAction(fieldStrategyAction);
+ table->addAction(rowStrategyAction);
+ table->addAction(manualStrategyAction);
+ table->addAction(submitAction);
+ table->addAction(revertAction);
+ table->addAction(selectAction);
if (QSqlDatabase::drivers().isEmpty())
QMessageBox::information(this, tr("No database drivers found"),
@@ -144,7 +150,7 @@ void Browser::addConnection()
void Browser::showTable(const QString &t)
{
- QSqlTableModel *model = new QSqlTableModel(table, connectionWidget->currentDatabase());
+ QSqlTableModel *model = new CustomModel(table, connectionWidget->currentDatabase());
model->setEditStrategy(QSqlTableModel::OnRowChange);
model->setTable(connectionWidget->currentDatabase().driver()->escapeIdentifier(t, QSqlDriver::TableName));
model->select();
@@ -215,8 +221,6 @@ void Browser::deleteRow()
if (!model)
return;
- model->setEditStrategy(QSqlTableModel::OnManualSubmit);
-
QModelIndexList currentSelection = table->selectionModel()->selectedIndexes();
for (int i = 0; i < currentSelection.count(); ++i) {
if (currentSelection.at(i).column() != 0)
@@ -224,24 +228,79 @@ void Browser::deleteRow()
model->removeRow(currentSelection.at(i).row());
}
- model->submitAll();
- model->setEditStrategy(QSqlTableModel::OnRowChange);
-
updateActions();
}
void Browser::updateActions()
{
- bool enableIns = qobject_cast(table->model());
+ QSqlTableModel * tm = qobject_cast(table->model());
+ bool enableIns = tm;
bool enableDel = enableIns && table->currentIndex().isValid();
insertRowAction->setEnabled(enableIns);
deleteRowAction->setEnabled(enableDel);
+
+ fieldStrategyAction->setEnabled(tm);
+ rowStrategyAction->setEnabled(tm);
+ manualStrategyAction->setEnabled(tm);
+ submitAction->setEnabled(tm);
+ revertAction->setEnabled(tm);
+ selectAction->setEnabled(tm);
+
+ if (tm) {
+ QSqlTableModel::EditStrategy es = tm->editStrategy();
+ fieldStrategyAction->setChecked(es == QSqlTableModel::OnFieldChange);
+ rowStrategyAction->setChecked(es == QSqlTableModel::OnRowChange);
+ manualStrategyAction->setChecked(es == QSqlTableModel::OnManualSubmit);
+ }
}
void Browser::about()
{
QMessageBox::about(this, tr("About"), tr("The SQL Browser demonstration "
"shows how a data browser can be used to visualize the results of SQL"
- "statements on a live database"));
+ "statements on a live database"));
}
+
+void Browser::on_fieldStrategyAction_triggered()
+{
+ QSqlTableModel * tm = qobject_cast(table->model());
+ if (tm)
+ tm->setEditStrategy(QSqlTableModel::OnFieldChange);
+}
+
+void Browser::on_rowStrategyAction_triggered()
+{
+ QSqlTableModel * tm = qobject_cast(table->model());
+ if (tm)
+ tm->setEditStrategy(QSqlTableModel::OnRowChange);
+}
+
+void Browser::on_manualStrategyAction_triggered()
+{
+ QSqlTableModel * tm = qobject_cast(table->model());
+ if (tm)
+ tm->setEditStrategy(QSqlTableModel::OnManualSubmit);
+}
+
+void Browser::on_submitAction_triggered()
+{
+ QSqlTableModel * tm = qobject_cast(table->model());
+ if (tm)
+ tm->submitAll();
+}
+
+void Browser::on_revertAction_triggered()
+{
+ QSqlTableModel * tm = qobject_cast(table->model());
+ if (tm)
+ tm->revertAll();
+}
+
+void Browser::on_selectAction_triggered()
+{
+ QSqlTableModel * tm = qobject_cast(table->model());
+ if (tm)
+ tm->select();
+}
+
diff --git a/examples/sql/sqlbrowser/browser.h b/examples/sql/sqlbrowser/browser.h
index 0769812ec86..e9f45345dfa 100644
--- a/examples/sql/sqlbrowser/browser.h
+++ b/examples/sql/sqlbrowser/browser.h
@@ -43,6 +43,7 @@
#define BROWSER_H
#include
+#include
#include "ui_browserwidget.h"
class ConnectionWidget;
@@ -77,6 +78,12 @@ public slots:
{ insertRow(); }
void on_deleteRowAction_triggered()
{ deleteRow(); }
+ void on_fieldStrategyAction_triggered();
+ void on_rowStrategyAction_triggered();
+ void on_manualStrategyAction_triggered();
+ void on_submitAction_triggered();
+ void on_revertAction_triggered();
+ void on_selectAction_triggered();
void on_connectionWidget_tableActivated(const QString &table)
{ showTable(table); }
void on_connectionWidget_metaDataRequested(const QString &table)
@@ -96,4 +103,17 @@ signals:
void statusMessage(const QString &message);
};
+class CustomModel: public QSqlTableModel
+{
+ Q_OBJECT
+public:
+ CustomModel(QObject *parent = 0, QSqlDatabase db = QSqlDatabase()):QSqlTableModel(parent, db) {}
+ QVariant data(const QModelIndex &idx, int role) const
+ {
+ if (role == Qt::BackgroundRole && isDirty(idx))
+ return QBrush(QColor(Qt::yellow));
+ return QSqlTableModel::data(idx, role);
+ }
+};
+
#endif
diff --git a/examples/sql/sqlbrowser/browserwidget.ui b/examples/sql/sqlbrowser/browserwidget.ui
index 20946f0ede3..ff65b1f199c 100644
--- a/examples/sql/sqlbrowser/browserwidget.ui
+++ b/examples/sql/sqlbrowser/browserwidget.ui
@@ -1,10 +1,8 @@
-
-
-
-
+
+Browser
-
-
+
+ 00
@@ -12,100 +10,90 @@
515
-
+ Qt SQL Browser
-
-
- 8
-
-
+
+ 6
+
+ 8
+
-
-
-
- 7
- 7
+
+
+ 00
-
+ Qt::Horizontal
-
-
-
- 13
- 7
+
+
+ 10
-
-
-
- 7
- 7
+
+
+ 20
-
+ Qt::ActionsContextMenu
-
+ QAbstractItemView::SelectRows
-
-
-
- 5
- 3
+
+
+ 00
-
+ 16777215180
-
+ SQL Query
-
-
- 9
-
-
+
+ 6
+
+ 9
+
-
-
-
- 7
- 3
+
+
+ 00
-
+ 018
-
+ 0120
@@ -114,19 +102,19 @@
-
-
- 1
-
-
+
+ 6
+
+ 1
+
-
+ Qt::Horizontal
-
+ 4020
@@ -135,15 +123,15 @@
-
-
+
+ &Clear
-
-
+
+ &Submit
@@ -154,37 +142,91 @@
-
-
+
+ false
-
+ &Insert Row
-
+ Inserts a new Row
-
-
+
+ false
-
+ &Delete Row
-
+ Deletes the current Row
+
+
+ true
+
+
+ Submit on &Field Change
+
+
+ Commit on Field Change
+
+
+
+
+ true
+
+
+ Submit on &Row Change
+
+
+ Commit on Row Change
+
+
+
+
+ true
+
+
+ Submit &Manually
+
+
+ Commit Manually
+
+
+
+
+ &Submit All
+
+
+ Submit Changes
+
+
+
+
+ &Revert All
+
+
+ Revert
+
+
+
+
+ S&elect
+
+
+ Refresh Data from Database
+
+
- ConnectionWidgetQTreeViewconnectionwidget.h
- 0
-
diff --git a/examples/webkit/webkit-guide/_index.html b/examples/webkit/webkit-guide/_index.html
index 5d7dd11d638..f3a1f9dfa66 100644
--- a/examples/webkit/webkit-guide/_index.html
+++ b/examples/webkit/webkit-guide/_index.html
@@ -298,7 +298,7 @@ entered (localStorage), but credit-card data s/b absent
X
diff --git a/examples/widgets/mousebuttons/buttontester.cpp b/examples/widgets/mousebuttons/buttontester.cpp
new file mode 100644
index 00000000000..32f73ebb72d
--- /dev/null
+++ b/examples/widgets/mousebuttons/buttontester.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Rick Stockton
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "buttontester.h"
+
+void ButtonTester::mousePressEvent(QMouseEvent *e)
+{
+ int j = ButtonTester::buttonByNumber (e->button());
+ QString result = "Mouse Press: raw button=" + QString::number(j) + " Qt=" + enumNameFromValue(e->button());
+ qDebug() << result;
+ this->setText(result);
+ if (j == 2) {
+ this->repaint();
+ }
+}
+
+void ButtonTester::mouseReleaseEvent(QMouseEvent *e)
+{
+ int j = ButtonTester::buttonByNumber (e->button());
+ QString result = "Mouse Release: raw button=" + QString::number(j) + " Qt=" + enumNameFromValue(e->button());
+ qDebug() << result;
+ this->setText(result);
+}
+
+void ButtonTester::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ int j = ButtonTester::buttonByNumber (e->button());
+ QString result = "Mouse DoubleClick: raw button=" + QString::number(j) + " Qt=" + enumNameFromValue(e->button());
+ qDebug() << result;
+ this->setText(result);
+}
+
+void ButtonTester::wheelEvent (QWheelEvent *e)
+{
+ QString result;
+ if (e->delta() > 0) {
+
+ if (e->orientation() == Qt::Vertical) {
+ result = "Mouse Wheel Event: UP";
+ } else {
+ result = "Mouse Wheel Event: LEFT";
+ }
+ } else if (e->delta() < 0) {
+ if (e->orientation() == Qt::Vertical) {
+ result = "Mouse Wheel Event: DOWN";
+ } else {
+ result = "Mouse Wheel Event: RIGHT";
+ }
+ }
+ qDebug() << result;
+ this->setText(result);
+}
+
+int ButtonTester::buttonByNumber(const Qt::MouseButton button)
+{
+ if (button == Qt::NoButton) return 0;
+ if (button == Qt::LeftButton) return 1;
+ if (button == Qt::RightButton) return 2;
+ if (button == Qt::MiddleButton) return 3;
+
+/* Please note that Qt Button #4 corresponds to button #8 on all
+ * platforms which EMULATE wheel events by creating button events
+ * (Button #4 = Scroll Up; Button #5 = Scroll Down; Button #6 = Scroll
+ * Left; and Button #7 = Scroll Right.) This includes X11, with both
+ * Xlib and XCB. So, the "raw button" for "Qt::BackButton" is
+ * usually described as "Button #8".
+
+ * If your platform supports "smooth scrolling", then, for the cases of
+ * Qt::BackButton and higher, this program will show "raw button" with a
+ * value which is too large. Subtract 4 to get the correct button ID for
+ * your platform.
+ */
+
+ if (button == Qt::BackButton) return 8;
+ if (button == Qt::ForwardButton) return 9;
+ if (button == Qt::TaskButton) return 10;
+ if (button == Qt::ExtraButton4) return 11;
+ if (button == Qt::ExtraButton5) return 12;
+ if (button == Qt::ExtraButton6) return 13;
+ if (button == Qt::ExtraButton7) return 14;
+ if (button == Qt::ExtraButton8) return 15;
+ if (button == Qt::ExtraButton9) return 16;
+ if (button == Qt::ExtraButton10) return 17;
+ if (button == Qt::ExtraButton11) return 18;
+ if (button == Qt::ExtraButton12) return 19;
+ if (button == Qt::ExtraButton13) return 20;
+ if (button == Qt::ExtraButton14) return 21;
+ if (button == Qt::ExtraButton15) return 22;
+ if (button == Qt::ExtraButton16) return 23;
+ if (button == Qt::ExtraButton17) return 24;
+ if (button == Qt::ExtraButton18) return 25;
+ if (button == Qt::ExtraButton19) return 26;
+ if (button == Qt::ExtraButton20) return 27;
+ if (button == Qt::ExtraButton21) return 28;
+ if (button == Qt::ExtraButton22) return 29;
+ if (button == Qt::ExtraButton23) return 30;
+ if (button == Qt::ExtraButton24) return 31;
+ qDebug("QMouseShortcutEntry::addShortcut contained Invalid Qt::MouseButton value");
+ return 0;
+}
+
+QString ButtonTester::enumNameFromValue(const Qt::MouseButton button)
+{
+ if (button == Qt::NoButton) return "NoButton";
+ if (button == Qt::LeftButton) return "LeftButton";
+ if (button == Qt::RightButton) return "RightButton";
+ if (button == Qt::MiddleButton) return "MiddleButton";
+ if (button == Qt::BackButton) return "BackButton";
+ if (button == Qt::ForwardButton) return "ForwardButton";
+ if (button == Qt::TaskButton) return "TaskButton";
+ if (button == Qt::ExtraButton4) return "ExtraButton4";
+ if (button == Qt::ExtraButton5) return "ExtraButton5";
+ if (button == Qt::ExtraButton6) return "ExtraButton6";
+ if (button == Qt::ExtraButton7) return "ExtraButton7";
+ if (button == Qt::ExtraButton8) return "ExtraButton8";
+ if (button == Qt::ExtraButton9) return "ExtraButton9";
+ if (button == Qt::ExtraButton10) return "ExtraButton10";
+ if (button == Qt::ExtraButton11) return "ExtraButton11";
+ if (button == Qt::ExtraButton12) return "ExtraButton12";
+ if (button == Qt::ExtraButton13) return "ExtraButton13";
+ if (button == Qt::ExtraButton14) return "ExtraButton14";
+ if (button == Qt::ExtraButton15) return "ExtraButton15";
+ if (button == Qt::ExtraButton16) return "ExtraButton16";
+ if (button == Qt::ExtraButton17) return "ExtraButton17";
+ if (button == Qt::ExtraButton18) return "ExtraButton18";
+ if (button == Qt::ExtraButton19) return "ExtraButton19";
+ if (button == Qt::ExtraButton20) return "ExtraButton20";
+ if (button == Qt::ExtraButton21) return "ExtraButton21";
+ if (button == Qt::ExtraButton22) return "ExtraButton22";
+ if (button == Qt::ExtraButton23) return "ExtraButton23";
+ if (button == Qt::ExtraButton24) return "ExtraButton24";
+ qDebug("QMouseShortcutEntry::addShortcut contained Invalid Qt::MouseButton value");
+ return "NoButton";
+}
diff --git a/examples/widgets/mousebuttons/buttontester.h b/examples/widgets/mousebuttons/buttontester.h
new file mode 100644
index 00000000000..0801a9ae5c4
--- /dev/null
+++ b/examples/widgets/mousebuttons/buttontester.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Rick Stockton
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BUTTONTESTER_H
+#define BUTTONTESTER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+class ButtonTester : public QTextEdit
+{
+ Q_OBJECT
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent * event);
+ int buttonByNumber(const Qt::MouseButton button);
+ QString enumNameFromValue(const Qt::MouseButton button);
+};
+
+#endif // BUTTONTESTER_H
diff --git a/examples/widgets/mousebuttons/main.cpp b/examples/widgets/mousebuttons/main.cpp
new file mode 100644
index 00000000000..7c9674a9d9f
--- /dev/null
+++ b/examples/widgets/mousebuttons/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2012 Rick Stockton
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "buttontester.h"
+#include
+
+int main(int argv, char **args)
+{
+ QApplication app(argv, args);
+
+ ButtonTester *testArea = new ButtonTester;
+ testArea->setMinimumSize(500, 350);
+ testArea->setText("To test your mouse with Qt, press buttons in this area.\nYou may also scroll or tilt your mouse wheel.");
+ QPushButton *quitButton = new QPushButton("Quit");
+
+ QObject::connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(testArea);
+ layout->addWidget(quitButton);
+
+ QWidget window;
+ window.setLayout(layout);
+ window.setWindowTitle("Mouse Button Tester");
+ window.show();
+
+ return app.exec();
+}
diff --git a/examples/widgets/mousebuttons/mousebuttons.pro b/examples/widgets/mousebuttons/mousebuttons.pro
new file mode 100644
index 00000000000..823b04657e6
--- /dev/null
+++ b/examples/widgets/mousebuttons/mousebuttons.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+
+TARGET = buttontester
+TEMPLATE = app
+
+SOURCES += \
+ main.cpp\
+ buttontester.cpp \
+
+HEADERS += \
+ buttontester.h \
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/qtbase/examples/widgets/mousebuttons
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS buttontester.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/qtbase/examples/widgets/mousebuttons
+INSTALLS += target sources
+QT += core widgets
diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro
index 51a92bcc29e..f5c98c3c778 100644
--- a/examples/widgets/widgets.pro
+++ b/examples/widgets/widgets.pro
@@ -12,6 +12,7 @@ SUBDIRS = analogclock \
imageviewer \
lineedits \
movie \
+ mousebuttons \
orientation \
scribble \
shapedclock \
diff --git a/mkspecs/aix-g++-64/qmake.conf b/mkspecs/aix-g++-64/qmake.conf
index b0179d56032..5a73aeb8c18 100644
--- a/mkspecs/aix-g++-64/qmake.conf
+++ b/mkspecs/aix-g++-64/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthreads
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar -X64 cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib -X64
diff --git a/mkspecs/aix-g++/qmake.conf b/mkspecs/aix-g++/qmake.conf
index 2e2e991f54d..9ddb1619abd 100644
--- a/mkspecs/aix-g++/qmake.conf
+++ b/mkspecs/aix-g++/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthreads
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/aix-xlc-64/qmake.conf b/mkspecs/aix-xlc-64/qmake.conf
index 486b8c6f0fc..db5ddc33cd4 100644
--- a/mkspecs/aix-xlc-64/qmake.conf
+++ b/mkspecs/aix-xlc-64/qmake.conf
@@ -66,9 +66,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthreads
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar -X64 cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib -X64
diff --git a/mkspecs/aix-xlc/qmake.conf b/mkspecs/aix-xlc/qmake.conf
index 8655db6d820..ff83a457026 100644
--- a/mkspecs/aix-xlc/qmake.conf
+++ b/mkspecs/aix-xlc/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthreads
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib
diff --git a/mkspecs/cmake/Qt5BasicConfig.cmake.in b/mkspecs/cmake/Qt5BasicConfig.cmake.in
index 45a0722ef5e..0334b6f6e2b 100644
--- a/mkspecs/cmake/Qt5BasicConfig.cmake.in
+++ b/mkspecs/cmake/Qt5BasicConfig.cmake.in
@@ -35,6 +35,57 @@ if (Qt5$${CMAKE_MODULE_NAME}_EXECUTABLE_COMPILE_FLAGS)
list(REMOVE_DUPLICATES Qt5$${CMAKE_MODULE_NAME}_EXECUTABLE_COMPILE_FLAGS)
endif()
+!!IF !isEmpty(CMAKE_STATIC_TYPE)
+# For static builds, we also list the dependencies of
+# Qt so that consumers can build.
+
+!!IF isEqual(CMAKE_MODULE_NAME, Core)
+
+set(Qt5Core_LIB_DEPENDENCIES)
+!!IF contains(QT_CONFIG, system-zlib)
+find_package(ZLIB REQUIRED)
+list(APPEND Qt5Core_LIB_DEPENDENCIES ${ZLIB_LIBRARIES})
+!!ENDIF
+
+!!IF contains(QT_CONFIG, glib)
+find_package(GTK2 REQUIRED glib-2.0 gthread-2.0)
+list(APPEND Qt5Core_LIB_DEPENDENCIES ${GTK2_LIBRARIES})
+!!ENDIF
+
+!!IF contains(QT_CONFIG, clock-monotonic)
+find_library(QT_RT_LIBRARY NAMES rt)
+mark_as_advanced(QT_RT_LIBRARY)
+list(APPEND Qt5Core_LIB_DEPENDENCIES ${QT_RT_LIBRARY})
+!!ENDIF
+
+set(CMAKE_THREAD_PREFER_PTHREADS 1)
+find_package(Threads)
+if(CMAKE_USE_PTHREADS_INIT)
+ list(APPEND Qt5Core_LIB_DEPENDENCIES ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
+endif()
+
+!!ENDIF # Core
+
+!!IF isEqual(CMAKE_MODULE_NAME, Gui)
+
+set(Qt5Gui_LIB_DEPENDENCIES)
+
+!!IF contains(QT_CONFIG, system-png)
+find_package(PNG REQUIRED)
+list(APPEND Qt5Gui_LIB_DEPENDENCIES ${PNG_LIBRARIES})
+!!ENDIF
+
+!!IF contains(QT_CONFIG, system-jpeg)
+find_package(JPEG REQUIRED)
+list(APPEND Qt5Gui_LIB_DEPENDENCIES ${JPEG_LIBRARIES})
+!!ENDIF
+
+!!ENDIF # Gui
+
+!!ENDIF # Static
+
+list(APPEND Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES "$${CMAKE_QT5_MODULE_DEPS}")
+
if (NOT _Qt5$${CMAKE_MODULE_NAME}_target)
set(_Qt5$${CMAKE_MODULE_NAME}_target 1)
!!IF !isEmpty(CMAKE_STATIC_TYPE)
@@ -50,7 +101,7 @@ endif()
!!IF !isEmpty(debug_type)
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES
- IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG \"$${CMAKE_QT5_MODULE_DEPS}\"
+ IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG \"${Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\"
!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE)
IMPORTED_LOCATION_DEBUG \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_DEBUG}\"
!!ELSE
@@ -67,7 +118,7 @@ set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES
!!IF !isEmpty(release_type)
set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES
- IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE \"$${CMAKE_QT5_MODULE_DEPS}\"
+ IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE \"${Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\"
!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE)
IMPORTED_LOCATION_RELEASE \"${_qt5_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_LIB_FILE_LOCATION_RELEASE}\"
!!ELSE
diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf
index f8f007bada6..384c013309c 100644
--- a/mkspecs/common/linux.conf
+++ b/mkspecs/common/linux.conf
@@ -34,6 +34,7 @@ QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_LIBUDEV = -ludev
QMAKE_CFLAGS_WAYLAND =
QMAKE_INCDIR_WAYLAND =
@@ -46,9 +47,6 @@ QMAKE_CFLAGS_XCB =
QMAKE_LIBS_XCB =
QMAKE_DEFINES_XCB =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf
index b22b8520138..6ba55325e89 100644
--- a/mkspecs/common/mac.conf
+++ b/mkspecs/common/mac.conf
@@ -21,9 +21,6 @@ QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_RANLIB = ranlib -s
diff --git a/mkspecs/cygwin-g++/qmake.conf b/mkspecs/cygwin-g++/qmake.conf
index c46384fc8b0..ece21e226f4 100644
--- a/mkspecs/cygwin-g++/qmake.conf
+++ b/mkspecs/cygwin-g++/qmake.conf
@@ -72,9 +72,6 @@ QMAKE_PREFIX_SHLIB = lib
QMAKE_PREFIX_STATICLIB = lib
QMAKE_EXTENSION_STATICLIB = a
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/darwin-g++/qmake.conf b/mkspecs/darwin-g++/qmake.conf
index 84dc764e6b2..c059f0cb6ff 100644
--- a/mkspecs/darwin-g++/qmake.conf
+++ b/mkspecs/darwin-g++/qmake.conf
@@ -78,9 +78,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib -s
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index 1aa8ae55440..6a8045ab3bb 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -24,7 +24,7 @@ CMAKE_PARTIAL_MODULE_DEPS = $$replace(CMAKE_MODULE_DEPS, ";", ";Qt5::")
CMAKE_QT_INSTALL_PREFIX = $$replace($$list($$[QT_INSTALL_PREFIX]), \\\\, /)/
CMAKE_QT_INSTALL_PREFIX_ESCAPED = "^$$re_escape($$CMAKE_QT_INSTALL_PREFIX)"
-CMAKE_INCLUDE_DIR = $$[QT_INSTALL_HEADERS]
+CMAKE_INCLUDE_DIR = $$replace($$list($$[QT_INSTALL_HEADERS]), \\\\, /)/
contains(CMAKE_INCLUDE_DIR, "$${CMAKE_QT_INSTALL_PREFIX_ESCAPED}.*") {
CMAKE_INCLUDE_DIR = $$replace(CMAKE_INCLUDE_DIR, "$$CMAKE_QT_INSTALL_PREFIX_ESCAPED", )
} else {
diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf
index 1a56787d158..5d8684bf001 100644
--- a/mkspecs/features/default_pre.prf
+++ b/mkspecs/features/default_pre.prf
@@ -26,10 +26,10 @@ CONFIG = lex yacc warn_on debug uic resources $$CONFIG
# can we tell syncqt to do a -developer-build
win32 {
CMP_QDIR = $$upper($$QTDIR)
- CMP_INSTALL_PREFIX = $$upper($$[QT_INSTALL_PREFIX])
+ CMP_INSTALL_PREFIX = $$upper($$[QT_HOST_PREFIX])
} else {
CMP_QDIR = $$QTDIR
- CMP_INSTALL_PREFIX = $$[QT_INSTALL_PREFIX]
+ CMP_INSTALL_PREFIX = $$[QT_HOST_PREFIX]
}
contains(CMP_QDIR, $$CMP_INSTALL_PREFIX):QTFWD = -qtdir $$QTDIR -module-fwd $$QTDIR/mkspecs/modules -developer-build
unset(CMP_QDIR)
@@ -46,6 +46,10 @@ CONFIG = lex yacc warn_on debug uic resources $$CONFIG
} else {
error("Failed to run: $$MSG")
}
+
+ # Let qmake know about the unexpectedly appearing cache file.
+ contains(QTFWD, -cache-module-fwd):_QMAKE_CACHE_ = $$QMAKE_SYNCQT_OUTDIR/.qmake.cache
+
unset(QTFWD)
unset(PRO_BASENAME)
}
diff --git a/mkspecs/features/module.prf b/mkspecs/features/module.prf
index 85639f03450..d95c7a418d6 100644
--- a/mkspecs/features/module.prf
+++ b/mkspecs/features/module.prf
@@ -1,5 +1,5 @@
!isEmpty(MODULE_PRI) {
- pritarget.path = $$[QT_INSTALL_DATA]/mkspecs/modules
+ pritarget.path = $$[QT_HOST_DATA]/mkspecs/modules
pritarget.files = $$MODULE_PRI
INSTALLS += pritarget
} else {
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index 60813429295..21443aa5b52 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -1,5 +1,32 @@
CONFIG *= moc thread
+# Temporary fixes to avoid QDeclarative -> QQml breakage:
+
+# Projects depending on declarative will now get the full set of
+# -DOldSymbol=NewSymbol definitions added to their configuration
+# so that the old symbol names still compile. All code previously
+# in the declarative library is now in the qml library.
+contains(QT, qmldevtools):!contains(QT, declarative) {
+ QT += declarative
+}
+contains(QT, qmldevtools-private):!contains(QT, declarative-private) {
+ QT += declarative-private
+}
+
+contains(QT, quick):!contains(QT, declarative) {
+ QT += declarative
+}
+contains(QT, quick-private):!contains(QT, declarative-private) {
+ QT += declarative-private
+}
+
+contains(QT, declarative):!contains(QT, qml) {
+ QT += qml
+}
+contains(QT, declarative-private):!contains(QT, qml-private) {
+ QT += qml-private
+}
+
#handle defines
win32 {
qt_static:DEFINES += QT_NODLL
@@ -125,21 +152,22 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) {
!isEmpty(QT_BUILD_TREE):QMAKE_LIBDIR = $$QT_BUILD_TREE/lib $$QMAKE_LIBDIR #as above, prepending prevents us from picking up "stale" libs
QMAKE_LIBDIR += $$QMAKE_LIBDIR_QT
-# Topological ordering of modules based on their QT..depends variable
-QT = $$sort_depends(QT, "QT.")
-
-QT_DEPENDS=
-
+# Figure out from which modules we're wanting to use the private headers
unset(using_privates)
+NEWQT =
for(QTLIB, QT) {
- # Figure out if we're wanting to use the private headers of a module
- contains(QTLIB, .*-private) {
- QTLIB ~= s/-private//
- use_private = UsePrivate
- } else {
- use_private = NoPrivate
+ QTLIBRAW = $$replace(QTLIB, -private$, )
+ !isEqual(QTLIBRAW, $$QTLIB) {
+ want_var = QT.$${QTLIBRAW}.want_private
+ $$want_var = UsePrivate
+ using_privates = true
}
-
+ NEWQT += $$QTLIBRAW
+}
+# Topological resolution of modules based on their QT..depends variable
+QT = $$resolve_depends(NEWQT, "QT.")
+# Finally actually add the modules
+for(QTLIB, QT) {
isEmpty(QT.$${QTLIB}.name) {
message("Warning: unknown QT module: $$QTLIB")
next()
@@ -149,14 +177,9 @@ for(QTLIB, QT) {
warning($$TARGET cannot have a QT of $$QTLIB)
next()
}
- qtAddModule($$QTLIB, $$use_private)
- QT_DEPENDS += $$eval(QT.$${QTLIB}.depends)
- isEqual(use_private, UsePrivate):using_privates = true
-}
-# add include paths for all .depends, since module/application might need f.ex. template specializations etc.
-QT_DEPENDS -= $$QT
-for(QTLIB, $$list($$lower($$unique(QT_DEPENDS)))):INCLUDEPATH *= $$INCLUDEPATH $$eval(QT.$${QTLIB}.includes)
+ qtAddModule($$QTLIB, $$eval(QT.$${QTLIB}.want_private))
+}
!isEmpty(using_privates):!no_private_qt_headers_warning:if(!debug_and_release|!build_pass) {
message("This project is using private headers and will therefore be tied to this specific Qt module build version.")
diff --git a/mkspecs/features/qt_config.prf b/mkspecs/features/qt_config.prf
index 84417288159..8d0dcce92c0 100644
--- a/mkspecs/features/qt_config.prf
+++ b/mkspecs/features/qt_config.prf
@@ -8,7 +8,7 @@ exists($$_QMAKE_CACHE_) {
isEmpty(QMAKE_QT_CONFIG)|!exists($$QMAKE_QT_CONFIG) {
!isEmpty(QT_BUILD_TREE):QMAKE_QT_CONFIG = $$QT_BUILD_TREE
else:exists($$_QMAKE_CACHE_):QMAKE_QT_CONFIG = $$fromfile($$_QMAKE_CACHE_, QT_BUILD_TREE)
- isEmpty(QMAKE_QT_CONFIG):QMAKE_QT_CONFIG = $$[QT_INSTALL_DATA]
+ isEmpty(QMAKE_QT_CONFIG):QMAKE_QT_CONFIG = $$[QT_HOST_DATA]
QMAKE_QT_CONFIG = $$QMAKE_QT_CONFIG/mkspecs/qconfig.pri
}
!exists($$QMAKE_QT_CONFIG)|!include($$QMAKE_QT_CONFIG, "", true) {
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 65eec35bfc4..31b28156e83 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -132,7 +132,7 @@ defineTest(qtAddModule) {
isEmpty(LINKAGE) {
# Make sure we can link to uninstalled libraries
- !isEqual(MODULE_LIBS, $$[QT_INSTALL_LIBS]) {
+ !isEqual(MODULE_LIBS, $$[QT_INSTALL_LIBS]) { ### XXX
QMAKE_LIBDIR *= $$MODULE_LIBS
unix:!mac:QMAKE_LFLAGS *= "-Wl,-rpath-link,$$MODULE_LIBS"
}
@@ -164,7 +164,7 @@ defineTest(qtAddModule) {
# variable, default
defineTest(qtPrepareTool) {
- MODBASE = $$[QT_INSTALL_BINS]
+ MODBASE = $$[QT_HOST_BINS]
!isEmpty(QT_BUILD_TREE):MODBASE = $$QT_BUILD_TREE/bin
count(ARGS, 2, greaterThan) {
isEmpty(QT.$${3}.bins):warning("No QT.$${3}.bins, module path ignored for qtPrepareTool($$1, $$2, $$3)")
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index aee95295e82..b71ef612525 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -8,7 +8,7 @@ isEmpty(QMAKE_QT_MODULE)|!exists($$QMAKE_QT_MODULE) {
!exists($$QMAKE_QT_MODULE):exists($$QMAKE_CACHE_DIR/mkspecs/qmodule.pri):QMAKE_QT_MODULE = $$QMAKE_CACHE_DIR/mkspecs/qmodule.pri
!exists($$QMAKE_QT_MODULE):exists($$QMAKE_CACHE_DIR/qtbase/mkspecs/qmodule.pri):QMAKE_QT_MODULE = $$QMAKE_CACHE_DIR/qtbase/mkspecs/qmodule.pri
!exists($$QMAKE_QT_MODULE):if(!isEmpty(QT_BUILD_TREE) & exists($$QT_BUILD_TREE/mkspecs/qmodule.pri)):QMAKE_QT_MODULE = $$QT_BUILD_TREE/mkspecs/qmodule.pri
- !exists($$QMAKE_QT_MODULE):exists($$[QT_INSTALL_DATA]/mkspecs/qmodule.pri):QMAKE_QT_MODULE = $$[QT_INSTALL_DATA]/mkspecs/qmodule.pri
+ !exists($$QMAKE_QT_MODULE):exists($$[QT_HOST_DATA]/mkspecs/qmodule.pri):QMAKE_QT_MODULE = $$[QT_HOST_DATA]/mkspecs/qmodule.pri
}
!contains(QMAKE_INTERNAL_INCLUDED_FILES, .*qmodule\\.pri) {
diff --git a/mkspecs/features/qt_module_config.prf b/mkspecs/features/qt_module_config.prf
index a8439198dfa..98cdab121f3 100644
--- a/mkspecs/features/qt_module_config.prf
+++ b/mkspecs/features/qt_module_config.prf
@@ -116,31 +116,27 @@ embedded:DEPENDPATH += ;$$EMBEDDED_H
#install directives
load(qt_installs)
-unix {
- CONFIG += create_libtool create_pc explicitlib
- QMAKE_LIBTOOL_LIBDIR = $$[QT_INSTALL_LIBS]
- QMAKE_PRL_LIBDIR = $$[QT_INSTALL_LIBS]
- QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS]
- QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS]/$$TARGET
- QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_INSTALL_HEADERS]
+unix|win32-g++* {
+ CONFIG += create_pc
+ QMAKE_PKGCONFIG_LIBDIR = $$[QT_RAW_INSTALL_LIBS]
+ QMAKE_PKGCONFIG_INCDIR = $$[QT_RAW_INSTALL_HEADERS]/$$TARGET
+ QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_RAW_INSTALL_HEADERS]
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
include_replace.match = $$QMAKE_INCDIR_QT
- include_replace.replace = $$[QT_INSTALL_HEADERS]
+ include_replace.replace = $$[QT_RAW_INSTALL_HEADERS]
lib_replace.match = $$QMAKE_LIBDIR_QT
- lib_replace.replace = $$[QT_INSTALL_LIBS]
+ lib_replace.replace = $$[QT_RAW_INSTALL_LIBS]
prefix_replace.match = $$QT_BUILD_TREE
- prefix_replace.replace = $$[QT_INSTALL_PREFIX]
- QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace
- QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace
+ prefix_replace.replace = $$[QT_RAW_INSTALL_PREFIX]
QMAKE_PKGCONFIG_INSTALL_REPLACE += include_replace lib_replace prefix_replace
}
-win32-g++* {
- CONFIG += create_pc
- QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS]
- QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS]/$$TARGET
- QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_INSTALL_HEADERS]
- QMAKE_PKGCONFIG_DESTDIR = pkgconfig
+unix {
+ CONFIG += create_libtool explicitlib
+ QMAKE_PRL_LIBDIR = $$[QT_RAW_INSTALL_LIBS] ### XXX
+ QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace
+ QMAKE_LIBTOOL_LIBDIR = $$[QT_RAW_INSTALL_LIBS]
+ QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace
}
contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
diff --git a/mkspecs/features/testcocoon.prf b/mkspecs/features/testcocoon.prf
index e6ad733540d..523497dba16 100644
--- a/mkspecs/features/testcocoon.prf
+++ b/mkspecs/features/testcocoon.prf
@@ -11,10 +11,10 @@ TARGET_BASENAME = $$basename(QMAKE_RESOLVED_TARGET)
# --cs-output defines the name to give to the execution report (.csexe).
TESTCOCOON_COVERAGE_OPTIONS = \
--cs-qt4 \
- --cs-exclude-file-regex=\'(^|[/\\\\])ui_.*\\.h\$\$\' \
--cs-exclude-file-regex=\'(^|[/\\\\])(qrc|moc)_.*\\.cpp\$\$\' \
--cs-exclude-file-regex=\'.*\\.moc\$\$\' \
--cs-exclude-file-regex=\'.*\\.g\$\$\' \
+ --cs-exclude-file-regex=\'.*\\.h\$\$\' \
--cs-output=\'$$TARGET_BASENAME\' # name of the csexe file (execution report)
# The .csmes file should be placed alongside the .so or binary.
diff --git a/mkspecs/freebsd-g++/qmake.conf b/mkspecs/freebsd-g++/qmake.conf
index 9d7c4431d84..f1db098c199 100644
--- a/mkspecs/freebsd-g++/qmake.conf
+++ b/mkspecs/freebsd-g++/qmake.conf
@@ -32,9 +32,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/freebsd-g++34/qmake.conf b/mkspecs/freebsd-g++34/qmake.conf
index 0f529934517..ee597de6c50 100644
--- a/mkspecs/freebsd-g++34/qmake.conf
+++ b/mkspecs/freebsd-g++34/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/freebsd-g++40/qmake.conf b/mkspecs/freebsd-g++40/qmake.conf
index bf4271126a2..331c267b9eb 100644
--- a/mkspecs/freebsd-g++40/qmake.conf
+++ b/mkspecs/freebsd-g++40/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/freebsd-icc/qmake.conf b/mkspecs/freebsd-icc/qmake.conf
index acc8f14b3ac..fc7251bcbf4 100644
--- a/mkspecs/freebsd-icc/qmake.conf
+++ b/mkspecs/freebsd-icc/qmake.conf
@@ -90,9 +90,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpux-acc-64/qmake.conf b/mkspecs/hpux-acc-64/qmake.conf
index b9aaf5ab242..de0fff1d91f 100644
--- a/mkspecs/hpux-acc-64/qmake.conf
+++ b/mkspecs/hpux-acc-64/qmake.conf
@@ -111,9 +111,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL -lXt
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpux-acc-o64/qmake.conf b/mkspecs/hpux-acc-o64/qmake.conf
index 389e813dba4..5773566b9e6 100644
--- a/mkspecs/hpux-acc-o64/qmake.conf
+++ b/mkspecs/hpux-acc-o64/qmake.conf
@@ -109,9 +109,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpux-acc/qmake.conf b/mkspecs/hpux-acc/qmake.conf
index d1b6e5ce56f..6bc226c7e29 100644
--- a/mkspecs/hpux-acc/qmake.conf
+++ b/mkspecs/hpux-acc/qmake.conf
@@ -90,9 +90,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL -lXt
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpux-g++-64/qmake.conf b/mkspecs/hpux-g++-64/qmake.conf
index f796496c56a..1f478ccca48 100644
--- a/mkspecs/hpux-g++-64/qmake.conf
+++ b/mkspecs/hpux-g++-64/qmake.conf
@@ -73,9 +73,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpux-g++/qmake.conf b/mkspecs/hpux-g++/qmake.conf
index e9891e79f1c..6685fe1a5e2 100644
--- a/mkspecs/hpux-g++/qmake.conf
+++ b/mkspecs/hpux-g++/qmake.conf
@@ -73,9 +73,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpuxi-acc-32/qmake.conf b/mkspecs/hpuxi-acc-32/qmake.conf
index d7e4a0ad345..53d05b7450e 100644
--- a/mkspecs/hpuxi-acc-32/qmake.conf
+++ b/mkspecs/hpuxi-acc-32/qmake.conf
@@ -65,9 +65,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL -lXt
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpuxi-acc-64/qmake.conf b/mkspecs/hpuxi-acc-64/qmake.conf
index 3ed9b550731..d5d51a9deab 100644
--- a/mkspecs/hpuxi-acc-64/qmake.conf
+++ b/mkspecs/hpuxi-acc-64/qmake.conf
@@ -108,9 +108,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL -lXt
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hpuxi-g++-64/qmake.conf b/mkspecs/hpuxi-g++-64/qmake.conf
index a8f445ca00c..9d4daae5c39 100644
--- a/mkspecs/hpuxi-g++-64/qmake.conf
+++ b/mkspecs/hpuxi-g++-64/qmake.conf
@@ -76,9 +76,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
QMAKE_LIBS_YACC = -ly
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/hurd-g++/qmake.conf b/mkspecs/hurd-g++/qmake.conf
index 09a72fa0d78..e7416cd9f61 100644
--- a/mkspecs/hurd-g++/qmake.conf
+++ b/mkspecs/hurd-g++/qmake.conf
@@ -42,9 +42,6 @@ QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/irix-cc-64/qmake.conf b/mkspecs/irix-cc-64/qmake.conf
index ec94824be6b..ac5f3b58479 100644
--- a/mkspecs/irix-cc-64/qmake.conf
+++ b/mkspecs/irix-cc-64/qmake.conf
@@ -98,9 +98,6 @@ QMAKE_LIBS_OPENGL = -lGL -lm
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = CC -ar -o
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/irix-cc/qmake.conf b/mkspecs/irix-cc/qmake.conf
index 777da9b5db4..eaec795f2ab 100644
--- a/mkspecs/irix-cc/qmake.conf
+++ b/mkspecs/irix-cc/qmake.conf
@@ -98,9 +98,6 @@ QMAKE_LIBS_OPENGL = -lGL -lm
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = CC -ar -o
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/irix-g++-64/qmake.conf b/mkspecs/irix-g++-64/qmake.conf
index aa853dedfe8..2dcd690c5a1 100644
--- a/mkspecs/irix-g++-64/qmake.conf
+++ b/mkspecs/irix-g++-64/qmake.conf
@@ -71,9 +71,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/irix-g++/qmake.conf b/mkspecs/irix-g++/qmake.conf
index 77d47a9ce99..c532a35f6f7 100644
--- a/mkspecs/irix-g++/qmake.conf
+++ b/mkspecs/irix-g++/qmake.conf
@@ -71,9 +71,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/linux-cxx/qmake.conf b/mkspecs/linux-cxx/qmake.conf
index 79aa834a90e..0bd11937306 100644
--- a/mkspecs/linux-cxx/qmake.conf
+++ b/mkspecs/linux-cxx/qmake.conf
@@ -63,9 +63,6 @@ QMAKE_LIBS_NIS = -lnsl
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_RANLIB =
diff --git a/mkspecs/linux-ecc-64/qmake.conf b/mkspecs/linux-ecc-64/qmake.conf
index 50f841f1d4e..a4b9e03f2c1 100644
--- a/mkspecs/linux-ecc-64/qmake.conf
+++ b/mkspecs/linux-ecc-64/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf
index 4ff63cda710..49a3306538f 100644
--- a/mkspecs/linux-icc/qmake.conf
+++ b/mkspecs/linux-icc/qmake.conf
@@ -74,9 +74,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = xiar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/linux-kcc/qmake.conf b/mkspecs/linux-kcc/qmake.conf
index 23fd6298ac5..ab1847f42d4 100644
--- a/mkspecs/linux-kcc/qmake.conf
+++ b/mkspecs/linux-kcc/qmake.conf
@@ -76,9 +76,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/linux-pgcc/qmake.conf b/mkspecs/linux-pgcc/qmake.conf
index ed882156098..80b4cc28ba0 100644
--- a/mkspecs/linux-pgcc/qmake.conf
+++ b/mkspecs/linux-pgcc/qmake.conf
@@ -67,9 +67,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/lynxos-g++/qmake.conf b/mkspecs/lynxos-g++/qmake.conf
index 6b6f4057bfd..500dc498eed 100644
--- a/mkspecs/lynxos-g++/qmake.conf
+++ b/mkspecs/lynxos-g++/qmake.conf
@@ -70,9 +70,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/macx-xcode/qmake.conf b/mkspecs/macx-xcode/qmake.conf
index 4cb462696e4..de145620397 100644
--- a/mkspecs/macx-xcode/qmake.conf
+++ b/mkspecs/macx-xcode/qmake.conf
@@ -13,8 +13,6 @@ include(../common/mac.conf)
include(../common/gcc-base-macx.conf)
include(../common/g++-macx.conf)
-QMAKE_CC =
-QMAKE_CXX =
QMAKE_LINK =
QMAKE_LINK_C =
QMAKE_LINK_C_SHLIB =
diff --git a/mkspecs/macx-xlc/qmake.conf b/mkspecs/macx-xlc/qmake.conf
index f84524bbdf4..77c300a4aec 100644
--- a/mkspecs/macx-xlc/qmake.conf
+++ b/mkspecs/macx-xlc/qmake.conf
@@ -77,9 +77,6 @@ QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
#QMAKE_LIBS_THREAD = -lpthreads
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib -s
diff --git a/mkspecs/netbsd-g++/qmake.conf b/mkspecs/netbsd-g++/qmake.conf
index ab4b7c374cf..17609f2fb7e 100644
--- a/mkspecs/netbsd-g++/qmake.conf
+++ b/mkspecs/netbsd-g++/qmake.conf
@@ -68,9 +68,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib
diff --git a/mkspecs/openbsd-g++/qmake.conf b/mkspecs/openbsd-g++/qmake.conf
index 56d94160e35..1539c469603 100644
--- a/mkspecs/openbsd-g++/qmake.conf
+++ b/mkspecs/openbsd-g++/qmake.conf
@@ -69,9 +69,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar q
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB = ranlib
diff --git a/mkspecs/sco-cc/qmake.conf b/mkspecs/sco-cc/qmake.conf
index 179b774e03e..4cb71db5208 100644
--- a/mkspecs/sco-cc/qmake.conf
+++ b/mkspecs/sco-cc/qmake.conf
@@ -63,9 +63,6 @@ QMAKE_LIBS_X11SM = -lSM -lICE
QMAKE_LIBS_OPENGL = -lGL -lXt
QMAKE_LIBS_OPENGL_QT = -lGL
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/sco-g++/qmake.conf b/mkspecs/sco-g++/qmake.conf
index 9b321a486a0..b4839eb5713 100644
--- a/mkspecs/sco-g++/qmake.conf
+++ b/mkspecs/sco-g++/qmake.conf
@@ -64,9 +64,6 @@ QMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lm
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/solaris-cc-64/qmake.conf b/mkspecs/solaris-cc-64/qmake.conf
index 80709af5f41..b28c4505c92 100644
--- a/mkspecs/solaris-cc-64/qmake.conf
+++ b/mkspecs/solaris-cc-64/qmake.conf
@@ -88,9 +88,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread -lrt
QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet -lnsl
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = CC -xar -o
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/solaris-cc/qmake.conf b/mkspecs/solaris-cc/qmake.conf
index 0672841acc2..e29d37bc877 100644
--- a/mkspecs/solaris-cc/qmake.conf
+++ b/mkspecs/solaris-cc/qmake.conf
@@ -71,9 +71,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread -lrt
QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet -lnsl
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = CC -xar -o
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/solaris-g++-64/qmake.conf b/mkspecs/solaris-g++-64/qmake.conf
index 7bc7b9fd604..c08212765d6 100644
--- a/mkspecs/solaris-g++-64/qmake.conf
+++ b/mkspecs/solaris-g++-64/qmake.conf
@@ -92,9 +92,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread -lrt
QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet -lnsl
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/solaris-g++/qmake.conf b/mkspecs/solaris-g++/qmake.conf
index be21cdd1da8..5c9909210f9 100644
--- a/mkspecs/solaris-g++/qmake.conf
+++ b/mkspecs/solaris-g++/qmake.conf
@@ -75,9 +75,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread -lrt
QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet -lnsl
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/tru64-cxx/qmake.conf b/mkspecs/tru64-cxx/qmake.conf
index afabf3e220f..a8db2a3c3a9 100644
--- a/mkspecs/tru64-cxx/qmake.conf
+++ b/mkspecs/tru64-cxx/qmake.conf
@@ -64,9 +64,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lrt
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/tru64-g++/qmake.conf b/mkspecs/tru64-g++/qmake.conf
index 6acd5cdb220..e1236cf5f86 100644
--- a/mkspecs/tru64-g++/qmake.conf
+++ b/mkspecs/tru64-g++/qmake.conf
@@ -66,9 +66,6 @@ QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lpthread -lexc -lrt
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/unixware-cc/qmake.conf b/mkspecs/unixware-cc/qmake.conf
index 74478d66e29..4e55970aa71 100644
--- a/mkspecs/unixware-cc/qmake.conf
+++ b/mkspecs/unixware-cc/qmake.conf
@@ -69,9 +69,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/unixware-g++/qmake.conf b/mkspecs/unixware-g++/qmake.conf
index a158d9522a2..753c3a86a71 100644
--- a/mkspecs/unixware-g++/qmake.conf
+++ b/mkspecs/unixware-g++/qmake.conf
@@ -68,9 +68,6 @@ QMAKE_LIBS_OPENGL = -lGL -lXt
QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD = -lthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cq
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/unsupported/integrity-ghs/qmake.conf b/mkspecs/unsupported/integrity-ghs/qmake.conf
index 54253edc8fe..7f2ac2fb047 100644
--- a/mkspecs/unsupported/integrity-ghs/qmake.conf
+++ b/mkspecs/unsupported/integrity-ghs/qmake.conf
@@ -50,9 +50,6 @@ QMAKE_LIBS_X11 =
QMAKE_LIBS_X11SM =
QMAKE_LIBS_THREAD =
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_RANLIB =
diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf
index 1ad529ebae7..2e0b7dba442 100644
--- a/mkspecs/unsupported/linux-host-g++/qmake.conf
+++ b/mkspecs/unsupported/linux-host-g++/qmake.conf
@@ -108,9 +108,6 @@ QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
QMAKE_LIBS_OPENVG = -lOpenVG
QMAKE_LIBS_THREAD = -lpthread
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = host-ar cqs
QMAKE_OBJCOPY = host-objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/unsupported/qnx-g++/qmake.conf b/mkspecs/unsupported/qnx-X11-g++/qmake.conf
similarity index 92%
rename from mkspecs/unsupported/qnx-g++/qmake.conf
rename to mkspecs/unsupported/qnx-X11-g++/qmake.conf
index 83c4a26e068..94f207aff63 100644
--- a/mkspecs/unsupported/qnx-g++/qmake.conf
+++ b/mkspecs/unsupported/qnx-X11-g++/qmake.conf
@@ -1,5 +1,5 @@
#
-# qmake configuration for qnx-g++
+# qmake configuration for qnx-x11-g++
#
# Written for QNX RTOS v6 with X11
#
@@ -37,9 +37,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
QMAKE_LIBS_NETWORK = -lsocket
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_RANLIB =
diff --git a/mkspecs/unsupported/qnx-g++/qplatformdefs.h b/mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h
similarity index 100%
rename from mkspecs/unsupported/qnx-g++/qplatformdefs.h
rename to mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h
diff --git a/mkspecs/unsupported/blackberry-armv7le-qcc/qmake.conf b/mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf
similarity index 92%
rename from mkspecs/unsupported/blackberry-armv7le-qcc/qmake.conf
rename to mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf
index f2407a6c13a..ea206e28ec3 100644
--- a/mkspecs/unsupported/blackberry-armv7le-qcc/qmake.conf
+++ b/mkspecs/unsupported/qnx-armv7le-qcc/qmake.conf
@@ -1,5 +1,5 @@
#
-# qmake configuration for blackberry-qcc
+# qmake configuration for qnx-qcc armv7 targets
#
MAKEFILE_GENERATOR = UNIX
diff --git a/mkspecs/unsupported/blackberry-armv7le-qcc/qplatformdefs.h b/mkspecs/unsupported/qnx-armv7le-qcc/qplatformdefs.h
similarity index 100%
rename from mkspecs/unsupported/blackberry-armv7le-qcc/qplatformdefs.h
rename to mkspecs/unsupported/qnx-armv7le-qcc/qplatformdefs.h
diff --git a/mkspecs/unsupported/blackberry-x86-qcc/qmake.conf b/mkspecs/unsupported/qnx-x86-qcc/qmake.conf
similarity index 92%
rename from mkspecs/unsupported/blackberry-x86-qcc/qmake.conf
rename to mkspecs/unsupported/qnx-x86-qcc/qmake.conf
index 93f1df2e072..fef8d443c1f 100644
--- a/mkspecs/unsupported/blackberry-x86-qcc/qmake.conf
+++ b/mkspecs/unsupported/qnx-x86-qcc/qmake.conf
@@ -1,5 +1,5 @@
#
-# qmake configuration for blackberry-qcc
+# qmake configuration for qnx-qcc x86 targets
#
MAKEFILE_GENERATOR = UNIX
diff --git a/mkspecs/unsupported/blackberry-x86-qcc/qplatformdefs.h b/mkspecs/unsupported/qnx-x86-qcc/qplatformdefs.h
similarity index 100%
rename from mkspecs/unsupported/blackberry-x86-qcc/qplatformdefs.h
rename to mkspecs/unsupported/qnx-x86-qcc/qplatformdefs.h
diff --git a/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf b/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf
index a3b571b1440..10f2627d664 100644
--- a/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf
+++ b/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf
@@ -84,9 +84,6 @@ QMAKE_LIBS_THREAD =
QMAKE_LIBS_NETWORK = # -lnetwrap # only needed if kernel is missing gethostbyname and friends
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf b/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf
index 8bdf1c50115..c3c974e3e7f 100644
--- a/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf
+++ b/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf
@@ -83,9 +83,6 @@ QMAKE_LIBS_OPENGL_QT = -lGL
QMAKE_LIBS_THREAD =
QMAKE_LIBS_NETWORK = # -lnet # only needed if kernel is missing gethostbyname and friends
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_RANLIB =
diff --git a/mkspecs/unsupported/win32-g++-cross/qmake.conf b/mkspecs/unsupported/win32-g++-cross/qmake.conf
index 7f41c8aab3f..9dcff807fac 100644
--- a/mkspecs/unsupported/win32-g++-cross/qmake.conf
+++ b/mkspecs/unsupported/win32-g++-cross/qmake.conf
@@ -79,6 +79,7 @@ QMAKE_SH = bash
MINGW_IN_SHELL = 1
QMAKE_DIR_SEP = /
QMAKE_COPY = cp
+QMAKE_STREAM_EDITOR = sed
QMAKE_COPY_DIR = cp -R
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm -f
diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf
index c1f0ac33070..641e4109ff6 100644
--- a/mkspecs/win32-g++/qmake.conf
+++ b/mkspecs/win32-g++/qmake.conf
@@ -79,6 +79,7 @@ QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
QMAKE_DIR_SEP = /
QMAKE_QMAKE ~= s,\\\\,/,
QMAKE_COPY = cp
+ QMAKE_STREAM_EDITOR = sed
QMAKE_COPY_DIR = cp -r
QMAKE_MOVE = mv
QMAKE_DEL_FILE = rm
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index 16af49311b0..2dddecb7b0c 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -15,7 +15,7 @@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \
#qt code
QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
- qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfile.o \
+ qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \
qfilesystementry.o qfilesystemengine_unix.o qfilesystemengine.o qfilesystemiterator_unix.o \
qfsfileengine_unix.o qfsfileengine.o \
qfsfileengine_iterator.o qregexp.o qvector.o qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o \
@@ -37,6 +37,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge
generators/integrity/gbuild.cpp \
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
$(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \
+ $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \
$(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \
$(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \
$(SOURCE_PATH)/src/corelib/global/qglobal.cpp $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \
@@ -73,7 +74,7 @@ CPPFLAGS = -g -I. -Igenerators -Igenerators/unix -Igenerators/win32 \
-Igenerators/mac -Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore \
-I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(BUILD_PATH)/src/corelib/global -I$(BUILD_PATH)/src/corelib/xml \
+ -I$(BUILD_PATH)/src/corelib/global \
-I$(SOURCE_PATH)/tools/shared \
-DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_STL \
@@ -176,6 +177,9 @@ qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
+qfiledevice.o: $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp
+
qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index 767237fcfc7..f36e4fa631b 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -33,9 +33,7 @@ CFLAGS_BARE = -c -Fo./ \
$(CFLAGS_EXTRA) \
-I. -Igenerators -Igenerators\unix -Igenerators\win32 -Igenerators\mac -Igenerators\integrity \
-I$(BUILD_PATH)\include -I$(BUILD_PATH)\include\QtCore -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION) -I$(BUILD_PATH)\include\QtCore\$(QT_VERSION)\QtCore \
- -I$(SOURCE_PATH)\include -I$(SOURCE_PATH)\include\QtCore -I$(SOURCE_PATH)\include\QtCore\$(QT_VERSION) -I$(SOURCE_PATH)\include\QtCore\$(QT_VERSION)\QtCore \
-I$(BUILD_PATH)\src\corelib\global \
- -I$(BUILD_PATH)\src\corelib\xml \
-I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \
-I$(SOURCE_PATH)\tools\shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NODLL -DQT_NO_STL \
@@ -84,6 +82,7 @@ QTOBJS= \
qdatetime.obj \
qdir.obj \
qdiriterator.obj \
+ qfiledevice.obj \
qfile.obj \
qtemporaryfile.obj \
qabstractfileengine.obj \
diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++
index 585061ed268..56d8edca7d3 100644
--- a/qmake/Makefile.win32-g++
+++ b/qmake/Makefile.win32-g++
@@ -2,12 +2,42 @@ ifeq "$(SOURCE_PATH)" ""
SOURCE_PATH = ..
endif
-#cmd version
-
ifeq "$(BUILD_PATH)" ""
BUILD_PATH = ..
endif
+CORESRC = $(SOURCE_PATH)/src/corelib
+TOOLSRC = $(SOURCE_PATH)/tools
+QMKSRC = $(SOURCE_PATH)/qmake
+
+# SHELL is the full path of sh.exe, unless
+# 1) it is found in the current directory
+# 2) it is not found at all
+# 3) it is overridden on the command line with an existing file
+# ... otherwise it is always sh.exe. Specifically, SHELL from the
+# environment has no effect.
+#
+# This check will fail if SHELL is explicitly set to a not
+# sh-compatible shell. This is not a problem, because configure.exe
+# will not do that.
+ifeq ($(SHELL), sh.exe)
+ ifeq ($(wildcard $(CURDIR)/sh.exe), )
+ SH = 0
+ else
+ SH = 1
+ endif
+else
+ SH = 1
+endif
+
+ifeq ($(SH), 1)
+ COPY = cp
+ DEL = rm -f
+else
+ COPY = copy
+ DEL = del /f
+endif
+
#
# specific stuff for mingw g++ make
#
@@ -17,9 +47,7 @@ CFLAGS = -c -o$@ -O \
-Igenerators/win32 -Igenerators/mac \
-Igenerators/integrity \
-I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION) -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
-I$(BUILD_PATH)/src/corelib/global \
- -I$(BUILD_PATH)/src/corelib/xml \
-I$(SOURCE_PATH)/mkspecs/win32-g++ \
-I$(SOURCE_PATH)/tools/shared \
-DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT \
@@ -56,6 +84,7 @@ QTOBJS= \
qdatetime.o \
qdir.o \
qdiriterator.o \
+ qfiledevice.o \
qfile.o \
qtemporaryfile.o \
qfileinfo.o \
@@ -101,16 +130,16 @@ QTOBJS= \
qmake.exe: $(OBJS) $(QTOBJS)
$(LINKQMAKE)
- -copy qmake.exe $(BUILD_PATH)\bin\qmake.exe
+ -$(COPY) qmake.exe $(BUILD_PATH)\bin\qmake.exe
Makefile: Makefile.win32-g++
@echo "Out of date, please rerun configure"
clean::
- -del $(OBJS) $(QTOBJS) $(ADDCLEAN)
+ -$(DEL) $(OBJS) $(QTOBJS) $(ADDCLEAN)
distclean:: clean
- -del qmake
+ -$(DEL) qmake.exe
.c.o:
$(CXX) $(CFLAGS) $<
@@ -118,227 +147,11 @@ distclean:: clean
.cpp.o:
$(CXX) $(CXXFLAGS) $<
-qconfig.o: $(BUILD_PATH)/src/corelib/global/qconfig.cpp
- $(CXX) $(CXXFLAGS) $(BUILD_PATH)/src/corelib/global/qconfig.cpp
-
-qsettings_win.o: $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
-
-qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
-
-qvariant.o: $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
-
-qurl.o: $(SOURCE_PATH)/src/corelib/io/qurl.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qurl.cpp
-
-qtextstream.o: $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
-
-qdatastream.o: $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
-
-qiodevice.o: $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
-
-qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
-
-qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
-
-qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
-
-qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
-
-qhash.o: $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
-
-qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
-
-qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
-
-qvsnprintf.o: $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
-
-qbytearraymatcher.o: $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
-
-qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
-
-qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
-
-qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
-
-qlocale_tools.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
-
-qlocale_win.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
-
-quuid.o: $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
-
-qbuffer.o: $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
-
-qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
-
-qlinkedlist.o: $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
-
-qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
-
-qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
-
-qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
-
-qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
-
-qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
-
-qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
-
-qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
-
-qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
-
-qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
-
-qfsfileengine_iterator.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
-
-qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
-
-qregexp.o: $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
-
-qvector.o: $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
-
-qbitarray.o: $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
-
-qdir.o: $(SOURCE_PATH)/src/corelib/io/qdir.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdir.cpp
-
-qdiriterator.o: $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
-
-qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
-
-qfileinfo.o: $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
-
-qdatetime.o: $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
-
-qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
-
-qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
-
-qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
-
-qmap.o: $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
-
-makefile.o: $(SOURCE_PATH)/qmake/generators/makefile.cpp
- $(CXX) $(CXXFLAGS) generators/makefile.cpp
-
-unixmake.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake.cpp
-
-unixmake2.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake2.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake2.cpp
-
-winmakefile.o: $(SOURCE_PATH)/qmake/generators/win32/winmakefile.cpp
- $(CXX) $(CXXFLAGS) generators/win32/winmakefile.cpp
-
-borland_bmake.o: $(SOURCE_PATH)/qmake/generators/win32/borland_bmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/borland_bmake.cpp
-
-mingw_make.o: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp
- $(CXX) $(CXXFLAGS) generators/win32/mingw_make.cpp
-
-msvc_nmake.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp
-
-msvc_vcproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp
-
-msvc_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp
-
-msvc_vcxproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcxproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcxproj.cpp
-
-msbuild_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msbuild_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msbuild_objectmodel.cpp
-
-registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
-
-gbuild.o: $(SOURCE_PATH)/qmake/generators/integrity/gbuild.cpp
- $(CXX) $(CXXFLAGS) generators/integrity/gbuild.cpp
-
-project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) project.cpp
-
-meta.o: $(SOURCE_PATH)/qmake/meta.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) meta.cpp
-
-main.o: $(SOURCE_PATH)/qmake/main.cpp $(SOURCE_PATH)/qmake/project.h
- $(CXX) $(CXXFLAGS) main.cpp
-
-option.o: $(SOURCE_PATH)/qmake/option.cpp $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) option.cpp
-
-property.o: $(SOURCE_PATH)/qmake/property.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) property.cpp
-
-projectgenerator.o: $(SOURCE_PATH)/qmake/generators/projectgenerator.cpp
- $(CXX) $(CXXFLAGS) generators/projectgenerator.cpp
-
-pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp
- $(CXX) $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp
-
-makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp
- $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp
-
-metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp
- $(CXX) $(CXXFLAGS) generators/metamakefile.cpp
-
-xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp
- $(CXX) $(CXXFLAGS) generators/xmloutput.cpp
-
-qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
-
-qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
-
-qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
+QTVPATH = $(TOOLSRC)/shared/windows:$(CORESRC)/global:$(CORESRC)/kernel:$(CORESRC)/tools:$(CORESRC)/codecs:$(CORESRC)/io:$(CORESRC)/xml:$(CORESRC)/plugin:$(BUILD_PATH)/src/corelib/global
+VPATH = $(QMKSRC):$(QMKSRC)/generators:$(QMKSRC)/generators/unix:$(QMKSRC)/generators/mac:$(QMKSRC)/generators/win32:$(QMKSRC)/generators/integrity:$(QTVPATH)
+
+project.o: $(QMKSRC)/project.h $(QMKSRC)/option.h
+meta.o: $(QMKSRC)/project.h $(QMKSRC)/option.h
+main.o: $(QMKSRC)/project.h
+option.o: $(QMKSRC)/option.h
+property.o: $(QMKSRC)/project.h $(QMKSRC)/option.h
diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh
deleted file mode 100644
index 6dfb4863754..00000000000
--- a/qmake/Makefile.win32-g++-sh
+++ /dev/null
@@ -1,343 +0,0 @@
-ifeq "$(SOURCE_PATH)" ""
-SOURCE_PATH = ..
-endif
-
-#sh version
-
-ifeq "$(BUILD_PATH)" ""
-BUILD_PATH = ..
-endif
-
-#
-# specific stuff for mingw g++ make
-#
-CXX = g++
-CFLAGS = -c -o$@ -O \
- -I. -Igenerators -Igenerators/unix \
- -Igenerators/win32 -Igenerators/mac \
- -Igenerators/integrity \
- -I$(BUILD_PATH)/include -I$(BUILD_PATH)/include/QtCore -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION) -I$(BUILD_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(SOURCE_PATH)/include -I$(SOURCE_PATH)/include/QtCore -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION) -I$(SOURCE_PATH)/include/QtCore/$(QT_VERSION)/QtCore \
- -I$(BUILD_PATH)/src/corelib/global \
- -I$(BUILD_PATH)/src/corelib/xml \
- -I$(SOURCE_PATH)/mkspecs/win32-g++ \
- -I$(SOURCE_PATH)/tools/shared \
- -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT \
- -DQT_NODLL -DQT_NO_STL -DQT_NO_COMPRESS -DUNICODE -DHAVE_QCONFIG_CPP \
- -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \
- -DQT_BOOTSTRAPPED
-CXXFLAGS = $(CFLAGS)
-LFLAGS = -static-libgcc -s
-LIBS = -lole32 -luuid -ladvapi32 -lkernel32
-LINKQMAKE = g++ $(LFLAGS) -o qmake.exe $(OBJS) $(QTOBJS) $(LIBS)
-ADDCLEAN =
-
-
-#qmake code
-OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \
- option.o winmakefile.o projectgenerator.o property.o meta.o \
- makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \
- borland_bmake.o msvc_nmake.o msvc_vcproj.o msvc_vcxproj.o \
- msvc_objectmodel.o msbuild_objectmodel.o registry.o gbuild.o
-
-ifdef QMAKE_OPENSOURCE_EDITION
-CFLAGS += -DQMAKE_OPENSOURCE_EDITION
-endif
-
-#qt code
-QTOBJS= \
- qbitarray.o \
- qbuffer.o \
- qbytearray.o \
- qcryptographichash.o \
- qvsnprintf.o \
- qbytearraymatcher.o \
- qconfig.o \
- qdatetime.o \
- qdir.o \
- qdiriterator.o \
- qfile.o \
- qtemporaryfile.o \
- qfileinfo.o \
- qabstractfileengine.o \
- qfilesystementry.o \
- qfilesystemengine.o \
- qfilesystemengine_win.o \
- qfilesystemiterator_win.o \
- qfsfileengine.o \
- qfsfileengine_iterator.o \
- qfsfileengine_win.o \
- qglobal.o \
- qhash.o \
- qiodevice.o \
- qlibraryinfo.o \
- qlist.o \
- qlinkedlist.o \
- qlocale.o \
- qlocale_tools.o \
- qlocale_win.o \
- qmalloc.o \
- qmap.o \
- qregexp.o \
- qtextcodec.o \
- qutfcodec.o \
- qstring.o \
- qstringlist.o \
- qsystemlibrary.o \
- qsystemerror.o \
- qtextstream.o \
- quuid.o \
- qvector.o \
- qurl.o \
- qsettings.o \
- qsettings_win.o \
- qvariant.o \
- qmetatype.o \
- qxmlstream.o \
- qxmlutils.o \
- qnumeric.o \
- qlogging.o
-
-qmake.exe: $(OBJS) $(QTOBJS)
- $(LINKQMAKE)
- -cp qmake.exe $(BUILD_PATH)/bin/qmake.exe
-
-Makefile: Makefile.win32-g++-sh
- @echo "Out of date, please rerun configure"
-
-clean::
- -del $(OBJS) $(QTOBJS) $(ADDCLEAN)
-
-distclean:: clean
- -del qmake
-
-.c.o:
- $(CXX) $(CFLAGS) $<
-
-.cpp.o:
- $(CXX) $(CXXFLAGS) $<
-
-qconfig.o: $(BUILD_PATH)/src/corelib/global/qconfig.cpp
- $(CXX) $(CXXFLAGS) $(BUILD_PATH)/src/corelib/global/qconfig.cpp
-
-qsettings_win.o: $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp
-
-qsettings.o: $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qsettings.cpp
-
-qvariant.o: $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qvariant.cpp
-
-qurl.o: $(SOURCE_PATH)/src/corelib/io/qurl.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qurl.cpp
-
-qtextstream.o: $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp
-
-qdatastream.o: $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdatastream.cpp
-
-qiodevice.o: $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp
-
-qlibraryinfo.o: $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp
-
-qnumeric.o: $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qnumeric.cpp
-
-qmalloc.o: $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp
-
-qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qglobal.cpp
-
-qhash.o: $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qhash.cpp
-
-qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp
-
-qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp
-
-qvsnprintf.o: $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp
-
-qbytearraymatcher.o: $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp
-
-qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp
-
-qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
-
-qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp
-
-qlocale_tools.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp
-
-qlocale_win.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp
-
-quuid.o: $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/quuid.cpp
-
-qbuffer.o: $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qbuffer.cpp
-
-qlist.o: $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlist.cpp
-
-qlinkedlist.o: $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qlinkedlist.cpp
-
-qfile.o: $(SOURCE_PATH)/src/corelib/io/qfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfile.cpp
-
-qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp
-
-qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp
-
-qfilesystementry.o: $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystementry.cpp
-
-qfilesystemengine.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine.cpp
-
-qfilesystemengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemengine_win.cpp
-
-qfilesystemiterator_win.o: $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfilesystemiterator_win.cpp
-
-qfsfileengine_win.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_win.cpp
-
-qfsfileengine.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine.cpp
-
-qfsfileengine_iterator.o: $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfsfileengine_iterator.cpp
-
-qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
-
-qregexp.o: $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp
-
-qvector.o: $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qvector.cpp
-
-qbitarray.o: $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp
-
-qdir.o: $(SOURCE_PATH)/src/corelib/io/qdir.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdir.cpp
-
-qdiriterator.o: $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdiriterator.cpp
-
-qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp
-
-qfileinfo.o: $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp
-
-qdatetime.o: $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qdatetime.cpp
-
-qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp
-
-qsystemerror.o: $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/kernel/qsystemerror.cpp
-
-qsystemlibrary.o: $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp
-
-qmap.o: $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qmap.cpp
-
-makefile.o: $(SOURCE_PATH)/qmake/generators/makefile.cpp
- $(CXX) $(CXXFLAGS) generators/makefile.cpp
-
-unixmake.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake.cpp
-
-unixmake2.o: $(SOURCE_PATH)/qmake/generators/unix/unixmake2.cpp
- $(CXX) $(CXXFLAGS) generators/unix/unixmake2.cpp
-
-winmakefile.o: $(SOURCE_PATH)/qmake/generators/win32/winmakefile.cpp
- $(CXX) $(CXXFLAGS) generators/win32/winmakefile.cpp
-
-borland_bmake.o: $(SOURCE_PATH)/qmake/generators/win32/borland_bmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/borland_bmake.cpp
-
-mingw_make.o: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp
- $(CXX) $(CXXFLAGS) generators/win32/mingw_make.cpp
-
-msvc_nmake.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp
-
-msvc_vcproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp
-
-msvc_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_objectmodel.cpp
-
-msvc_vcxproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcxproj.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msvc_vcxproj.cpp
-
-msbuild_objectmodel.o: $(SOURCE_PATH)/qmake/generators/win32/msbuild_objectmodel.cpp
- $(CXX) $(CXXFLAGS) generators/win32/msbuild_objectmodel.cpp
-
-registry.o: $(SOURCE_PATH)/tools/shared/windows/registry.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/tools/shared/windows/registry.cpp
-
-gbuild.o: $(SOURCE_PATH)/qmake/generators/integrity/gbuild.cpp
- $(CXX) $(CXXFLAGS) generators/integrity/gbuild.cpp
-
-project.o: $(SOURCE_PATH)/qmake/project.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) project.cpp
-
-meta.o: $(SOURCE_PATH)/qmake/meta.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) meta.cpp
-
-main.o: $(SOURCE_PATH)/qmake/main.cpp $(SOURCE_PATH)/qmake/project.h
- $(CXX) $(CXXFLAGS) main.cpp
-
-option.o: $(SOURCE_PATH)/qmake/option.cpp $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) option.cpp
-
-property.o: $(SOURCE_PATH)/qmake/property.cpp $(SOURCE_PATH)/qmake/project.h $(SOURCE_PATH)/qmake/option.h
- $(CXX) $(CXXFLAGS) property.cpp
-
-projectgenerator.o: $(SOURCE_PATH)/qmake/generators/projectgenerator.cpp
- $(CXX) $(CXXFLAGS) generators/projectgenerator.cpp
-
-pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp
- $(CXX) $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp
-
-makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp
- $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp
-
-metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp
- $(CXX) $(CXXFLAGS) generators/metamakefile.cpp
-
-xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp
- $(CXX) $(CXXFLAGS) generators/xmloutput.cpp
-
-qxmlstream.o: $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlstream.cpp
-
-qxmlutils.o: $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/xml/qxmlutils.cpp
-
-qlogging.o: $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
- $(CXX) $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/global/qlogging.cpp
diff --git a/qmake/generators/integrity/gbuild.cpp b/qmake/generators/integrity/gbuild.cpp
index c72c120f394..895df24193a 100644
--- a/qmake/generators/integrity/gbuild.cpp
+++ b/qmake/generators/integrity/gbuild.cpp
@@ -213,7 +213,7 @@ GBuildMakefileGenerator::write()
dllbase += DLLOFFSET;
}
- warn_msg(WarnParser, Option::output.fileName().toAscii());
+ warn_msg(WarnParser, Option::output.fileName().toAscii().constData());
QTextStream t(&Option::output);
QString primaryTarget(project->values("QMAKE_CXX").at(0));
@@ -425,7 +425,7 @@ GBuildMakefileGenerator::openOutput(QFile &file, const QString &build) const
outputName += QDir::separator();
outputName += fileInfo(project->projectFile()).baseName();
outputName += projectSuffix();
- warn_msg(WarnParser, outputName.toAscii());
+ warn_msg(WarnParser, outputName.toAscii().constData());
file.setFileName(outputName);
}
debug_msg(1, "file is %s", file.fileName().toLatin1().constData());
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
index b78ebd136d5..770a1ad34e4 100644
--- a/qmake/generators/mac/pbuilder_pbx.cpp
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -178,7 +178,6 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
}
if(tmp_proj.first("TEMPLATE") == "subdirs") {
QMakeProject *pp = new QMakeProject(&tmp_proj);
- pp->read(0);
pb_subdirs += new ProjectBuilderSubDirs(pp, dir);
} else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") {
QString pbxproj = qmake_getpwd() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix();
@@ -508,6 +507,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
//HEADER
const int pbVersion = pbuilderVersion();
+ QStringList buildConfigGroups;
+ buildConfigGroups << "PROJECT";
+ if (pbVersion >= 46)
+ buildConfigGroups << "TARGET";
+
t << "// !$*UTF8*$!" << "\n"
<< "{" << "\n"
<< "\t" << writeSettings("archiveVersion", "1", SettingsNoQuote) << ";" << "\n"
@@ -810,7 +814,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
QStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
QString libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS",
- "QMAKE_LIBS", QString() };
+ "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", QString() };
for(int i = 0; !libs[i].isNull(); i++) {
tmp = project->values(libs[i]);
for(int x = 0; x < tmp.count();) {
@@ -1014,28 +1018,22 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", escapeFilePath(grp)) << ";" << "\n"
<< "\t\t" << "};" << "\n";
}
- { //INSTALL BUILDPHASE (copy)
+ if (!project->isEmpty("DESTDIR")) {
QString phase_key = keyFor("QMAKE_PBX_TARGET_COPY_PHASE");
- QString destDir = Option::output_dir;
- if (!project->isEmpty("QMAKE_ORIG_DESTDIR"))
- destDir = project->first("QMAKE_ORIG_DESTDIR");
+ QString destDir = project->first("DESTDIR");
destDir = fixForOutput(destDir);
destDir = fileInfo(Option::fixPathToLocalOS(destDir)).absoluteFilePath();
- project->values("QMAKE_PBX_PRESCRIPT_BUILDPHASES").append(phase_key);
+ project->values("QMAKE_PBX_BUILDPHASES").append(phase_key);
t << "\t\t" << phase_key << " = {\n"
+ << "\t\t\t" << writeSettings("isa", "PBXShellScriptBuildPhase", SettingsNoQuote) << ";" << "\n"
<< "\t\t\t" << writeSettings("name", "Project Copy") << ";" << "\n"
<< "\t\t\t" << writeSettings("buildActionMask", "2147483647", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("dstPath", escapeFilePath(destDir)) << ";" << "\n"
- << "\t\t\t" << writeSettings("dstSubfolderSpec", "0", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("files", keyFor("QMAKE_PBX_TARGET_COPY_FILE"), SettingsAsList, 4) << ";" << "\n"
- << "\t\t\t" << writeSettings("isa", "PBXCopyFilesBuildPhase", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("files", QStringList(), SettingsAsList, 4) << ";" << "\n"
+ << "\t\t\t" << writeSettings("inputPaths", QStringList(), SettingsAsList, 4) << ";" << "\n"
+ << "\t\t\t" << writeSettings("outputPaths", QStringList(), SettingsAsList, 4) << ";" << "\n"
<< "\t\t\t" << writeSettings("runOnlyForDeploymentPostprocessing", "0", SettingsNoQuote) << ";" << "\n"
- << "\t\t" << "};\n"
- << "\t\t" << keyFor("QMAKE_PBX_TARGET_COPY_FILE") << " = {\n"
- << "\t\t\t" << writeSettings("fileRef", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n"
- << "\t\t\t" << writeSettings("isa", "PBXBuildFile", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << "settings = {\n"
- << "\t\t\t" << "};\n"
+ << "\t\t\t" << writeSettings("shellPath", "/bin/sh") << ";" << "\n"
+ << "\t\t\t" << writeSettings("shellScript", fixForOutput("cp -r $BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME " + escapeFilePath(destDir))) << ";" << "\n"
<< "\t\t" << "};\n";
}
//BUNDLE_DATA BUILDPHASE (copy)
@@ -1113,6 +1111,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("name", "Qt Preprocessor Steps") << ";" << "\n"
<< "\t\t\t" << writeSettings("productName", "Qt Preprocessor Steps") << ";" << "\n"
<< "\t\t\t" << writeSettings("productReference", keyFor("QMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")) << ";" << "\n";
+ if (pbVersion >= 46)
+ t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST"), SettingsNoQuote) << ";" << "\n";
if(!project->isEmpty("QMAKE_PBX_PRODUCT_TYPE"))
t << "\t\t\t" << writeSettings("productType", project->first("QMAKE_PBX_PRODUCT_TYPE")) << ";" << "\n";
else
@@ -1217,28 +1217,30 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t\t" << writeSettings("CPLUSPLUS", fixForOutput(findProgram(cCompiler))) << ";" << "\n";
}
- t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n"
- << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n"
- << "\t\t\t\t" << writeSettings("OPTIMIZATION_CFLAGS", QStringList(), SettingsAsList, 5) << ";" << "\n";
- {
- QStringList cflags = fixListForOutput("QMAKE_CFLAGS");
- const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
- for(int i = 0; i < prl_defines.size(); ++i)
- cflags += "-D" + prl_defines.at(i);
- const QStringList &defines = project->values("DEFINES");
- for(int i = 0; i < defines.size(); ++i)
- cflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n";
- }
- {
- QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
- const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
- for(int i = 0; i < prl_defines.size(); ++i)
- cxxflags += "-D" + prl_defines.at(i);
- const QStringList &defines = project->values("DEFINES");
- for(int i = 0; i < defines.size(); ++i)
- cxxflags += "-D" + defines.at(i);
- t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n";
+ if (pbVersion < 46) {
+ t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("OPTIMIZATION_CFLAGS", QStringList(), SettingsAsList, 5) << ";" << "\n";
+ {
+ QStringList cflags = fixListForOutput("QMAKE_CFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n";
+ }
+ {
+ QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cxxflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cxxflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n";
+ }
}
t << "\t\t\t\t" << writeSettings("LEXFLAGS", fixListForOutput("QMAKE_LEXFLAGS")) << ";" << "\n"
<< "\t\t\t\t" << writeSettings("YACCFLAGS", fixListForOutput("QMAKE_YACCFLAGS")) << ";" << "\n"
@@ -1298,7 +1300,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
+ fixListForOutput("QMAKE_LFLAGS")
+ fixListForOutput("QMAKE_LIBDIR_FLAGS")
+ fixListForOutput("QMAKE_FRAMEWORKPATH_FLAGS")
- + fixListForOutput("QMAKE_LIBS"),
+ + fixListForOutput("QMAKE_LIBS")
+ + fixListForOutput("QMAKE_LIBS_PRIVATE"),
SettingsAsList, 6) << ";" << "\n";
}
if(!project->isEmpty("DESTDIR")) {
@@ -1318,7 +1321,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
project->isActiveConfig("lib_bundle"))
t << "\t\t\t\t" << writeSettings("FRAMEWORK_VERSION", project->first("QMAKE_FRAMEWORK_VERSION")) << ";" << "\n";
}
- if(!project->isEmpty("COMPAT_FRAMEWORKPATH"))
+ if (pbVersion < 46 && !project->isEmpty("COMPAT_FRAMEWORKPATH"))
t << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), SettingsAsList, 5) << ";" << "\n";
if(!project->isEmpty("COMPAT_VERSION"))
t << "\t\t\t\t" << writeSettings("DYLIB_COMPATIBILITY_VERSION", project->first("COMPAT_VERSION")) << ";" << "\n";
@@ -1334,7 +1337,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
else
t << "\t\t\t\t" << writeSettings("SYMROOT", fixForOutput(qmake_getpwd())) << ";" << "\n";
#endif
- {
+ if (pbVersion < 46) {
QStringList archs;
if(project->isActiveConfig("x86"))
archs += "i386";
@@ -1374,7 +1377,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
}
tmp = project->values("QMAKE_PBX_VARS");
for(int i = 0; i < tmp.count(); i++) {
- QString var = tmp[i], val = qgetenv(var.toLatin1());
+ QString var = tmp[i], val = QString::fromAscii(qgetenv(var.toLatin1().constData()));
if(val.isEmpty() && var == "TB")
val = "/usr/bin/";
t << "\t\t\t\t" << writeSettings(var, escapeFilePath(val)) << ";" << "\n";
@@ -1385,6 +1388,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("dependencies", project->values("QMAKE_PBX_TARGET_DEPENDS"), SettingsAsList, 4) << ";" << "\n"
<< "\t\t\t" << writeSettings("productReference", keyFor(pbx_dir + "QMAKE_PBX_REFERENCE")) << ";" << "\n"
<< "\t\t\t" << writeSettings("shouldUseHeadermap", "1", SettingsNoQuote) << ";" << "\n";
+ if (pbVersion >= 46)
+ t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST_TARGET"), SettingsNoQuote) << ";" << "\n";
if(pbVersion >= 38)
t << "\t\t\t" << writeSettings("isa", "PBXNativeTarget", SettingsNoQuote) << ";" << "\n";
if(project->first("TEMPLATE") == "app") {
@@ -1493,6 +1498,16 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
settings.insert(name, value);
}
}
+ if (pbVersion >= 46) {
+ if (project->first("TEMPLATE") == "app") {
+ settings.insert("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET")));
+ } else {
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
+ lib.prepend("lib");
+ settings.insert("PRODUCT_NAME", escapeFilePath(lib));
+ }
+ }
QString name;
if(pbVersion >= 42)
@@ -1500,42 +1515,121 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
else
name = (as_release ? "Deployment" : "Development");
if(pbVersion >= 42) {
- QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name);
- project->values("QMAKE_PBX_BUILDCONFIGS").append(key);
+ for (int i = 0; i < buildConfigGroups.size(); i++) {
+ QString key = keyFor("QMAKE_PBX_BUILDCONFIG_" + name + buildConfigGroups.at(i));
+ project->values("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i)).append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << "buildSettings = {" << "\n";
+ for (QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
+ t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n";
+ if (pbVersion >= 46) {
+ if (buildConfigGroups.at(i) == QLatin1String("PROJECT")) {
+ t << "\t\t\t\t" << writeSettings("HEADER_SEARCH_PATHS", fixListForOutput("INCLUDEPATH") + QStringList(fixForOutput(specdir())), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("LIBRARY_SEARCH_PATHS", fixListForOutput("QMAKE_PBX_LIBPATHS"), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("FRAMEWORK_SEARCH_PATHS", fixListForOutput("QMAKE_FRAMEWORKPATH"), SettingsAsList, 5) << ";" << "\n"
+ << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";" << "\n";
+ {
+ QStringList cflags = fixListForOutput("QMAKE_CFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CFLAGS", cflags, SettingsAsList, 5) << ";" << "\n";
+ }
+ {
+ QStringList cxxflags = fixListForOutput("QMAKE_CXXFLAGS");
+ const QStringList &prl_defines = project->values("PRL_EXPORT_DEFINES");
+ for (int i = 0; i < prl_defines.size(); ++i)
+ cxxflags += "-D" + prl_defines.at(i);
+ const QStringList &defines = project->values("DEFINES");
+ for (int i = 0; i < defines.size(); ++i)
+ cxxflags += "-D" + defines.at(i);
+ t << "\t\t\t\t" << writeSettings("OTHER_CPLUSPLUSFLAGS", cxxflags, SettingsAsList, 5) << ";" << "\n";
+ }
+ if (!project->isActiveConfig("staticlib")) {
+ t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
+ fixListForOutput("SUBLIBS")
+ + fixListForOutput("QMAKE_LFLAGS")
+ + fixListForOutput("QMAKE_LIBDIR_FLAGS")
+ + fixListForOutput("QMAKE_FRAMEWORKPATH_FLAGS")
+ + fixListForOutput("QMAKE_LIBS")
+ + fixListForOutput("QMAKE_LIBS_PRIVATE"),
+ SettingsAsList, 6) << ";" << "\n";
+ }
+ {
+ QStringList archs;
+ if (project->isActiveConfig("x86"))
+ archs += "i386";
+ if (project->isActiveConfig("ppc")) {
+ if (!archs.isEmpty())
+ archs += " ";
+ archs += "ppc";
+ }
+ if (project->isActiveConfig("ppc64")) {
+ if (!archs.isEmpty())
+ archs += " ";
+ archs += "ppc64";
+ }
+ if (project->isActiveConfig("x86_64")) {
+ if (!archs.isEmpty())
+ archs += " ";
+ archs += "x86_64";
+ }
+ if (!archs.isEmpty())
+ t << "\t\t\t\t" << writeSettings("ARCHS", archs) << ";" << "\n";
+ }
+ } else {
+ if (project->first("TEMPLATE") == "app") {
+ if (pbVersion < 38 && project->isActiveConfig("app_bundle"))
+ t << "\t\t\t\t" << writeSettings("WRAPPER_SUFFIX", "app") << ";" << "\n";
+ t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", fixForOutput(project->first("QMAKE_ORIG_TARGET"))) << ";" << "\n";
+ } else {
+ if (!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib"))
+ t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "STATIC") << ";" << "\n";
+ else
+ t << "\t\t\t\t" << writeSettings("LIBRARY_STYLE", "DYNAMIC") << ";" << "\n";
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if (!project->isActiveConfig("lib_bundle") && !project->isActiveConfig("staticlib"))
+ lib.prepend("lib");
+ t << "\t\t\t\t" << writeSettings("PRODUCT_NAME", escapeFilePath(lib)) << ";" << "\n";
+ }
+ }
+ t << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << writeSettings("name", name) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ }
+
+ QString key = keyFor("QMAKE_PBX_BUILDSTYLE_" + name);
+ if (project->isActiveConfig("debug") != (bool)as_release) {
+ project->values("QMAKE_PBX_BUILDSTYLES").append(key);
+ active_buildstyle = name;
+ } else if (pbVersion >= 42) {
+ project->values("QMAKE_PBX_BUILDSTYLES").append(key);
+ }
t << "\t\t" << key << " = {" << "\n"
- << "\t\t\t" << writeSettings("isa", "XCBuildConfiguration", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n"
<< "\t\t\t" << "buildSettings = {" << "\n";
for(QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
- t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";\n";
+ t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n";
t << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << writeSettings("isa", "PBXBuildStyle") << ";" << "\n"
<< "\t\t\t" << writeSettings("name", name) << ";" << "\n"
<< "\t\t" << "};" << "\n";
}
-
- QString key = keyFor("QMAKE_PBX_BUILDSTYLE_" + name);
- if(project->isActiveConfig("debug") != (bool)as_release) {
- project->values("QMAKE_PBX_BUILDSTYLES").append(key);
- active_buildstyle = name;
- } else if(pbVersion >= 42) {
- project->values("QMAKE_PBX_BUILDSTYLES").append(key);
- }
- t << "\t\t" << key << " = {" << "\n"
- << "\t\t\t" << writeSettings("buildRules", QStringList(), SettingsAsList, 4) << ";" << "\n"
- << "\t\t\t" << "buildSettings = {" << "\n";
- for(QMap::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it)
- t << "\t\t\t\t" << writeSettings(set_it.key(), set_it.value()) << ";" << "\n";
- t << "\t\t\t" << "};" << "\n"
- << "\t\t\t" << writeSettings("isa", "PBXBuildStyle") << ";" << "\n"
- << "\t\t\t" << writeSettings("name", name) << ";" << "\n"
- << "\t\t" << "};" << "\n";
}
if(pbVersion >= 42) {
- t << "\t\t" << keyFor("QMAKE_PBX_BUILDCONFIG_LIST") << " = {" << "\n"
- << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_PBX_BUILDCONFIGS"), SettingsAsList, 4) << ";" << "\n"
- << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n"
- << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n"
- << "\t\t" << "};" << "\n";
+ for (int i = 0; i < buildConfigGroups.size(); i++) {
+ t << "\t\t" << keyFor("QMAKE_PBX_BUILDCONFIG_LIST_" + buildConfigGroups.at(i)) << " = {" << "\n"
+ << "\t\t\t" << writeSettings("isa", "XCConfigurationList", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("buildConfigurations", project->values("QMAKE_PBX_BUILDCONFIGS_" + buildConfigGroups.at(i)), SettingsAsList, 4) << ";" << "\n"
+ << "\t\t\t" << writeSettings("defaultConfigurationIsVisible", "0", SettingsNoQuote) << ";" << "\n"
+ << "\t\t\t" << writeSettings("defaultConfigurationIsName", active_buildstyle) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
}
//ROOT
t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n"
@@ -1544,7 +1638,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
<< "\t\t\t" << writeSettings("isa", "PBXProject", SettingsNoQuote) << ";" << "\n"
<< "\t\t\t" << writeSettings("mainGroup", keyFor("QMAKE_PBX_ROOT_GROUP")) << ";" << "\n";
if(pbVersion >= 42)
- t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST")) << ";" << "\n";
+ t << "\t\t\t" << writeSettings("buildConfigurationList", keyFor("QMAKE_PBX_BUILDCONFIG_LIST_PROJECT")) << ";" << "\n";
t << "\t\t\t" << writeSettings("projectDirPath", QStringList()) << ";" << "\n"
<< "\t\t\t" << writeSettings("targets", project->values("QMAKE_PBX_TARGETS"), SettingsAsList, 4) << ";" << "\n"
<< "\t\t" << "};" << "\n";
@@ -1693,7 +1787,11 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const
#ifdef Q_OS_DARWIN
ret = QLatin1String("34");
QCFType cfurl;
- OSStatus err = LSFindApplicationForInfo(0, CFSTR("com.apple.Xcode"), 0, 0, &cfurl);
+ // Check for XCode 4 first
+ OSStatus err = LSFindApplicationForInfo(0, CFSTR("com.apple.dt.Xcode"), 0, 0, &cfurl);
+ // Now check for XCode 3
+ if (err == kLSApplicationNotFoundErr)
+ err = LSFindApplicationForInfo(0, CFSTR("com.apple.Xcode"), 0, 0, &cfurl);
if (err == noErr) {
QCFType bundle = CFBundleCreate(0, cfurl);
if (bundle) {
@@ -1703,7 +1801,9 @@ ProjectBuilderMakefileGenerator::pbuilderVersion() const
QStringList versions = QCFString::toQString(str).split(QLatin1Char('.'));
int versionMajor = versions.at(0).toInt();
int versionMinor = versions.at(1).toInt();
- if (versionMajor >= 2) {
+ if (versionMajor >= 3) {
+ ret = QLatin1String("46");
+ } else if (versionMajor >= 2) {
ret = QLatin1String("42");
} else if (versionMajor == 1 && versionMinor >= 5) {
ret = QLatin1String("39");
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 59a615e63ad..63367f116a9 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -2235,10 +2235,6 @@ QString MakefileGenerator::buildArgs(const QString &outdir)
ret += " -win32";
}
- //configs
- for(QStringList::Iterator it = Option::user_configs.begin();
- it != Option::user_configs.end(); ++it)
- ret += " -config " + (*it);
//arguments
for(QStringList::Iterator it = Option::before_user_vars.begin();
it != Option::before_user_vars.end(); ++it) {
@@ -3178,7 +3174,7 @@ MakefileGenerator::pkgConfigPrefix() const
{
if(!project->isEmpty("QMAKE_PKGCONFIG_PREFIX"))
return project->first("QMAKE_PKGCONFIG_PREFIX");
- return QLibraryInfo::location(QLibraryInfo::PrefixPath);
+ return QLibraryInfo::rawLocation(QLibraryInfo::PrefixPath);
}
QString
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index d28d48b4d03..642dd97e683 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -185,9 +185,9 @@ SourceFile *SourceFiles::lookupFile(const char *file)
void SourceFiles::addFile(SourceFile *p, const char *k, bool own_file)
{
- QByteArray ba = p->file.local().toLatin1();
+ const QByteArray ba = p->file.local().toLatin1();
if(!k)
- k = ba;
+ k = ba.constData();
int h = hash(k) % num_nodes;
SourceFileNode *pn = new SourceFileNode;
pn->own_file = own_file;
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp
index b9fec023ab7..b855585500c 100644
--- a/qmake/generators/metamakefile.cpp
+++ b/qmake/generators/metamakefile.cpp
@@ -238,25 +238,21 @@ MakefileGenerator
//initialize the base
QHash basevars;
+ QStringList basecfgs;
if(!project->isEmpty(build + ".CONFIG"))
- basevars["CONFIG"] += project->values(build + ".CONFIG");
- basevars["CONFIG"] += build;
- basevars["CONFIG"] += "build_pass";
+ basecfgs = project->values(build + ".CONFIG");
+ basecfgs += build;
+ basecfgs += "build_pass";
basevars["BUILD_PASS"] = QStringList(build);
QStringList buildname = project->values(build + ".name");
basevars["BUILD_NAME"] = (buildname.isEmpty() ? QStringList(build) : buildname);
//create project
- QMakeProject *build_proj = new QMakeProject(project->properties(), basevars);
+ QMakeProject *build_proj = new QMakeProject(project->properties());
+ build_proj->setExtraVars(basevars);
+ build_proj->setExtraConfigs(basecfgs);
- //all the user configs must be set again afterwards (for .pro tests and for .prf tests)
- const QStringList old_after_user_config = Option::after_user_configs;
- const QStringList old_user_config = Option::user_configs;
- Option::after_user_configs += basevars["CONFIG"];
- Option::user_configs += basevars["CONFIG"];
build_proj->read(project->projectFile());
- Option::after_user_configs = old_after_user_config;
- Option::user_configs = old_user_config;
//done
return createMakefileGenerator(build_proj);
@@ -451,6 +447,8 @@ QT_END_INCLUDE_NAMESPACE
MakefileGenerator *
MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO)
{
+ Option::postProcessProject(proj);
+
MakefileGenerator *mkfile = NULL;
if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
mkfile = new ProjectGenerator;
@@ -496,6 +494,8 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO)
MetaMakefileGenerator *
MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op, bool *success)
{
+ Option::postProcessProject(proj);
+
MetaMakefileGenerator *ret = 0;
if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
Option::qmake_mode == Option::QMAKE_GENERATE_PRL)) {
diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp
index a2eb45ef407..9a181a43f52 100644
--- a/qmake/generators/projectgenerator.cpp
+++ b/qmake/generators/projectgenerator.cpp
@@ -344,8 +344,6 @@ ProjectGenerator::writeMakefile(QTextStream &t)
t << "######################################################################" << endl;
t << "# Automatically generated by qmake (" << qmake_version() << ") " << QDateTime::currentDateTime().toString() << endl;
t << "######################################################################" << endl << endl;
- if(!Option::user_configs.isEmpty())
- t << "CONFIG += " << Option::user_configs.join(" ") << endl;
int i;
for(i = 0; i < Option::before_user_vars.size(); ++i)
t << Option::before_user_vars[i] << endl;
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index 03460551a9a..c088e8e480c 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -404,14 +404,14 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
QString ar_cmd = project->values("QMAKE_LIB").join(" ");
if (ar_cmd.isEmpty())
ar_cmd = "armar --create";
- objectsLinkLine = ar_cmd + " " + var("DEST_TARGET") + " --via " + ar_script_file;
+ objectsLinkLine = ar_cmd + " " + var("DEST_TARGET") + " --via " + escapeFilePath(ar_script_file);
} else {
// Strip off any options since the ar commands will be read from file.
QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0);;
if (ar_cmd.isEmpty())
ar_cmd = "ar";
createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS"));
- objectsLinkLine = ar_cmd + " -M < " + ar_script_file;
+ objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file);
}
} else {
QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
@@ -420,10 +420,10 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
}
if (project->isActiveConfig("rvct_linker")) {
createRvctObjectScriptFile(ld_script_file, project->values("OBJECTS"));
- objectsLinkLine = QString::fromLatin1("--via ") + ld_script_file;
+ objectsLinkLine = QString::fromLatin1("--via ") + escapeFilePath(ld_script_file);
} else {
createLdObjectScriptFile(ld_script_file, project->values("OBJECTS"));
- objectsLinkLine = ld_script_file;
+ objectsLinkLine = escapeFilePath(ld_script_file);
}
}
Win32MakefileGenerator::writeObjectsPart(t);
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 81f541f94eb..e0f55a64c90 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -1615,7 +1615,7 @@ bool VCLinkerTool::parseOption(const char* option)
{
// Split up in subsystem, and version number
QStringList both = QString(option+11).split(",");
- switch (elfHash(both[0].toLatin1())) {
+ switch (elfHash(both[0].toLatin1().constData())) {
case 0x8438445: // CONSOLE
SubSystem = subSystemConsole;
break;
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index 8b1cf519ff6..37d923f9c17 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -477,7 +477,7 @@ protected:
public:
void parseOptions(QStringList& options) {
for (QStringList::ConstIterator it=options.begin(); (it!=options.end()); it++)
- parseOption((*it).toLatin1());
+ parseOption((*it).toLatin1().constData());
}
static QStringList fixCommandLine(const QString &input);
};
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 109b50fd940..434d4b45592 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -1575,11 +1575,11 @@ QString VcprojGenerator::findTemplate(QString file)
QString ret;
if(!exists((ret = file)) &&
!exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) &&
- !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc.net/" + file))) &&
- !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2002/" + file))) &&
- !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2003/" + file))) &&
- !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2005/" + file))) &&
- !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2008/" + file))))
+ !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc.net/" + file))) &&
+ !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2002/" + file))) &&
+ !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2003/" + file))) &&
+ !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2005/" + file))) &&
+ !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::HostDataPath) + "/win32-msvc2008/" + file))))
return "";
debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.toLatin1().constData());
return ret;
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index a26be16f78c..9d983ffc66a 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -649,6 +649,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t)
t << "DEF_FILE = " << varList("DEF_FILE") << endl;
t << "RES_FILE = " << varList("RES_FILE") << endl; // Not on mingw, can't see why not though...
t << "COPY = " << var("QMAKE_COPY") << endl;
+ t << "SED = " << var("QMAKE_STREAM_EDITOR") << endl;
t << "COPY_FILE = " << var("QMAKE_COPY_FILE") << endl;
t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl;
t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
@@ -852,7 +853,22 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t)
}
if(!ret.isEmpty())
ret += "\n\t";
- ret += "-$(INSTALL_FILE) \"" + pkgConfigFileName(true) + "\" \"" + dst_pc + "\"";
+ const QString replace_rule("QMAKE_PKGCONFIG_INSTALL_REPLACE");
+ if (project->isEmpty(replace_rule)
+ || project->isActiveConfig("no_sed_meta_install")
+ || project->isEmpty("QMAKE_STREAM_EDITOR")) {
+ ret += "-$(INSTALL_FILE) \"" + pkgConfigFileName(true) + "\" \"" + dst_pc + "\"";
+ } else {
+ ret += "-$(SED)";
+ QStringList replace_rules = project->values(replace_rule);
+ for (int r = 0; r < replace_rules.size(); ++r) {
+ const QString match = project->first(replace_rules.at(r) + ".match"),
+ replace = project->first(replace_rules.at(r) + ".replace");
+ if (!match.isEmpty() /*&& match != replace*/)
+ ret += " -e \"s," + match + "," + replace + ",g\"";
+ }
+ ret += " \"" + pkgConfigFileName(true) + "\" >\"" + dst_pc + "\"";
+ }
if(!uninst.isEmpty())
uninst.append("\n\t");
uninst.append("-$(DEL_FILE) \"" + dst_pc + "\"");
diff --git a/qmake/main.cpp b/qmake/main.cpp
index 54cf9f9bdf3..985afaa8e85 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -163,7 +163,7 @@ int runQMake(int argc, char **argv)
fn = fn.right(fn.length() - di - 1);
}
- if (!Option::prepareProject()) {
+ if (!Option::prepareProject(fn)) {
exit_val = 3;
break;
}
diff --git a/qmake/option.cpp b/qmake/option.cpp
index 0c649fdd777..b2a1e6982fd 100644
--- a/qmake/option.cpp
+++ b/qmake/option.cpp
@@ -91,8 +91,6 @@ QString Option::output_dir;
Option::QMAKE_RECURSIVE Option::recursive = Option::QMAKE_RECURSIVE_DEFAULT;
QStringList Option::before_user_vars;
QStringList Option::after_user_vars;
-QStringList Option::user_configs;
-QStringList Option::after_user_configs;
QString Option::user_template;
QString Option::user_template_prefix;
QStringList Option::shellPath;
@@ -116,6 +114,7 @@ bool Option::mkfile::do_dep_heuristics = true;
bool Option::mkfile::do_preprocess = false;
bool Option::mkfile::do_stub_makefile = false;
bool Option::mkfile::do_cache = true;
+QString Option::mkfile::project_root;
QString Option::mkfile::project_build_root;
QString Option::mkfile::cachefile;
QStringList Option::mkfile::project_files;
@@ -150,8 +149,11 @@ static QString detectProjectFile(const QString &path)
static QString cleanSpec(const QString &spec)
{
QString ret = QDir::cleanPath(spec);
- if (ret.contains('/'))
- ret = QDir::cleanPath(QFileInfo(ret).absoluteFilePath());
+ if (ret.contains('/')) {
+ const QFileInfo specDirInfo(ret);
+ if (specDirInfo.exists() && specDirInfo.isDir())
+ ret = QDir::cleanPath(specDirInfo.absoluteFilePath());
+ }
return ret;
}
@@ -219,6 +221,8 @@ bool usage(const char *a0)
int
Option::parseCommandLine(int argc, char **argv, int skip)
{
+ QStringList user_configs;
+
bool before = true;
for(int x = skip; x < argc; x++) {
if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */
@@ -303,7 +307,7 @@ Option::parseCommandLine(int argc, char **argv, int skip)
} else if(opt == "nr" || opt == "norecursive") {
Option::recursive = Option::QMAKE_RECURSIVE_NO;
} else if(opt == "config") {
- Option::user_configs += argv[++x];
+ user_configs += argv[++x];
} else {
if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
@@ -376,6 +380,9 @@ Option::parseCommandLine(int argc, char **argv, int skip)
}
}
+ if (!user_configs.isEmpty())
+ Option::before_user_vars += "CONFIG += " + user_configs.join(" ");
+
return Option::QMAKE_CMDLINE_SUCCESS;
}
@@ -576,7 +583,50 @@ void Option::applyHostMode()
}
}
-bool Option::prepareProject()
+QStringList Option::mkspecPaths()
+{
+ QStringList ret;
+ const QString concat = QLatin1String("/mkspecs");
+
+ QByteArray qmakepath = qgetenv("QMAKEPATH");
+ if (!qmakepath.isEmpty()) {
+ const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
+ for (QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
+ ret << ((*it) + concat);
+ }
+ if (!Option::mkfile::project_build_root.isEmpty())
+ ret << Option::mkfile::project_build_root + concat;
+ if (!Option::mkfile::project_root.isEmpty())
+ ret << Option::mkfile::project_root + concat;
+ ret << QLibraryInfo::location(QLibraryInfo::HostDataPath) + concat;
+ ret.removeDuplicates();
+ return ret;
+}
+
+bool Option::resolveSpec(QString *spec)
+{
+ QString qmakespec = fixEnvVariables(*spec);
+ if (qmakespec.isEmpty())
+ qmakespec = "default";
+ if (QDir::isRelativePath(qmakespec)) {
+ QStringList mkspec_roots = mkspecPaths();
+ debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(),
+ mkspec_roots.join("::").toLatin1().constData());
+ for (QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
+ QString mkspec = (*it) + QLatin1Char('/') + qmakespec;
+ if (QFile::exists(mkspec)) {
+ *spec = mkspec;
+ return true;
+ }
+ }
+ fprintf(stderr, "Could not find mkspecs for your QMAKESPEC(%s) after trying:\n\t%s\n",
+ qmakespec.toLatin1().constData(), mkspec_roots.join("\n\t").toLatin1().constData());
+ return false;
+ }
+ return true;
+}
+
+bool Option::prepareProject(const QString &pfile)
{
mkfile::project_build_root.clear();
if (mkfile::do_cache) {
@@ -601,6 +651,37 @@ bool Option::prepareProject()
}
}
no_cache:
+
+ QString srcpath = (pfile != "-")
+ ? QDir::cleanPath(QFileInfo(pfile).absolutePath()) : qmake_getpwd();
+ if (srcpath != output_dir || mkfile::project_build_root.isEmpty()) {
+ QDir srcdir(srcpath);
+ QDir dstdir(output_dir);
+ do {
+ if (!mkfile::project_build_root.isEmpty()) {
+ // If we already know the build root, just match up the source root with it.
+ if (dstdir.path() == mkfile::project_build_root) {
+ mkfile::project_root = srcdir.path();
+ break;
+ }
+ } else {
+ // Look for mkspecs/ in source and build. First to win determines the root.
+ if (dstdir.exists("mkspecs") || srcdir.exists("mkspecs")) {
+ mkfile::project_build_root = dstdir.path();
+ mkfile::project_root = srcdir.path();
+ if (mkfile::project_root == mkfile::project_build_root)
+ mkfile::project_root.clear();
+ break;
+ }
+ }
+ } while (!srcdir.isRoot() && srcdir.cdUp() && !dstdir.isRoot() && dstdir.cdUp());
+ } else {
+ mkfile::project_root.clear();
+ }
+
+ if (!resolveSpec(&Option::mkfile::qmakespec))
+ return false;
+
return true;
}
diff --git a/qmake/option.h b/qmake/option.h
index b8a3b561fa8..23384877fd1 100644
--- a/qmake/option.h
+++ b/qmake/option.h
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
QT_BEGIN_NAMESPACE
@@ -108,7 +109,8 @@ struct Option
//both of these must be called..
static int init(int argc=0, char **argv=0); //parse cmdline
static void applyHostMode();
- static bool prepareProject();
+ static QStringList mkspecPaths();
+ static bool prepareProject(const QString &pfile);
static bool postProcessProject(QMakeProject *);
enum StringFixFlags {
@@ -172,7 +174,7 @@ struct Option
static int warn_level;
enum QMAKE_RECURSIVE { QMAKE_RECURSIVE_DEFAULT, QMAKE_RECURSIVE_YES, QMAKE_RECURSIVE_NO };
static QMAKE_RECURSIVE recursive;
- static QStringList before_user_vars, after_user_vars, user_configs, after_user_configs;
+ static QStringList before_user_vars, after_user_vars;
enum HOST_MODE { HOST_UNKNOWN_MODE, HOST_UNIX_MODE, HOST_WIN_MODE, HOST_MACX_MODE };
static HOST_MODE host_mode;
enum TARG_MODE { TARG_UNKNOWN_MODE, TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE,
@@ -202,6 +204,7 @@ struct Option
static bool do_dep_heuristics;
static bool do_preprocess;
static bool do_stub_makefile;
+ static QString project_root;
static QString project_build_root;
static QString cachefile;
static int cachefile_depth;
@@ -211,33 +214,12 @@ struct Option
private:
static int parseCommandLine(int, char **, int=0);
+ static bool resolveSpec(QString *spec);
};
inline QString fixEnvVariables(const QString &x) { return Option::fixString(x, Option::FixEnvVars); }
inline QStringList splitPathList(const QString &paths) { return paths.split(Option::dirlist_sep); }
-// this is a stripped down version of the one found in QtCore
-class QLibraryInfo
-{
-public:
- enum LibraryLocation
- {
- PrefixPath,
- DocumentationPath,
- HeadersPath,
- LibrariesPath,
- BinariesPath,
- PluginsPath,
- DataPath,
- TranslationsPath,
- SettingsPath,
- ExamplesPath,
- ImportsPath,
- TestsPath
- };
- static QString location(LibraryLocation);
-};
-
QT_END_NAMESPACE
#endif // OPTION_H
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 1179812b1bc..7655f05f2e0 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -530,9 +530,10 @@ static void qmake_error_msg(const QString &msg)
*/
QStringList qmake_feature_paths(QMakeProperty *prop=0)
{
+ const QString mkspecs_concat = QLatin1String("/mkspecs");
+ const QString base_concat = QLatin1String("/features");
QStringList concat;
{
- const QString base_concat = QLatin1String("/features");
switch(Option::target_mode) {
case Option::TARG_MACX_MODE: //also a unix
concat << base_concat + QLatin1String("/mac");
@@ -549,7 +550,7 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0)
}
concat << base_concat;
}
- const QString mkspecs_concat = QLatin1String("/mkspecs");
+
QStringList feature_roots;
QByteArray mkspec_path = qgetenv("QMAKEFEATURES");
if(!mkspec_path.isNull())
@@ -574,44 +575,28 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0)
feature_roots << ((*it) + mkspecs_concat + (*concat_it));
}
}
- if(!Option::mkfile::qmakespec.isEmpty())
- feature_roots << Option::mkfile::qmakespec + QLatin1String("/features");
if(!Option::mkfile::qmakespec.isEmpty()) {
+ // The spec is already platform-dependent, so no subdirs here.
+ feature_roots << Option::mkfile::qmakespec + base_concat;
+
QFileInfo specfi(Option::mkfile::qmakespec);
- QDir specdir(specfi.absoluteFilePath());
- while(!specdir.isRoot()) {
- if(!specdir.cdUp() || specdir.isRoot())
- break;
- if(QFile::exists(specdir.path() + QLatin1String("/features"))) {
+ if (!specfi.isRoot()) {
+ QDir specdir(specfi.absolutePath());
+ if (specdir.exists(QLatin1String("features"))) {
for(QStringList::Iterator concat_it = concat.begin();
concat_it != concat.end(); ++concat_it)
feature_roots << (specdir.path() + (*concat_it));
- break;
}
}
}
for(QStringList::Iterator concat_it = concat.begin();
concat_it != concat.end(); ++concat_it)
- feature_roots << (QLibraryInfo::location(QLibraryInfo::DataPath) +
+ feature_roots << (QLibraryInfo::location(QLibraryInfo::HostDataPath) +
mkspecs_concat + (*concat_it));
+ feature_roots.removeDuplicates();
return feature_roots;
}
-QStringList qmake_mkspec_paths()
-{
- QStringList ret;
- const QString concat = QLatin1String("/mkspecs");
- QByteArray qmakepath = qgetenv("QMAKEPATH");
- if (!qmakepath.isEmpty()) {
- const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
- for(QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
- ret << ((*it) + concat);
- }
- ret << QLibraryInfo::location(QLibraryInfo::DataPath) + concat;
-
- return ret;
-}
-
QMakeProject::~QMakeProject()
{
if(own_prop)
@@ -630,10 +615,8 @@ QMakeProject::~QMakeProject()
void
-QMakeProject::init(QMakeProperty *p, const QHash *vars)
+QMakeProject::init(QMakeProperty *p)
{
- if(vars)
- base_vars = *vars;
if(!p) {
prop = new QMakeProperty;
own_prop = true;
@@ -645,9 +628,11 @@ QMakeProject::init(QMakeProperty *p, const QHash *vars)
reset();
}
-QMakeProject::QMakeProject(QMakeProject *p, const QHash *vars)
+// Duplicate project. It is *not* allowed to call the complex read() functions on the copy.
+QMakeProject::QMakeProject(QMakeProject *p, const QHash *_vars)
{
- init(p->properties(), vars ? vars : &p->variables());
+ init(p->properties());
+ vars = _vars ? *_vars : p->variables();
for(QHash::iterator it = p->replaceFunctions.begin(); it != p->replaceFunctions.end(); ++it) {
it.value()->ref();
replaceFunctions.insert(it.key(), it.value());
@@ -1174,6 +1159,8 @@ QMakeProject::parse(const QString &t, QHash &place, int nu
}
if(var == "REQUIRES") // special case to get communicated to backends!
doProjectCheckReqs(vallist, place);
+ else if (var == "_QMAKE_CACHE_")
+ Option::mkfile::cachefile = varlist.isEmpty() ? QString() : varlist.at(0);
}
return true;
}
@@ -1271,7 +1258,7 @@ QMakeProject::read(const QString &project, uchar cmd)
bool
QMakeProject::read(uchar cmd)
{
- if(cfile.isEmpty()) {
+ if ((cmd & ReadSetup) && base_vars.isEmpty()) {
// hack to get the Option stuff in there
base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext;
base_vars["QMAKE_EXT_C"] = Option::c_ext;
@@ -1280,56 +1267,13 @@ QMakeProject::read(uchar cmd)
if(!Option::user_template_prefix.isEmpty())
base_vars["TEMPLATE_PREFIX"] = QStringList(Option::user_template_prefix);
- if ((cmd & ReadSetup) && Option::mkfile::do_cache) { // parse the cache
+ if (Option::mkfile::do_cache) { // parse the cache
if (Option::output_dir.startsWith(Option::mkfile::project_build_root))
Option::mkfile::cachefile_depth =
Option::output_dir.mid(Option::mkfile::project_build_root.length()).count('/');
}
- if (cmd & ReadSetup) { // parse mkspec
- QString qmakespec = fixEnvVariables(Option::mkfile::qmakespec);
- QStringList mkspec_roots = qmake_mkspec_paths();
- debug_msg(2, "Looking for mkspec %s in (%s)", qmakespec.toLatin1().constData(),
- mkspec_roots.join("::").toLatin1().constData());
- if(qmakespec.isEmpty()) {
- for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
- QString mkspec = (*it) + QLatin1String("/default");
- QFileInfo default_info(mkspec);
- if(default_info.exists() && default_info.isDir()) {
- qmakespec = mkspec;
- break;
- }
- }
- if(qmakespec.isEmpty()) {
- fprintf(stderr, "QMAKESPEC has not been set, so configuration cannot be deduced.\n");
- return false;
- }
- Option::mkfile::qmakespec = qmakespec;
- }
-
- if(QDir::isRelativePath(qmakespec)) {
- if (QFile::exists(Option::output_dir+"/"+qmakespec+"/qmake.conf")) {
- qmakespec = Option::mkfile::qmakespec = QFileInfo(Option::output_dir+"/"+qmakespec).absoluteFilePath();
- } else if (QFile::exists(qmakespec+"/qmake.conf")) {
- Option::mkfile::qmakespec = QFileInfo(Option::mkfile::qmakespec).absoluteFilePath();
- } else {
- bool found_mkspec = false;
- for(QStringList::ConstIterator it = mkspec_roots.begin(); it != mkspec_roots.end(); ++it) {
- QString mkspec = (*it) + QLatin1Char('/') + qmakespec;
- if(QFile::exists(mkspec)) {
- found_mkspec = true;
- Option::mkfile::qmakespec = qmakespec = mkspec;
- break;
- }
- }
- if(!found_mkspec) {
- fprintf(stderr, "Could not find mkspecs for your QMAKESPEC(%s) after trying:\n\t%s\n",
- qmakespec.toLatin1().constData(), mkspec_roots.join("\n\t").toLatin1().constData());
- return false;
- }
- }
- }
-
- // parse qmake configuration
+ { // parse mkspec
+ QString qmakespec = Option::mkfile::qmakespec;
while(qmakespec.endsWith(QLatin1Char('/')))
qmakespec.truncate(qmakespec.length()-1);
QString spec = qmakespec + QLatin1String("/qmake.conf");
@@ -1349,6 +1293,10 @@ QMakeProject::read(uchar cmd)
vars = base_vars; // start with the base
+ for (QHash::ConstIterator it = extra_vars.constBegin();
+ it != extra_vars.constEnd(); ++it)
+ vars.insert(it.key(), it.value());
+
if(cmd & ReadFeatures) {
debug_msg(1, "Processing default_pre: %s", vars["CONFIG"].join("::").toLatin1().constData());
doProjectInclude("default_pre", IncludeFlagFeature, vars);
@@ -1360,7 +1308,6 @@ QMakeProject::read(uchar cmd)
//before commandline
if (cmd & ReadSetup) {
- cfile = pfile;
parser.file = "(internal)";
parser.from_file = false;
parser.line_no = 1; //really arg count now.. duh
@@ -1375,12 +1322,12 @@ QMakeProject::read(uchar cmd)
}
}
- //commandline configs
- if ((cmd & ReadSetup) && !Option::user_configs.isEmpty()) {
- parser.file = "(configs)";
+ // After user configs, to override them
+ if (!extra_configs.isEmpty()) {
+ parser.file = "(extra configs)";
parser.from_file = false;
parser.line_no = 1; //really arg count now.. duh
- parse("CONFIG += " + Option::user_configs.join(" "), vars);
+ parse("CONFIG += " + extra_configs.join(" "), vars);
}
if(cmd & ReadProFile) { // parse project file
@@ -1406,12 +1353,14 @@ QMakeProject::read(uchar cmd)
}
}
- //after configs (set in BUILDS)
- if ((cmd & ReadSetup) && !Option::after_user_configs.isEmpty()) {
- parser.file = "(configs)";
+ // Again, to ensure the project does not mess with us.
+ // Specifically, do not allow a project to override debug/release within a
+ // debug_and_release build pass - it's too late for that at this point anyway.
+ if (!extra_configs.isEmpty()) {
+ parser.file = "(extra configs)";
parser.from_file = false;
parser.line_no = 1; //really arg count now.. duh
- parse("CONFIG += " + Option::after_user_configs.join(" "), vars);
+ parse("CONFIG += " + extra_configs.join(" "), vars);
}
if(cmd & ReadFeatures) {
@@ -1437,7 +1386,6 @@ QMakeProject::read(uchar cmd)
break;
}
}
- Option::postProcessProject(this); // let Option post-process
return true;
}
@@ -1487,7 +1435,7 @@ QMakeProject::resolveSpec(QString *spec, const QString &qmakespec)
if (*spec == "default") {
#ifdef Q_OS_UNIX
char buffer[1024];
- int l = readlink(qmakespec.toLatin1(), buffer, 1023);
+ int l = readlink(qmakespec.toLatin1().constData(), buffer, 1023);
if (l != -1) {
buffer[l] = '\0';
*spec = QString::fromLatin1(buffer);
@@ -1685,12 +1633,8 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QHash args_list,
if(args.count() > 1)
singleLine = (args[1].toLower() == "true");
QString output;
- FILE *proc = QT_POPEN(args[0].toLatin1(), "r");
+ FILE *proc = QT_POPEN(args[0].toLatin1().constData(), "r");
while(proc && !feof(proc)) {
int read_in = int(fread(buff, 1, 255, proc));
if(!read_in)
@@ -3113,19 +3057,19 @@ QStringList &QMakeProject::values(const QString &_var, QHash vars, base_vars;
+ QStringList extra_configs;
+ QHash vars, base_vars, extra_vars;
bool parse(const QString &text, QHash &place, int line_count=1);
enum IncludeStatus {
@@ -105,19 +106,19 @@ class QMakeProject
bool doProjectCheckReqs(const QStringList &deps, QHash &place);
bool doVariableReplace(QString &str, QHash &place);
QStringList doVariableReplaceExpand(const QString &str, QHash &place, bool *ok=0);
- void init(QMakeProperty *, const QHash *);
+ void init(QMakeProperty *);
QStringList &values(const QString &v, QHash &place);
void validateModes();
void resolveSpec(QString *spec, const QString &qmakespec);
public:
- QMakeProject() { init(0, 0); }
- QMakeProject(QMakeProperty *p) { init(p, 0); }
+ QMakeProject(QMakeProperty *p = 0) { init(p); }
QMakeProject(QMakeProject *p, const QHash *nvars=0);
- QMakeProject(const QHash &nvars) { init(0, &nvars); }
- QMakeProject(QMakeProperty *p, const QHash &nvars) { init(p, &nvars); }
~QMakeProject();
+ void setExtraVars(const QHash &_vars) { extra_vars = _vars; }
+ void setExtraConfigs(const QStringList &_cfgs) { extra_configs = _cfgs; }
+
enum { ReadProFile=0x01, ReadSetup=0x02, ReadFeatures=0x04, ReadAll=0xFF };
inline bool parse(const QString &text) { return parse(text, vars); }
bool read(const QString &project, uchar cmd=ReadAll);
diff --git a/qmake/property.cpp b/qmake/property.cpp
index 4221605545e..8ed9462c601 100644
--- a/qmake/property.cpp
+++ b/qmake/property.cpp
@@ -49,10 +49,48 @@
QT_BEGIN_NAMESPACE
-QStringList qmake_mkspec_paths(); //project.cpp
+static const struct {
+ const char *name;
+ QLibraryInfo::LibraryLocation loc;
+ bool raw;
+} propList[] = {
+ { "QT_SYSROOT", QLibraryInfo::SysrootPath, true },
+ { "QT_INSTALL_PREFIX", QLibraryInfo::PrefixPath, false },
+ { "QT_INSTALL_DATA", QLibraryInfo::DataPath, false },
+ { "QT_INSTALL_DOCS", QLibraryInfo::DocumentationPath, false },
+ { "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath, false },
+ { "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath, false },
+ { "QT_INSTALL_BINS", QLibraryInfo::BinariesPath, false },
+ { "QT_INSTALL_TESTS", QLibraryInfo::TestsPath, false },
+ { "QT_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, false },
+ { "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, false },
+ { "QT_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, false },
+ { "QT_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, false },
+ { "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, false },
+ { "QT_INSTALL_DEMOS", QLibraryInfo::ExamplesPath, false }, // Just backwards compat
+ { "QT_RAW_INSTALL_PREFIX", QLibraryInfo::PrefixPath, true },
+ { "QT_RAW_INSTALL_DATA", QLibraryInfo::DataPath, true },
+ { "QT_RAW_INSTALL_DOCS", QLibraryInfo::DocumentationPath, true },
+ { "QT_RAW_INSTALL_HEADERS", QLibraryInfo::HeadersPath, true },
+ { "QT_RAW_INSTALL_LIBS", QLibraryInfo::LibrariesPath, true },
+ { "QT_RAW_INSTALL_BINS", QLibraryInfo::BinariesPath, true },
+ { "QT_RAW_INSTALL_TESTS", QLibraryInfo::TestsPath, true },
+ { "QT_RAW_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, true },
+ { "QT_RAW_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, true },
+ { "QT_RAW_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, true },
+ { "QT_RAW_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, true },
+ { "QT_RAW_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, true },
+ { "QT_HOST_PREFIX", QLibraryInfo::HostPrefixPath, true },
+ { "QT_HOST_DATA", QLibraryInfo::HostDataPath, true },
+ { "QT_HOST_BINS", QLibraryInfo::HostBinariesPath, true },
+};
QMakeProperty::QMakeProperty() : settings(0)
{
+ for (int i = 0; i < sizeof(propList)/sizeof(propList[0]); i++)
+ m_values[QString::fromLatin1(propList[i].name)] = propList[i].raw
+ ? QLibraryInfo::rawLocation(propList[i].loc)
+ : QLibraryInfo::location(propList[i].loc);
}
QMakeProperty::~QMakeProperty()
@@ -80,34 +118,11 @@ QMakeProperty::keyBase(bool version) const
QString
QMakeProperty::value(QString v, bool just_check)
{
- if(v == "QT_INSTALL_PREFIX")
- return QLibraryInfo::location(QLibraryInfo::PrefixPath);
- else if(v == "QT_INSTALL_DATA")
- return QLibraryInfo::location(QLibraryInfo::DataPath);
- else if(v == "QT_INSTALL_DOCS")
- return QLibraryInfo::location(QLibraryInfo::DocumentationPath);
- else if(v == "QT_INSTALL_HEADERS")
- return QLibraryInfo::location(QLibraryInfo::HeadersPath);
- else if(v == "QT_INSTALL_LIBS")
- return QLibraryInfo::location(QLibraryInfo::LibrariesPath);
- else if(v == "QT_INSTALL_BINS")
- return QLibraryInfo::location(QLibraryInfo::BinariesPath);
- else if(v == "QT_INSTALL_TESTS")
- return QLibraryInfo::location(QLibraryInfo::TestsPath);
- else if(v == "QT_INSTALL_PLUGINS")
- return QLibraryInfo::location(QLibraryInfo::PluginsPath);
- else if(v == "QT_INSTALL_IMPORTS")
- return QLibraryInfo::location(QLibraryInfo::ImportsPath);
- else if(v == "QT_INSTALL_TRANSLATIONS")
- return QLibraryInfo::location(QLibraryInfo::TranslationsPath);
- else if(v == "QT_INSTALL_CONFIGURATION")
- return QLibraryInfo::location(QLibraryInfo::SettingsPath);
- else if(v == "QT_INSTALL_EXAMPLES")
- return QLibraryInfo::location(QLibraryInfo::ExamplesPath);
- else if(v == "QT_INSTALL_DEMOS")
- return QLibraryInfo::location(QLibraryInfo::ExamplesPath);
+ QString val = m_values.value(v);
+ if (!val.isNull())
+ return val;
else if(v == "QMAKE_MKSPECS")
- return qmake_mkspec_paths().join(Option::dirlist_sep);
+ return Option::mkspecPaths().join(Option::dirlist_sep);
else if(v == "QMAKE_VERSION")
return qmake_version();
#ifdef QT_VERSION_STR
@@ -194,19 +209,8 @@ QMakeProperty::exec()
}
}
QStringList specialProps;
- specialProps.append("QT_INSTALL_PREFIX");
- specialProps.append("QT_INSTALL_DATA");
- specialProps.append("QT_INSTALL_DOCS");
- specialProps.append("QT_INSTALL_HEADERS");
- specialProps.append("QT_INSTALL_LIBS");
- specialProps.append("QT_INSTALL_BINS");
- specialProps.append("QT_INSTALL_TESTS");
- specialProps.append("QT_INSTALL_PLUGINS");
- specialProps.append("QT_INSTALL_IMPORTS");
- specialProps.append("QT_INSTALL_TRANSLATIONS");
- specialProps.append("QT_INSTALL_CONFIGURATION");
- specialProps.append("QT_INSTALL_EXAMPLES");
- specialProps.append("QT_INSTALL_DEMOS");
+ for (int i = 0; i < sizeof(propList)/sizeof(propList[0]); i++)
+ specialProps.append(QString::fromLatin1(propList[i].name));
specialProps.append("QMAKE_MKSPECS");
specialProps.append("QMAKE_VERSION");
#ifdef QT_VERSION_STR
diff --git a/qmake/property.h b/qmake/property.h
index d67d0ad09de..6195e482fb3 100644
--- a/qmake/property.h
+++ b/qmake/property.h
@@ -44,6 +44,7 @@
#include
#include
+#include
QT_BEGIN_NAMESPACE
@@ -55,6 +56,9 @@ class QMakeProperty
void initSettings();
QString keyBase(bool =true) const;
QString value(QString, bool just_check);
+
+ QHash m_values;
+
public:
QMakeProperty();
~QMakeProperty();
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index abb073c48ea..dda03d43b83 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -42,6 +42,7 @@ bootstrap { #Qt code
qdatetime.cpp \
qdir.cpp \
qdiriterator.cpp \
+ qfiledevice.cpp \
qfile.cpp \
qabstractfileengine.cpp \
qfileinfo.cpp \
diff --git a/qtbase.pro b/qtbase.pro
index 5fc9cb38884..9290d5adcdb 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -39,9 +39,6 @@ confclean.depends += clean
confclean.commands =
unix {
confclean.commands += (cd config.tests/unix/stl && $(MAKE) distclean); \
- (cd config.tests/unix/endian && $(MAKE) distclean); \
- (cd config.tests/unix/ipv6 && $(MAKE) distclean); \
- (cd config.tests/unix/largefile && $(MAKE) distclean); \
(cd config.tests/unix/ptrsize && $(MAKE) distclean); \
(cd config.tests/x11/notype && $(MAKE) distclean); \
(cd config.tests/unix/getaddrinfo && $(MAKE) distclean); \
@@ -50,7 +47,6 @@ unix {
(cd config.tests/unix/mysql && $(MAKE) distclean); \
(cd config.tests/unix/mysql_r && $(MAKE) distclean); \
(cd config.tests/unix/nis && $(MAKE) distclean); \
- (cd config.tests/unix/nix && $(MAKE) distclean); \
(cd config.tests/unix/iodbc && $(MAKE) distclean); \
(cd config.tests/unix/odbc && $(MAKE) distclean); \
(cd config.tests/unix/oci && $(MAKE) distclean); \
@@ -98,7 +94,7 @@ CONFIG -= qt
### installations ####
#qmake
-qmake.path=$$[QT_INSTALL_BINS]
+qmake.path = $$[QT_HOST_BINS]
win32 {
qmake.files=$$QT_BUILD_TREE/bin/qmake.exe
} else {
@@ -107,18 +103,18 @@ win32 {
INSTALLS += qmake
#syncqt
-syncqt.path=$$[QT_INSTALL_BINS]
+syncqt.path = $$[QT_HOST_BINS]
syncqt.files=$$QT_BUILD_TREE/bin/syncqt
win32:syncqt.files=$$QT_BUILD_TREE/bin/syncqt.bat
INSTALLS += syncqt
#qtmodule-configtests
-configtests.path=$$[QT_INSTALL_BINS]
+configtests.path = $$[QT_HOST_BINS]
configtests.files=$$QT_BUILD_TREE/bin/qtmodule-configtests
INSTALLS += configtests
#mkspecs
-mkspecs.path=$$[QT_INSTALL_DATA]/mkspecs
+mkspecs.path = $$[QT_HOST_DATA]/mkspecs
mkspecs.files=$$QT_BUILD_TREE/mkspecs/qconfig.pri $$QT_BUILD_TREE/mkspecs/qmodule.pri $$files($$QT_SOURCE_TREE/mkspecs/*)
mkspecs.files -= $$QT_SOURCE_TREE/mkspecs/modules
unix {
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
index af0ee52e9a6..f6900325bc9 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp
@@ -995,7 +995,7 @@ static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Ta
return stream;
}
-HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
+HB_Face HB_AllocFace(void *font, HB_GetFontTableFunc tableFunc)
{
HB_Face face = (HB_Face )malloc(sizeof(HB_FaceRec));
if (!face)
@@ -1012,6 +1012,30 @@ HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
face->tmpLogClusters = 0;
face->glyphs_substituted = false;
face->buffer = 0;
+ face->font_for_init = font;
+ face->get_font_table_func = tableFunc;
+
+ return face;
+}
+
+HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc)
+{
+ HB_Face face = HB_AllocFace(font, tableFunc);
+ if (face)
+ face = HB_LoadFace(face);
+ return face;
+}
+
+HB_Face HB_LoadFace(HB_Face face)
+{
+ void *font = face->font_for_init;
+ if (!font)
+ return face;
+
+ HB_GetFontTableFunc tableFunc = face->get_font_table_func;
+
+ face->get_font_table_func = 0;
+ face->font_for_init = 0;
HB_Error error = HB_Err_Ok;
HB_Stream stream;
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
index 470e27b6f97..f225a865250 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.h
@@ -201,6 +201,8 @@ typedef struct {
hb_bitfield combiningClass :8;
} HB_GlyphAttributes;
+typedef HB_Error (*HB_GetFontTableFunc)(void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length);
+
typedef struct HB_FaceRec_ {
HB_Bool isSymbolFont;
@@ -217,11 +219,15 @@ typedef struct HB_FaceRec_ {
unsigned int *tmpLogClusters;
int length;
int orig_nglyphs;
+ void *font_for_init;
+ HB_GetFontTableFunc get_font_table_func;
} HB_FaceRec;
-typedef HB_Error (*HB_GetFontTableFunc)(void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length);
+
HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc);
+HB_Face HB_AllocFace(void *font, HB_GetFontTableFunc tableFunc);
+HB_Face HB_LoadFace(HB_Face face);
void HB_FreeFace(HB_Face face);
typedef struct {
diff --git a/src/3rdparty/pcre/AUTHORS b/src/3rdparty/pcre/AUTHORS
new file mode 100644
index 00000000000..ba4753d8583
--- /dev/null
+++ b/src/3rdparty/pcre/AUTHORS
@@ -0,0 +1,45 @@
+THE MAIN PCRE LIBRARY
+---------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2012 University of Cambridge
+All rights reserved
+
+
+PCRE JUST-IN-TIME COMPILATION SUPPORT
+-------------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2010-2012 Zoltan Herczeg
+All rights reserved.
+
+
+STACK-LESS JUST-IN-TIME COMPILER
+--------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2009-2012 Zoltan Herczeg
+All rights reserved.
+
+
+THE C++ WRAPPER LIBRARY
+-----------------------
+
+Written by: Google Inc.
+
+Copyright (c) 2007-2012 Google Inc
+All rights reserved
+
+####
diff --git a/src/3rdparty/pcre/COPYING b/src/3rdparty/pcre/COPYING
new file mode 100644
index 00000000000..58eed01b61d
--- /dev/null
+++ b/src/3rdparty/pcre/COPYING
@@ -0,0 +1,5 @@
+PCRE LICENCE
+
+Please see the file LICENCE in the PCRE distribution for licensing details.
+
+End
diff --git a/src/3rdparty/pcre/LICENCE b/src/3rdparty/pcre/LICENCE
new file mode 100644
index 00000000000..5ce31a828d3
--- /dev/null
+++ b/src/3rdparty/pcre/LICENCE
@@ -0,0 +1,92 @@
+PCRE LICENCE
+------------
+
+PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
+specified below. The documentation for PCRE, supplied in the "doc"
+directory, is distributed under the same terms as the software itself.
+
+The basic library functions are written in C and are freestanding. Also
+included in the distribution is a set of C++ wrapper functions, and a
+just-in-time compiler that can be used to optimize pattern matching. These
+are both optional features that can be omitted when the library is built.
+
+
+THE BASIC LIBRARY FUNCTIONS
+---------------------------
+
+Written by: Philip Hazel
+Email local part: ph10
+Email domain: cam.ac.uk
+
+University of Cambridge Computing Service,
+Cambridge, England.
+
+Copyright (c) 1997-2012 University of Cambridge
+All rights reserved.
+
+
+PCRE JUST-IN-TIME COMPILATION SUPPORT
+-------------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2010-2012 Zoltan Herczeg
+All rights reserved.
+
+
+STACK-LESS JUST-IN-TIME COMPILER
+--------------------------------
+
+Written by: Zoltan Herczeg
+Email local part: hzmester
+Emain domain: freemail.hu
+
+Copyright(c) 2009-2012 Zoltan Herczeg
+All rights reserved.
+
+
+THE C++ WRAPPER FUNCTIONS
+-------------------------
+
+Contributed by: Google Inc.
+
+Copyright (c) 2007-2012, Google Inc.
+All rights reserved.
+
+
+THE "BSD" LICENCE
+-----------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the name of Google
+ Inc. nor the names of their contributors may be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+End
diff --git a/src/3rdparty/pcre/pcre.h b/src/3rdparty/pcre/pcre.h
new file mode 100644
index 00000000000..712bd3d714b
--- /dev/null
+++ b/src/3rdparty/pcre/pcre.h
@@ -0,0 +1,503 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This is the public header file for the PCRE library, to be #included by
+applications that call the PCRE functions.
+
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef _PCRE_H
+#define _PCRE_H
+
+/* The current PCRE version information. */
+
+#define PCRE_MAJOR 8
+#define PCRE_MINOR 30
+#define PCRE_PRERELEASE
+#define PCRE_DATE 2012-02-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
+export setting is defined in pcre_internal.h, which includes this file. So we
+don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
+
+#if defined(_WIN32) && !defined(PCRE_STATIC)
+# ifndef PCRE_EXP_DECL
+# define PCRE_EXP_DECL extern __declspec(dllimport)
+# endif
+# ifdef __cplusplus
+# ifndef PCRECPP_EXP_DECL
+# define PCRECPP_EXP_DECL extern __declspec(dllimport)
+# endif
+# ifndef PCRECPP_EXP_DEFN
+# define PCRECPP_EXP_DEFN __declspec(dllimport)
+# endif
+# endif
+#endif
+
+/* By default, we use the standard "extern" declarations. */
+
+#ifndef PCRE_EXP_DECL
+# ifdef __cplusplus
+# define PCRE_EXP_DECL extern "C"
+# else
+# define PCRE_EXP_DECL extern
+# endif
+#endif
+
+#ifdef __cplusplus
+# ifndef PCRECPP_EXP_DECL
+# define PCRECPP_EXP_DECL extern
+# endif
+# ifndef PCRECPP_EXP_DEFN
+# define PCRECPP_EXP_DEFN
+# endif
+#endif
+
+/* Have to include stdlib.h in order to ensure that size_t is defined;
+it is needed here for malloc. */
+
+#include
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options. Some are compile-time only, some are run-time only, and some are
+both, so we keep them all distinct. However, almost all the bits in the options
+word are now used. In the long run, we may have to re-use some of the
+compile-time only bits for runtime options, or vice versa. In the comments
+below, "compile", "exec", and "DFA exec" mean that the option is permitted to
+be set for those functions; "used in" means that an option may be set only for
+compile, but is subsequently referenced in exec and/or DFA exec. Any of the
+compile-time options may be inspected during studying (and therefore JIT
+compiling). */
+
+#define PCRE_CASELESS 0x00000001 /* Compile */
+#define PCRE_MULTILINE 0x00000002 /* Compile */
+#define PCRE_DOTALL 0x00000004 /* Compile */
+#define PCRE_EXTENDED 0x00000008 /* Compile */
+#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
+#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
+#define PCRE_EXTRA 0x00000040 /* Compile */
+#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
+#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
+#define PCRE_UNGREEDY 0x00000200 /* Compile */
+#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
+#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
+#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
+/* The next two are also used in exec and DFA exec */
+#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
+#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
+#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
+#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
+#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
+#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
+#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
+#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
+#define PCRE_DUPNAMES 0x00080000 /* Compile */
+#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */
+#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
+#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
+#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
+#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
+#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
+#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
+#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
+#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
+#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
+
+/* Exec-time and get/set-time error codes */
+
+#define PCRE_ERROR_NOMATCH (-1)
+#define PCRE_ERROR_NULL (-2)
+#define PCRE_ERROR_BADOPTION (-3)
+#define PCRE_ERROR_BADMAGIC (-4)
+#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
+#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
+#define PCRE_ERROR_NOMEMORY (-6)
+#define PCRE_ERROR_NOSUBSTRING (-7)
+#define PCRE_ERROR_MATCHLIMIT (-8)
+#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
+#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
+#define PCRE_ERROR_PARTIAL (-12)
+#define PCRE_ERROR_BADPARTIAL (-13)
+#define PCRE_ERROR_INTERNAL (-14)
+#define PCRE_ERROR_BADCOUNT (-15)
+#define PCRE_ERROR_DFA_UITEM (-16)
+#define PCRE_ERROR_DFA_UCOND (-17)
+#define PCRE_ERROR_DFA_UMLIMIT (-18)
+#define PCRE_ERROR_DFA_WSSIZE (-19)
+#define PCRE_ERROR_DFA_RECURSE (-20)
+#define PCRE_ERROR_RECURSIONLIMIT (-21)
+#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
+#define PCRE_ERROR_BADNEWLINE (-23)
+#define PCRE_ERROR_BADOFFSET (-24)
+#define PCRE_ERROR_SHORTUTF8 (-25)
+#define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */
+#define PCRE_ERROR_RECURSELOOP (-26)
+#define PCRE_ERROR_JIT_STACKLIMIT (-27)
+#define PCRE_ERROR_BADMODE (-28)
+#define PCRE_ERROR_BADENDIANNESS (-29)
+
+/* Specific error codes for UTF-8 validity checks */
+
+#define PCRE_UTF8_ERR0 0
+#define PCRE_UTF8_ERR1 1
+#define PCRE_UTF8_ERR2 2
+#define PCRE_UTF8_ERR3 3
+#define PCRE_UTF8_ERR4 4
+#define PCRE_UTF8_ERR5 5
+#define PCRE_UTF8_ERR6 6
+#define PCRE_UTF8_ERR7 7
+#define PCRE_UTF8_ERR8 8
+#define PCRE_UTF8_ERR9 9
+#define PCRE_UTF8_ERR10 10
+#define PCRE_UTF8_ERR11 11
+#define PCRE_UTF8_ERR12 12
+#define PCRE_UTF8_ERR13 13
+#define PCRE_UTF8_ERR14 14
+#define PCRE_UTF8_ERR15 15
+#define PCRE_UTF8_ERR16 16
+#define PCRE_UTF8_ERR17 17
+#define PCRE_UTF8_ERR18 18
+#define PCRE_UTF8_ERR19 19
+#define PCRE_UTF8_ERR20 20
+#define PCRE_UTF8_ERR21 21
+
+/* Specific error codes for UTF-16 validity checks */
+
+#define PCRE_UTF16_ERR0 0
+#define PCRE_UTF16_ERR1 1
+#define PCRE_UTF16_ERR2 2
+#define PCRE_UTF16_ERR3 3
+#define PCRE_UTF16_ERR4 4
+
+/* Request types for pcre_fullinfo() */
+
+#define PCRE_INFO_OPTIONS 0
+#define PCRE_INFO_SIZE 1
+#define PCRE_INFO_CAPTURECOUNT 2
+#define PCRE_INFO_BACKREFMAX 3
+#define PCRE_INFO_FIRSTBYTE 4
+#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
+#define PCRE_INFO_FIRSTTABLE 5
+#define PCRE_INFO_LASTLITERAL 6
+#define PCRE_INFO_NAMEENTRYSIZE 7
+#define PCRE_INFO_NAMECOUNT 8
+#define PCRE_INFO_NAMETABLE 9
+#define PCRE_INFO_STUDYSIZE 10
+#define PCRE_INFO_DEFAULT_TABLES 11
+#define PCRE_INFO_OKPARTIAL 12
+#define PCRE_INFO_JCHANGED 13
+#define PCRE_INFO_HASCRORLF 14
+#define PCRE_INFO_MINLENGTH 15
+#define PCRE_INFO_JIT 16
+#define PCRE_INFO_JITSIZE 17
+
+/* Request types for pcre_config(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_CONFIG_UTF8 0
+#define PCRE_CONFIG_NEWLINE 1
+#define PCRE_CONFIG_LINK_SIZE 2
+#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
+#define PCRE_CONFIG_MATCH_LIMIT 4
+#define PCRE_CONFIG_STACKRECURSE 5
+#define PCRE_CONFIG_UNICODE_PROPERTIES 6
+#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
+#define PCRE_CONFIG_BSR 8
+#define PCRE_CONFIG_JIT 9
+#define PCRE_CONFIG_UTF16 10
+#define PCRE_CONFIG_JITTARGET 11
+
+/* Request types for pcre_study(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_STUDY_JIT_COMPILE 0x0001
+
+/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
+these bits, just add new ones on the end, in order to remain compatible. */
+
+#define PCRE_EXTRA_STUDY_DATA 0x0001
+#define PCRE_EXTRA_MATCH_LIMIT 0x0002
+#define PCRE_EXTRA_CALLOUT_DATA 0x0004
+#define PCRE_EXTRA_TABLES 0x0008
+#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
+#define PCRE_EXTRA_MARK 0x0020
+#define PCRE_EXTRA_EXECUTABLE_JIT 0x0040
+
+/* Types */
+
+struct real_pcre; /* declaration; the definition is private */
+typedef struct real_pcre pcre;
+
+struct real_pcre16; /* declaration; the definition is private */
+typedef struct real_pcre16 pcre16;
+
+struct real_pcre_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre_jit_stack pcre_jit_stack;
+
+struct real_pcre16_jit_stack; /* declaration; the definition is private */
+typedef struct real_pcre16_jit_stack pcre16_jit_stack;
+
+/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
+a 16 bit wide signed data type. Otherwise it can be a dummy data type since
+pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
+#ifndef PCRE_UCHAR16
+#define PCRE_UCHAR16 unsigned short
+#endif
+
+#ifndef PCRE_SPTR16
+#define PCRE_SPTR16 const PCRE_UCHAR16 *
+#endif
+
+/* When PCRE is compiled as a C++ library, the subject pointer type can be
+replaced with a custom type. For conventional use, the public interface is a
+const char *. */
+
+#ifndef PCRE_SPTR
+#define PCRE_SPTR const char *
+#endif
+
+/* The structure for passing additional data to pcre_exec(). This is defined in
+such as way as to be extensible. Always add new fields at the end, in order to
+remain compatible. */
+
+typedef struct pcre_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ unsigned char **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre_extra;
+
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_extra {
+ unsigned long int flags; /* Bits for which fields are set */
+ void *study_data; /* Opaque data from pcre_study() */
+ unsigned long int match_limit; /* Maximum number of calls to match() */
+ void *callout_data; /* Data passed back in callouts */
+ const unsigned char *tables; /* Pointer to character tables */
+ unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+ PCRE_UCHAR16 **mark; /* For passing back a mark pointer */
+ void *executable_jit; /* Contains a pointer to a compiled jit code */
+} pcre16_extra;
+
+/* The structure for passing out data via the pcre_callout_function. We use a
+structure so that new fields can be added on the end in future versions,
+without changing the API of the function, thereby allowing old clients to work
+without modification. */
+
+typedef struct pcre_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const unsigned char *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre_callout_block;
+
+/* Same structure as above, but with 16 bit char pointers. */
+
+typedef struct pcre16_callout_block {
+ int version; /* Identifies version of block */
+ /* ------------------------ Version 0 ------------------------------- */
+ int callout_number; /* Number compiled into pattern */
+ int *offset_vector; /* The offset vector */
+ PCRE_SPTR16 subject; /* The subject being matched */
+ int subject_length; /* The length of the subject */
+ int start_match; /* Offset to start of this match attempt */
+ int current_position; /* Where we currently are in the subject */
+ int capture_top; /* Max current capture */
+ int capture_last; /* Most recently closed capture */
+ void *callout_data; /* Data passed in with the call */
+ /* ------------------- Added for Version 1 -------------------------- */
+ int pattern_position; /* Offset to next item in the pattern */
+ int next_item_length; /* Length of next item in the pattern */
+ /* ------------------- Added for Version 2 -------------------------- */
+ const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */
+ /* ------------------------------------------------------------------ */
+} pcre16_callout_block;
+
+/* Indirection for store get and free functions. These can be set to
+alternative malloc/free functions if required. Special ones are used in the
+non-recursive case for "frames". There is also an optional callout function
+that is triggered by the (?) regex item. For Virtual Pascal, these definitions
+have to take another form. */
+
+#ifndef VPCOMPAT
+PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre_free)(void *);
+PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
+
+PCRE_EXP_DECL void *(*pcre16_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_free)(void *);
+PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
+PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
+PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
+#else /* VPCOMPAT */
+PCRE_EXP_DECL void *pcre_malloc(size_t);
+PCRE_EXP_DECL void pcre_free(void *);
+PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre_stack_free(void *);
+PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
+
+PCRE_EXP_DECL void *pcre16_malloc(size_t);
+PCRE_EXP_DECL void pcre16_free(void *);
+PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
+PCRE_EXP_DECL void pcre16_stack_free(void *);
+PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
+#endif /* VPCOMPAT */
+
+/* User defined callback which provides a stack just before the match starts. */
+
+typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
+typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
+
+/* Exported PCRE functions */
+
+PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
+ const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
+ const unsigned char *);
+PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
+ int *, const unsigned char *);
+PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
+ int *, const unsigned char *);
+PCRE_EXP_DECL int pcre_config(int, void *);
+PCRE_EXP_DECL int pcre16_config(int, void *);
+PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
+ int *, int, const char *, char *, int);
+PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
+ char *, int);
+PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_UCHAR16 *, int);
+PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
+ const char *, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
+ int, int, int, int *, int);
+PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
+ PCRE_SPTR16, int, int, int, int *, int);
+PCRE_EXP_DECL void pcre_free_substring(const char *);
+PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
+PCRE_EXP_DECL void pcre_free_substring_list(const char **);
+PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
+ void *);
+PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
+ void *);
+PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
+ int *, int, const char *, const char **);
+PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
+ int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
+PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
+PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
+ char **, char **);
+PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
+ PCRE_UCHAR16 **, PCRE_UCHAR16 **);
+PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
+ const char **);
+PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
+ PCRE_SPTR16 *);
+PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
+ const char ***);
+PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
+ PCRE_SPTR16 **);
+PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
+PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
+PCRE_EXP_DECL int pcre_refcount(pcre *, int);
+PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
+PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
+PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
+PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
+PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
+PCRE_EXP_DECL const char *pcre_version(void);
+PCRE_EXP_DECL const char *pcre16_version(void);
+
+/* Utility functions for byte order swaps. */
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
+ const unsigned char *);
+PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
+ PCRE_SPTR16, int, int *, int);
+
+/* JIT compiler related functions. */
+
+PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
+PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
+PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
+PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
+PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
+ pcre_jit_callback, void *);
+PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
+ pcre16_jit_callback, void *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* End of pcre.h */
diff --git a/src/3rdparty/pcre/pcre16_byte_order.c b/src/3rdparty/pcre/pcre16_byte_order.c
new file mode 100644
index 00000000000..11d2973a3db
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_byte_order.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_byte_order.c"
+
+/* End of pcre16_byte_order.c */
diff --git a/src/3rdparty/pcre/pcre16_chartables.c b/src/3rdparty/pcre/pcre16_chartables.c
new file mode 100644
index 00000000000..7c0ff35f5e0
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_chartables.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_chartables.c"
+
+/* End of pcre16_chartables.c */
diff --git a/src/3rdparty/pcre/pcre16_compile.c b/src/3rdparty/pcre/pcre16_compile.c
new file mode 100644
index 00000000000..e499b670877
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_compile.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_compile.c"
+
+/* End of pcre16_compile.c */
diff --git a/src/3rdparty/pcre/pcre16_config.c b/src/3rdparty/pcre/pcre16_config.c
new file mode 100644
index 00000000000..b52138764f6
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_config.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_config.c"
+
+/* End of pcre16_config.c */
diff --git a/src/3rdparty/pcre/pcre16_dfa_exec.c b/src/3rdparty/pcre/pcre16_dfa_exec.c
new file mode 100644
index 00000000000..2ba740e972b
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_dfa_exec.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_dfa_exec.c"
+
+/* End of pcre16_dfa_exec.c */
diff --git a/src/3rdparty/pcre/pcre16_exec.c b/src/3rdparty/pcre/pcre16_exec.c
new file mode 100644
index 00000000000..7417b1770c6
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_exec.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_exec.c"
+
+/* End of pcre16_exec.c */
diff --git a/src/3rdparty/pcre/pcre16_fullinfo.c b/src/3rdparty/pcre/pcre16_fullinfo.c
new file mode 100644
index 00000000000..544dca6ed5c
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_fullinfo.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_fullinfo.c"
+
+/* End of pcre16_fullinfo.c */
diff --git a/src/3rdparty/pcre/pcre16_get.c b/src/3rdparty/pcre/pcre16_get.c
new file mode 100644
index 00000000000..3ded08c622c
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_get.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_get.c"
+
+/* End of pcre16_get.c */
diff --git a/src/3rdparty/pcre/pcre16_globals.c b/src/3rdparty/pcre/pcre16_globals.c
new file mode 100644
index 00000000000..a136b3d8c22
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_globals.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_globals.c"
+
+/* End of pcre16_globals.c */
diff --git a/src/3rdparty/pcre/pcre16_jit_compile.c b/src/3rdparty/pcre/pcre16_jit_compile.c
new file mode 100644
index 00000000000..ab0cacd7646
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_jit_compile.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_jit_compile.c"
+
+/* End of pcre16_jit_compile.c */
diff --git a/src/3rdparty/pcre/pcre16_maketables.c b/src/3rdparty/pcre/pcre16_maketables.c
new file mode 100644
index 00000000000..b1cd1c579d6
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_maketables.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_maketables.c"
+
+/* End of pcre16_maketables.c */
diff --git a/src/3rdparty/pcre/pcre16_newline.c b/src/3rdparty/pcre/pcre16_newline.c
new file mode 100644
index 00000000000..7fe201400f5
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_newline.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_newline.c"
+
+/* End of pcre16_newline.c */
diff --git a/src/3rdparty/pcre/pcre16_ord2utf16.c b/src/3rdparty/pcre/pcre16_ord2utf16.c
new file mode 100644
index 00000000000..9f7db8661fc
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_ord2utf16.c
@@ -0,0 +1,95 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF16 string. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+/*************************************************
+* Convert character value to UTF-16 *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x10ffff
+and encodes it as a UTF-16 character in 1 to 2 pcre_uchars.
+
+Arguments:
+ cvalue the character value
+ buffer pointer to buffer for result - at least 2 pcre_uchars long
+
+Returns: number of characters placed in the buffer
+*/
+
+int
+PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
+{
+#ifdef SUPPORT_UTF
+
+/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
+Should never happen in practice. */
+if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
+ cvalue = 0xfffe;
+
+if (cvalue <= 0xffff)
+ {
+ *buffer = (pcre_uchar)cvalue;
+ return 1;
+ }
+
+cvalue -= 0x10000;
+*buffer++ = 0xd800 | (cvalue >> 10);
+*buffer = 0xdc00 | (cvalue & 0x3ff);
+return 2;
+
+#else /* SUPPORT_UTF */
+(void)(cvalue); /* Keep compiler happy; this function won't ever be */
+(void)(buffer); /* called when SUPPORT_UTF is not defined. */
+return 0;
+#endif /* SUPPORT_UTF */
+}
+
+/* End of pcre16_ord2utf16.c */
diff --git a/src/3rdparty/pcre/pcre16_refcount.c b/src/3rdparty/pcre/pcre16_refcount.c
new file mode 100644
index 00000000000..d3d15439737
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_refcount.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_refcount.c"
+
+/* End of pcre16_refcount.c */
diff --git a/src/3rdparty/pcre/pcre16_string_utils.c b/src/3rdparty/pcre/pcre16_string_utils.c
new file mode 100644
index 00000000000..382c40799fb
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_string_utils.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_string_utils.c"
+
+/* End of pcre16_string_utils.c */
diff --git a/src/3rdparty/pcre/pcre16_study.c b/src/3rdparty/pcre/pcre16_study.c
new file mode 100644
index 00000000000..f87de081fc4
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_study.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_study.c"
+
+/* End of pcre16_study.c */
diff --git a/src/3rdparty/pcre/pcre16_tables.c b/src/3rdparty/pcre/pcre16_tables.c
new file mode 100644
index 00000000000..d84297093a4
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_tables.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_tables.c"
+
+/* End of pcre16_tables.c */
diff --git a/src/3rdparty/pcre/pcre16_ucd.c b/src/3rdparty/pcre/pcre16_ucd.c
new file mode 100644
index 00000000000..ee23439a013
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_ucd.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_ucd.c"
+
+/* End of pcre16_ucd.c */
diff --git a/src/3rdparty/pcre/pcre16_utf16_utils.c b/src/3rdparty/pcre/pcre16_utf16_utils.c
new file mode 100644
index 00000000000..7cfdbdd5eee
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_utf16_utils.c
@@ -0,0 +1,129 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains a function for converting any UTF-16 character
+strings to host byte order. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+/*************************************************
+* Convert any UTF-16 string to host byte order *
+*************************************************/
+
+/* This function takes an UTF-16 string and converts
+it to host byte order. The length can be explicitly set,
+or automatically detected for zero terminated strings.
+BOMs can be kept or discarded during the conversion.
+Conversion can be done in place (output == input).
+
+Arguments:
+ output the output buffer, its size must be greater
+ or equal than the input string
+ input any UTF-16 string
+ length the number of 16-bit units in the input string
+ can be less than zero for zero terminated strings
+ host_byte_order
+ A non-zero value means the input is in host byte
+ order, which can be dynamically changed by BOMs later.
+ Initially it contains the starting byte order and returns
+ with the last byte order so it can be used for stream
+ processing. It can be NULL, which set the host byte
+ order mode by default.
+ keep_boms for a non-zero value, the BOM (0xfeff) characters
+ are copied as well
+
+Returns: the number of 16-bit units placed into the output buffer,
+ including the zero-terminator
+*/
+
+int
+pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input,
+ int length, int *host_byte_order, int keep_boms)
+{
+#ifdef SUPPORT_UTF
+/* This function converts any UTF-16 string to host byte order and optionally
+removes any Byte Order Marks (BOMS). Returns with the remainig length. */
+int host_bo = host_byte_order != NULL ? *host_byte_order : 1;
+pcre_uchar *optr = (pcre_uchar *)output;
+const pcre_uchar *iptr = (const pcre_uchar *)input;
+const pcre_uchar *end;
+/* The c variable must be unsigned. */
+register pcre_uchar c;
+
+if (length < 0)
+ length = STRLEN_UC(iptr) + 1;
+end = iptr + length;
+
+while (iptr < end)
+ {
+ c = *iptr++;
+ if (c == 0xfeff || c == 0xfffe)
+ {
+ /* Detecting the byte order of the machine is unnecessary, it is
+ enough to know that the UTF-16 string has the same byte order or not. */
+ host_bo = c == 0xfeff;
+ if (keep_boms != 0)
+ *optr++ = 0xfeff;
+ else
+ length--;
+ }
+ else
+ *optr++ = host_bo ? c : ((c >> 8) | (c << 8)); /* Flip bytes if needed. */
+ }
+if (host_byte_order != NULL)
+ *host_byte_order = host_bo;
+
+#else /* SUPPORT_UTF */
+(void)(output); /* Keep picky compilers happy */
+(void)(input);
+(void)(keep_boms);
+#endif /* SUPPORT_UTF */
+return length;
+}
+
+/* End of pcre16_utf16_utils.c */
diff --git a/src/3rdparty/pcre/pcre16_valid_utf16.c b/src/3rdparty/pcre/pcre16_valid_utf16.c
new file mode 100644
index 00000000000..90b9f867708
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_valid_utf16.c
@@ -0,0 +1,146 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function for validating UTF-16 character
+strings. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Validate a UTF-16 string *
+*************************************************/
+
+/* This function is called (optionally) at the start of compile or match, to
+check that a supposed UTF-16 string is actually valid. The early check means
+that subsequent code can assume it is dealing with a valid string. The check
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
+
+From release 8.21 more information about the details of the error are passed
+back in the returned value:
+
+PCRE_UTF16_ERR0 No error
+PCRE_UTF16_ERR1 Missing low surrogate at the end of the string
+PCRE_UTF16_ERR2 Invalid low surrogate
+PCRE_UTF16_ERR3 Isolated low surrogate
+PCRE_UTF16_ERR4 Not allowed character
+
+Arguments:
+ string points to the string
+ length length of string, or -1 if the string is zero-terminated
+ errp pointer to an error position offset variable
+
+Returns: = 0 if the string is a valid UTF-16 string
+ > 0 otherwise, setting the offset of the bad character
+*/
+
+int
+PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
+{
+#ifdef SUPPORT_UTF
+register PCRE_PUCHAR p;
+register pcre_uchar c;
+
+if (length < 0)
+ {
+ for (p = string; *p != 0; p++);
+ length = p - string;
+ }
+
+for (p = string; length-- > 0; p++)
+ {
+ c = *p;
+
+ if ((c & 0xf800) != 0xd800)
+ {
+ /* Normal UTF-16 code point. Neither high nor low surrogate. */
+
+ /* This is probably a BOM from a different byte-order.
+ Regardless, the string is rejected. */
+ if (c == 0xfffe)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR4;
+ }
+ }
+ else if ((c & 0x0400) == 0)
+ {
+ /* High surrogate. */
+
+ /* Must be a followed by a low surrogate. */
+ if (length == 0)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR1;
+ }
+ p++;
+ length--;
+ if ((*p & 0xfc00) != 0xdc00)
+ {
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR2;
+ }
+ }
+ else
+ {
+ /* Isolated low surrogate. Always an error. */
+ *erroroffset = p - string;
+ return PCRE_UTF16_ERR3;
+ }
+ }
+
+#else /* SUPPORT_UTF */
+(void)(string); /* Keep picky compilers happy */
+(void)(length);
+#endif /* SUPPORT_UTF */
+
+return PCRE_UTF16_ERR0; /* This indicates success */
+}
+
+/* End of pcre16_valid_utf16.c */
diff --git a/src/3rdparty/pcre/pcre16_version.c b/src/3rdparty/pcre/pcre16_version.c
new file mode 100644
index 00000000000..e991b1a8cfd
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_version.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_version.c"
+
+/* End of pcre16_version.c */
diff --git a/src/3rdparty/pcre/pcre16_xclass.c b/src/3rdparty/pcre/pcre16_xclass.c
new file mode 100644
index 00000000000..5aac2a36c68
--- /dev/null
+++ b/src/3rdparty/pcre/pcre16_xclass.c
@@ -0,0 +1,45 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* Generate code with 16 bit character support. */
+#define COMPILE_PCRE16
+
+#include "pcre_xclass.c"
+
+/* End of pcre16_xclass.c */
diff --git a/src/3rdparty/pcre/pcre_byte_order.c b/src/3rdparty/pcre/pcre_byte_order.c
new file mode 100644
index 00000000000..6f5fa742d6d
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_byte_order.c
@@ -0,0 +1,288 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that tests a compiled pattern to
+see if it was compiled with the opposite endianness. If so, it uses an
+auxiliary local function to flip the appropriate bytes. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Swap byte functions *
+*************************************************/
+
+/* The following functions swap the bytes of a pcre_uint16
+and pcre_uint32 value.
+
+Arguments:
+ value any number
+
+Returns: the byte swapped value
+*/
+
+static pcre_uint32
+swap_uint32(pcre_uint32 value)
+{
+return ((value & 0x000000ff) << 24) |
+ ((value & 0x0000ff00) << 8) |
+ ((value & 0x00ff0000) >> 8) |
+ (value >> 24);
+}
+
+static pcre_uint16
+swap_uint16(pcre_uint16 value)
+{
+return (value >> 8) | (value << 8);
+}
+
+
+/*************************************************
+* Test for a byte-flipped compiled regex *
+*************************************************/
+
+/* This function swaps the bytes of a compiled pattern usually
+loaded form the disk. It also sets the tables pointer, which
+is likely an invalid pointer after reload.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ tables points to the character tables or NULL
+
+Returns: 0 if the swap is successful, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
+ pcre_extra *extra_data, const unsigned char *tables)
+#else
+PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
+ pcre16_extra *extra_data, const unsigned char *tables)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+pcre_study_data *study;
+#ifndef COMPILE_PCRE8
+pcre_uchar *ptr;
+int length;
+#ifdef SUPPORT_UTF
+BOOL utf;
+BOOL utf16_char;
+#endif /* SUPPORT_UTF */
+#endif /* !COMPILE_PCRE8 */
+
+if (re == NULL) return PCRE_ERROR_NULL;
+if (re->magic_number == MAGIC_NUMBER)
+ {
+ if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+ re->tables = tables;
+ return 0;
+ }
+
+if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
+if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+re->magic_number = MAGIC_NUMBER;
+re->size = swap_uint32(re->size);
+re->options = swap_uint32(re->options);
+re->flags = swap_uint16(re->flags);
+re->top_bracket = swap_uint16(re->top_bracket);
+re->top_backref = swap_uint16(re->top_backref);
+re->first_char = swap_uint16(re->first_char);
+re->req_char = swap_uint16(re->req_char);
+re->name_table_offset = swap_uint16(re->name_table_offset);
+re->name_entry_size = swap_uint16(re->name_entry_size);
+re->name_count = swap_uint16(re->name_count);
+re->ref_count = swap_uint16(re->ref_count);
+re->tables = tables;
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ {
+ study = (pcre_study_data *)extra_data->study_data;
+ study->size = swap_uint32(study->size);
+ study->flags = swap_uint32(study->flags);
+ study->minlength = swap_uint32(study->minlength);
+ }
+
+#ifndef COMPILE_PCRE8
+ptr = (pcre_uchar *)re + re->name_table_offset;
+length = re->name_count * re->name_entry_size;
+#ifdef SUPPORT_UTF
+utf = (re->options & PCRE_UTF16) != 0;
+utf16_char = FALSE;
+#endif
+
+while(TRUE)
+ {
+ /* Swap previous characters. */
+ while (length-- > 0)
+ {
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+#ifdef SUPPORT_UTF
+ if (utf16_char)
+ {
+ if (HAS_EXTRALEN(ptr[-1]))
+ {
+ /* We know that there is only one extra character in UTF-16. */
+ *ptr = swap_uint16(*ptr);
+ ptr++;
+ }
+ }
+ utf16_char = FALSE;
+#endif /* SUPPORT_UTF */
+
+ /* Get next opcode. */
+ length = 0;
+ *ptr = swap_uint16(*ptr);
+ switch (*ptr)
+ {
+ case OP_END:
+ return 0;
+
+#ifdef SUPPORT_UTF
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ if (utf) utf16_char = TRUE;
+#endif
+ /* Fall through. */
+
+ default:
+ length = PRIV(OP_lengths)[*ptr] - 1;
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uchar);
+ length = 0;
+ break;
+
+ case OP_XCLASS:
+ /* Reverse the size of the XCLASS instance. */
+ ptr++;
+ *ptr = swap_uint16(*ptr);
+ if (LINK_SIZE > 1)
+ {
+ /* LINK_SIZE can be 1 or 2 in 16 bit mode. */
+ ptr++;
+ *ptr = swap_uint16(*ptr);
+ }
+ ptr++;
+ length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
+ *ptr = swap_uint16(*ptr);
+ if ((*ptr & XCL_MAP) != 0)
+ {
+ /* Skip the character bit map. */
+ ptr += 32/sizeof(pcre_uchar);
+ length -= 32/sizeof(pcre_uchar);
+ }
+ break;
+ }
+ ptr++;
+ }
+/* Control should never reach here in 16 bit mode. */
+#endif /* !COMPILE_PCRE8 */
+
+return 0;
+}
+
+/* End of pcre_byte_order.c */
diff --git a/src/3rdparty/pcre/pcre_chartables.c b/src/3rdparty/pcre/pcre_chartables.c
new file mode 100644
index 00000000000..55df49777de
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_chartables.c
@@ -0,0 +1,198 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* This file contains character tables that are used when no external tables
+are passed to PCRE by the application that calls it. The tables are used only
+for characters whose code values are less than 256.
+
+This is a default version of the tables that assumes ASCII encoding. A program
+called dftables (which is distributed with PCRE) can be used to build
+alternative versions of this file. This is necessary if you are running in an
+EBCDIC environment, or if you want to default to a different encoding, for
+example ISO-8859-1. When dftables is run, it creates these tables in the
+current locale. If PCRE is configured with --enable-rebuild-chartables, this
+happens automatically.
+
+The following #includes are present because without them gcc 4.x may remove the
+array definition from the final binary if PCRE is built into a static library
+and dead code stripping is activated. This leads to link errors. Pulling in the
+header ensures that the array gets flagged as "someone outside this compilation
+unit might reference this" and so it will always be supplied to the linker. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+const pcre_uint8 PRIV(default_tables)[] = {
+
+/* This table is a lower casing table. */
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,
+ 136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,
+ 152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,
+ 168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,
+ 184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,
+ 200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,
+ 232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,
+ 248,249,250,251,252,253,254,255,
+
+/* This table is a case flipping table. */
+
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,
+ 112,113,114,115,116,117,118,119,
+ 120,121,122, 91, 92, 93, 94, 95,
+ 96, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90,123,124,125,126,127,
+ 128,129,130,131,132,133,134,135,
+ 136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,
+ 152,153,154,155,156,157,158,159,
+ 160,161,162,163,164,165,166,167,
+ 168,169,170,171,172,173,174,175,
+ 176,177,178,179,180,181,182,183,
+ 184,185,186,187,188,189,190,191,
+ 192,193,194,195,196,197,198,199,
+ 200,201,202,203,204,205,206,207,
+ 208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,
+ 224,225,226,227,228,229,230,231,
+ 232,233,234,235,236,237,238,239,
+ 240,241,242,243,244,245,246,247,
+ 248,249,250,251,252,253,254,255,
+
+/* This table contains bit maps for various character classes. Each map is 32
+bytes long and the bits run from the least significant end of each byte. The
+classes that have their own maps are: space, xdigit, digit, upper, lower, word,
+graph, print, punct, and cntrl. Other classes are built from combinations. */
+
+ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+ 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
+ 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+/* This table identifies various classes of character by individual bits:
+ 0x01 white space character
+ 0x02 letter
+ 0x04 decimal digit
+ 0x08 hexadecimal digit
+ 0x10 alphanumeric or '_'
+ 0x80 regular expression metacharacter or binary zero
+*/
+
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
+ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
+ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
+ 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
+ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
+
+/* End of pcre_chartables.c */
diff --git a/src/3rdparty/pcre/pcre_compile.c b/src/3rdparty/pcre/pcre_compile.c
new file mode 100644
index 00000000000..b0c57ca1229
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_compile.c
@@ -0,0 +1,8162 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_compile(), along with
+supporting internal functions that are not used by other modules. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK cd /* Block containing newline information */
+#define PSSTART start_pattern /* Field containing processed string start */
+#define PSEND end_pattern /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+
+/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which
+is also used by pcretest. PCRE_DEBUG is not defined when building a production
+library. We do not need to select pcre16_printint.c specially, because the
+COMPILE_PCREx macro will already be appropriately set. */
+
+#ifdef PCRE_DEBUG
+/* pcre_printint.c should not include any headers */
+#define PCRE_INCLUDED
+#include "pcre_printint.c"
+#undef PCRE_INCLUDED
+#endif
+
+
+/* Macro for setting individual bits in class bitmaps. */
+
+#define SETBIT(a,b) a[b/8] |= (1 << (b%8))
+
+/* Maximum length value to check against when making sure that the integer that
+holds the compiled pattern length does not overflow. We make it a bit less than
+INT_MAX to allow for adding in group terminating bytes, so that we don't have
+to check them every time. */
+
+#define OFLOW_MAX (INT_MAX - 20)
+
+
+/*************************************************
+* Code parameters and static tables *
+*************************************************/
+
+/* This value specifies the size of stack workspace that is used during the
+first pre-compile phase that determines how much memory is required. The regex
+is partly compiled into this space, but the compiled parts are discarded as
+soon as they can be, so that hopefully there will never be an overrun. The code
+does, however, check for an overrun. The largest amount I've seen used is 218,
+so this number is very generous.
+
+The same workspace is used during the second, actual compile phase for
+remembering forward references to groups so that they can be filled in at the
+end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
+is 4 there is plenty of room for most patterns. However, the memory can get
+filled up by repetitions of forward references, for example patterns like
+/(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so
+that the workspace is expanded using malloc() in this situation. The value
+below is therefore a minimum, and we put a maximum on it for safety. The
+minimum is now also defined in terms of LINK_SIZE so that the use of malloc()
+kicks in at the same number of forward references in all cases. */
+
+#define COMPILE_WORK_SIZE (2048*LINK_SIZE)
+#define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)
+
+/* The overrun tests check for a slightly smaller size so that they detect the
+overrun before it actually does run off the end of the data block. */
+
+#define WORK_SIZE_SAFETY_MARGIN (100)
+
+/* Private flags added to firstchar and reqchar. */
+
+#define REQ_CASELESS 0x10000000l /* Indicates caselessness */
+#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */
+
+/* Repeated character flags. */
+
+#define UTF_LENGTH 0x10000000l /* The char contains its length. */
+
+/* Table for handling escaped characters in the range '0'-'z'. Positive returns
+are simple data values; negative values are for special things like \d and so
+on. Zero means further processing is needed (for things like \x), or the escape
+is invalid. */
+
+#ifndef EBCDIC
+
+/* This is the "normal" table for ASCII systems or for EBCDIC systems running
+in UTF-8 mode. */
+
+static const short int escapes[] = {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ CHAR_COLON, CHAR_SEMICOLON,
+ CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN,
+ CHAR_GREATER_THAN_SIGN, CHAR_QUESTION_MARK,
+ CHAR_COMMERCIAL_AT, -ESC_A,
+ -ESC_B, -ESC_C,
+ -ESC_D, -ESC_E,
+ 0, -ESC_G,
+ -ESC_H, 0,
+ 0, -ESC_K,
+ 0, 0,
+ -ESC_N, 0,
+ -ESC_P, -ESC_Q,
+ -ESC_R, -ESC_S,
+ 0, 0,
+ -ESC_V, -ESC_W,
+ -ESC_X, 0,
+ -ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
+ CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
+ CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
+ CHAR_GRAVE_ACCENT, 7,
+ -ESC_b, 0,
+ -ESC_d, ESC_e,
+ ESC_f, 0,
+ -ESC_h, 0,
+ 0, -ESC_k,
+ 0, 0,
+ ESC_n, 0,
+ -ESC_p, 0,
+ ESC_r, -ESC_s,
+ ESC_tee, 0,
+ -ESC_v, -ESC_w,
+ 0, 0,
+ -ESC_z
+};
+
+#else
+
+/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */
+
+static const short int escapes[] = {
+/* 48 */ 0, 0, 0, '.', '<', '(', '+', '|',
+/* 50 */ '&', 0, 0, 0, 0, 0, 0, 0,
+/* 58 */ 0, 0, '!', '$', '*', ')', ';', '~',
+/* 60 */ '-', '/', 0, 0, 0, 0, 0, 0,
+/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
+/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
+/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
+/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
+/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
+/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
+/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
+/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
+/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
+/* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G,
+/* C8 */-ESC_H, 0, 0, 0, 0, 0, 0, 0,
+/* D0 */ '}', 0, -ESC_K, 0, 0,-ESC_N, 0, -ESC_P,
+/* D8 */-ESC_Q,-ESC_R, 0, 0, 0, 0, 0, 0,
+/* E0 */ '\\', 0, -ESC_S, 0, 0,-ESC_V, -ESC_W, -ESC_X,
+/* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0,
+/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
+/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
+};
+#endif
+
+
+/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
+searched linearly. Put all the names into a single string, in order to reduce
+the number of relocations when a shared library is dynamically linked. The
+string is built from string macros so that it works in UTF-8 mode on EBCDIC
+platforms. */
+
+typedef struct verbitem {
+ int len; /* Length of verb name */
+ int op; /* Op when no arg, or -1 if arg mandatory */
+ int op_arg; /* Op when arg present, or -1 if not allowed */
+} verbitem;
+
+static const char verbnames[] =
+ "\0" /* Empty name is a shorthand for MARK */
+ STRING_MARK0
+ STRING_ACCEPT0
+ STRING_COMMIT0
+ STRING_F0
+ STRING_FAIL0
+ STRING_PRUNE0
+ STRING_SKIP0
+ STRING_THEN;
+
+static const verbitem verbs[] = {
+ { 0, -1, OP_MARK },
+ { 4, -1, OP_MARK },
+ { 6, OP_ACCEPT, -1 },
+ { 6, OP_COMMIT, -1 },
+ { 1, OP_FAIL, -1 },
+ { 4, OP_FAIL, -1 },
+ { 5, OP_PRUNE, OP_PRUNE_ARG },
+ { 4, OP_SKIP, OP_SKIP_ARG },
+ { 4, OP_THEN, OP_THEN_ARG }
+};
+
+static const int verbcount = sizeof(verbs)/sizeof(verbitem);
+
+
+/* Tables of names of POSIX character classes and their lengths. The names are
+now all in a single string, to reduce the number of relocations when a shared
+library is dynamically loaded. The list of lengths is terminated by a zero
+length entry. The first three must be alpha, lower, upper, as this is assumed
+for handling case independence. */
+
+static const char posix_names[] =
+ STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
+ STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
+ STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
+ STRING_word0 STRING_xdigit;
+
+static const pcre_uint8 posix_name_lengths[] = {
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
+
+/* Table of class bit maps for each POSIX class. Each class is formed from a
+base map, with an optional addition or removal of another map. Then, for some
+classes, there is some additional tweaking: for [:blank:] the vertical space
+characters are removed, and for [:alpha:] and [:alnum:] the underscore
+character is removed. The triples in the table consist of the base map offset,
+second map offset or -1 if no second map, and a non-negative value for map
+addition or a negative value for map subtraction (if there are two maps). The
+absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
+remove vertical space characters, 2 => remove underscore. */
+
+static const int posix_class_maps[] = {
+ cbit_word, cbit_digit, -2, /* alpha */
+ cbit_lower, -1, 0, /* lower */
+ cbit_upper, -1, 0, /* upper */
+ cbit_word, -1, 2, /* alnum - word without underscore */
+ cbit_print, cbit_cntrl, 0, /* ascii */
+ cbit_space, -1, 1, /* blank - a GNU extension */
+ cbit_cntrl, -1, 0, /* cntrl */
+ cbit_digit, -1, 0, /* digit */
+ cbit_graph, -1, 0, /* graph */
+ cbit_print, -1, 0, /* print */
+ cbit_punct, -1, 0, /* punct */
+ cbit_space, -1, 0, /* space */
+ cbit_word, -1, 0, /* word - a Perl extension */
+ cbit_xdigit,-1, 0 /* xdigit */
+};
+
+/* Table of substitutes for \d etc when PCRE_UCP is set. The POSIX class
+substitutes must be in the order of the names, defined above, and there are
+both positive and negative cases. NULL means no substitute. */
+
+#ifdef SUPPORT_UCP
+static const pcre_uchar string_PNd[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pNd[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_N, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXsp[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXsp[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_s, CHAR_p, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXwd[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXwd[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_w, CHAR_d, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+
+static const pcre_uchar *substitutes[] = {
+ string_PNd, /* \D */
+ string_pNd, /* \d */
+ string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
+ string_pXsp, /* \s */
+ string_PXwd, /* \W */
+ string_pXwd /* \w */
+};
+
+static const pcre_uchar string_pL[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pLl[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pLu[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_pXan[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_h[] = {
+ CHAR_BACKSLASH, CHAR_h, '\0' };
+static const pcre_uchar string_pXps[] = {
+ CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PL[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PLl[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_l, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PLu[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_L, CHAR_u, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_PXan[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_a, CHAR_n, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+static const pcre_uchar string_H[] = {
+ CHAR_BACKSLASH, CHAR_H, '\0' };
+static const pcre_uchar string_PXps[] = {
+ CHAR_BACKSLASH, CHAR_P, CHAR_LEFT_CURLY_BRACKET,
+ CHAR_X, CHAR_p, CHAR_s, CHAR_RIGHT_CURLY_BRACKET, '\0' };
+
+static const pcre_uchar *posix_substitutes[] = {
+ string_pL, /* alpha */
+ string_pLl, /* lower */
+ string_pLu, /* upper */
+ string_pXan, /* alnum */
+ NULL, /* ascii */
+ string_h, /* blank */
+ NULL, /* cntrl */
+ string_pNd, /* digit */
+ NULL, /* graph */
+ NULL, /* print */
+ NULL, /* punct */
+ string_pXps, /* space */ /* NOTE: Xps is POSIX space */
+ string_pXwd, /* word */
+ NULL, /* xdigit */
+ /* Negated cases */
+ string_PL, /* ^alpha */
+ string_PLl, /* ^lower */
+ string_PLu, /* ^upper */
+ string_PXan, /* ^alnum */
+ NULL, /* ^ascii */
+ string_H, /* ^blank */
+ NULL, /* ^cntrl */
+ string_PNd, /* ^digit */
+ NULL, /* ^graph */
+ NULL, /* ^print */
+ NULL, /* ^punct */
+ string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
+ string_PXwd, /* ^word */
+ NULL /* ^xdigit */
+};
+#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
+#endif
+
+#define STRING(a) # a
+#define XSTRING(s) STRING(s)
+
+/* The texts of compile-time error messages. These are "char *" because they
+are passed to the outside world. Do not ever re-use any error number, because
+they are documented. Always add a new error instead. Messages marked DEAD below
+are no longer used. This used to be a table of strings, but in order to reduce
+the number of relocations needed when a shared library is loaded dynamically,
+it is now one long string. We cannot use a table of offsets, because the
+lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we
+simply count through to the one we want - this isn't a performance issue
+because these strings are used only when there is a compilation error.
+
+Each substring ends with \0 to insert a null character. This includes the final
+substring, so that the whole string ends with \0\0, which can be detected when
+counting through. */
+
+static const char error_texts[] =
+ "no error\0"
+ "\\ at end of pattern\0"
+ "\\c at end of pattern\0"
+ "unrecognized character follows \\\0"
+ "numbers out of order in {} quantifier\0"
+ /* 5 */
+ "number too big in {} quantifier\0"
+ "missing terminating ] for character class\0"
+ "invalid escape sequence in character class\0"
+ "range out of order in character class\0"
+ "nothing to repeat\0"
+ /* 10 */
+ "operand of unlimited repeat could match the empty string\0" /** DEAD **/
+ "internal error: unexpected repeat\0"
+ "unrecognized character after (? or (?-\0"
+ "POSIX named classes are supported only within a class\0"
+ "missing )\0"
+ /* 15 */
+ "reference to non-existent subpattern\0"
+ "erroffset passed as NULL\0"
+ "unknown option bit(s) set\0"
+ "missing ) after comment\0"
+ "parentheses nested too deeply\0" /** DEAD **/
+ /* 20 */
+ "regular expression is too large\0"
+ "failed to get memory\0"
+ "unmatched parentheses\0"
+ "internal error: code overflow\0"
+ "unrecognized character after (?<\0"
+ /* 25 */
+ "lookbehind assertion is not fixed length\0"
+ "malformed number or name after (?(\0"
+ "conditional group contains more than two branches\0"
+ "assertion expected after (?(\0"
+ "(?R or (?[+-]digits must be followed by )\0"
+ /* 30 */
+ "unknown POSIX class name\0"
+ "POSIX collating elements are not supported\0"
+ "this version of PCRE is compiled without UTF support\0"
+ "spare error\0" /** DEAD **/
+ "character value in \\x{...} sequence is too large\0"
+ /* 35 */
+ "invalid condition (?(0)\0"
+ "\\C not allowed in lookbehind assertion\0"
+ "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0"
+ "number after (?C is > 255\0"
+ "closing ) for (?C expected\0"
+ /* 40 */
+ "recursive call could loop indefinitely\0"
+ "unrecognized character after (?P\0"
+ "syntax error in subpattern name (missing terminator)\0"
+ "two named subpatterns have the same name\0"
+ "invalid UTF-8 string\0"
+ /* 45 */
+ "support for \\P, \\p, and \\X has not been compiled\0"
+ "malformed \\P or \\p sequence\0"
+ "unknown property name after \\P or \\p\0"
+ "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
+ "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
+ /* 50 */
+ "repeated subpattern is too long\0" /** DEAD **/
+ "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0"
+ "internal error: overran compiling workspace\0"
+ "internal error: previously-checked referenced subpattern not found\0"
+ "DEFINE group contains more than one branch\0"
+ /* 55 */
+ "repeating a DEFINE group is not allowed\0" /** DEAD **/
+ "inconsistent NEWLINE options\0"
+ "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
+ "a numbered reference must not be zero\0"
+ "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
+ /* 60 */
+ "(*VERB) not recognized\0"
+ "number is too big\0"
+ "subpattern name expected\0"
+ "digit expected after (?+\0"
+ "] is an invalid data character in JavaScript compatibility mode\0"
+ /* 65 */
+ "different names for subpatterns of the same number are not allowed\0"
+ "(*MARK) must have an argument\0"
+ "this version of PCRE is not compiled with Unicode property support\0"
+ "\\c must be followed by an ASCII character\0"
+ "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
+ /* 70 */
+ "internal error: unknown opcode in find_fixedlength()\0"
+ "\\N is not supported in a class\0"
+ "too many forward references\0"
+ "disallowed Unicode code point (>= 0xd800 && <= 0xdfff)\0"
+ "invalid UTF-16 string\0"
+ ;
+
+/* Table to identify digits and hex digits. This is used when compiling
+patterns. Note that the tables in chartables are dependent on the locale, and
+may mark arbitrary characters as digits - but the PCRE compiling code expects
+to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have
+a private table here. It costs 256 bytes, but it is a lot faster than doing
+character value tests (at least in some simple cases I timed), and in some
+applications one wants PCRE to compile efficiently as well as match
+efficiently.
+
+For convenience, we use the same bit definitions as in chartables:
+
+ 0x04 decimal digit
+ 0x08 hexadecimal digit
+
+Then we can use ctype_digit and ctype_xdigit in the code. */
+
+/* Using a simple comparison for decimal numbers rather than a memory read
+is much faster, and the resulting code is simpler (the compiler turns it
+into a subtraction and unsigned comparison). */
+
+#define IS_DIGIT(x) ((x) >= CHAR_0 && (x) <= CHAR_9)
+
+#ifndef EBCDIC
+
+/* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
+UTF-8 mode. */
+
+static const pcre_uint8 digitab[] =
+ {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */
+ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
+
+#else
+
+/* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
+
+static const pcre_uint8 digitab[] =
+ {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- 95 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
+ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */
+ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
+
+static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
+ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */
+ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
+ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */
+ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */
+ 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */
+ 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- 95 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */
+ 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */
+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */
+ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */
+ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */
+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */
+ 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+ 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */
+ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */
+ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */
+ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */
+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */
+#endif
+
+
+/* Definition to allow mutual recursion */
+
+static BOOL
+ compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int,
+ int *, int *, branch_chain *, compile_data *, int *);
+
+
+
+/*************************************************
+* Find an error text *
+*************************************************/
+
+/* The error texts are now all in one long string, to save on relocations. As
+some of the text is of unknown length, we can't use a table of offsets.
+Instead, just count through the strings. This is not a performance issue
+because it happens only when there has been a compilation error.
+
+Argument: the error number
+Returns: pointer to the error string
+*/
+
+static const char *
+find_error_text(int n)
+{
+const char *s = error_texts;
+for (; n > 0; n--)
+ {
+ while (*s++ != 0) {};
+ if (*s == 0) return "Error text not found (please report)";
+ }
+return s;
+}
+
+
+/*************************************************
+* Expand the workspace *
+*************************************************/
+
+/* This function is called during the second compiling phase, if the number of
+forward references fills the existing workspace, which is originally a block on
+the stack. A larger block is obtained from malloc() unless the ultimate limit
+has been reached or the increase will be rather small.
+
+Argument: pointer to the compile data block
+Returns: 0 if all went well, else an error number
+*/
+
+static int
+expand_workspace(compile_data *cd)
+{
+pcre_uchar *newspace;
+int newsize = cd->workspace_size * 2;
+
+if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX;
+if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||
+ newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)
+ return ERR72;
+
+newspace = (PUBL(malloc))(IN_UCHARS(newsize));
+if (newspace == NULL) return ERR21;
+memcpy(newspace, cd->start_workspace, cd->workspace_size * sizeof(pcre_uchar));
+cd->hwm = (pcre_uchar *)newspace + (cd->hwm - cd->start_workspace);
+if (cd->workspace_size > COMPILE_WORK_SIZE)
+ (PUBL(free))((void *)cd->start_workspace);
+cd->start_workspace = newspace;
+cd->workspace_size = newsize;
+return 0;
+}
+
+
+
+/*************************************************
+* Check for counted repeat *
+*************************************************/
+
+/* This function is called when a '{' is encountered in a place where it might
+start a quantifier. It looks ahead to see if it really is a quantifier or not.
+It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
+where the ddds are digits.
+
+Arguments:
+ p pointer to the first char after '{'
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_counted_repeat(const pcre_uchar *p)
+{
+if (!IS_DIGIT(*p)) return FALSE;
+p++;
+while (IS_DIGIT(*p)) p++;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (*p++ != CHAR_COMMA) return FALSE;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (!IS_DIGIT(*p)) return FALSE;
+p++;
+while (IS_DIGIT(*p)) p++;
+
+return (*p == CHAR_RIGHT_CURLY_BRACKET);
+}
+
+
+
+/*************************************************
+* Handle escapes *
+*************************************************/
+
+/* This function is called when a \ has been encountered. It either returns a
+positive value for a simple escape such as \n, or a negative value which
+encodes one of the more complicated things such as \d. A backreference to group
+n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When
+UTF-8 is enabled, a positive value greater than 255 may be returned. On entry,
+ptr is pointing at the \. On exit, it is on the final character of the escape
+sequence.
+
+Arguments:
+ ptrptr points to the pattern position pointer
+ errorcodeptr points to the errorcode variable
+ bracount number of previous extracting brackets
+ options the options bits
+ isclass TRUE if inside a character class
+
+Returns: zero or positive => a data character
+ negative => a special escape sequence
+ on error, errorcodeptr is set
+*/
+
+static int
+check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount,
+ int options, BOOL isclass)
+{
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+const pcre_uchar *ptr = *ptrptr + 1;
+pcre_int32 c;
+int i;
+
+GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */
+ptr--; /* Set pointer back to the last byte */
+
+/* If backslash is at the end of the pattern, it's an error. */
+
+if (c == 0) *errorcodeptr = ERR1;
+
+/* Non-alphanumerics are literals. For digits or letters, do an initial lookup
+in a table. A non-zero result is something that can be returned immediately.
+Otherwise further processing may be required. */
+
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+/* Not alphanumeric */
+else if (c < CHAR_0 || c > CHAR_z) {}
+else if ((i = escapes[c - CHAR_0]) != 0) c = i;
+
+#else /* EBCDIC coding */
+/* Not alphanumeric */
+else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {}
+else if ((i = escapes[c - 0x48]) != 0) c = i;
+#endif
+
+/* Escapes that need further processing, or are illegal. */
+
+else
+ {
+ const pcre_uchar *oldptr;
+ BOOL braced, negated;
+
+ switch (c)
+ {
+ /* A number of Perl escapes are not handled by PCRE. We give an explicit
+ error. */
+
+ case CHAR_l:
+ case CHAR_L:
+ *errorcodeptr = ERR37;
+ break;
+
+ case CHAR_u:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ /* In JavaScript, \u must be followed by four hexadecimal numbers.
+ Otherwise it is a lowercase u letter. */
+ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
+ && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0
+ && MAX_255(ptr[3]) && (digitab[ptr[3]] & ctype_xdigit) != 0
+ && MAX_255(ptr[4]) && (digitab[ptr[4]] & ctype_xdigit) != 0)
+ {
+ c = 0;
+ for (i = 0; i < 4; ++i)
+ {
+ register int cc = *(++ptr);
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ }
+ }
+ else
+ *errorcodeptr = ERR37;
+ break;
+
+ case CHAR_U:
+ /* In JavaScript, \U is an uppercase U letter. */
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0) *errorcodeptr = ERR37;
+ break;
+
+ /* In a character class, \g is just a literal "g". Outside a character
+ class, \g must be followed by one of a number of specific things:
+
+ (1) A number, either plain or braced. If positive, it is an absolute
+ backreference. If negative, it is a relative backreference. This is a Perl
+ 5.10 feature.
+
+ (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
+ is part of Perl's movement towards a unified syntax for back references. As
+ this is synonymous with \k{name}, we fudge it up by pretending it really
+ was \k.
+
+ (3) For Oniguruma compatibility we also support \g followed by a name or a
+ number either in angle brackets or in single quotes. However, these are
+ (possibly recursive) subroutine calls, _not_ backreferences. Just return
+ the -ESC_g code (cf \k). */
+
+ case CHAR_g:
+ if (isclass) break;
+ if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
+ {
+ c = -ESC_g;
+ break;
+ }
+
+ /* Handle the Perl-compatible cases */
+
+ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+ {
+ const pcre_uchar *p;
+ for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
+ if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break;
+ if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ c = -ESC_k;
+ break;
+ }
+ braced = TRUE;
+ ptr++;
+ }
+ else braced = FALSE;
+
+ if (ptr[1] == CHAR_MINUS)
+ {
+ negated = TRUE;
+ ptr++;
+ }
+ else negated = FALSE;
+
+ /* The integer range is limited by the machine's int representation. */
+ c = 0;
+ while (IS_DIGIT(ptr[1]))
+ {
+ if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
+ {
+ c = -1;
+ break;
+ }
+ c = c * 10 + *(++ptr) - CHAR_0;
+ }
+ if (((unsigned int)c) > INT_MAX) /* Integer overflow */
+ {
+ while (IS_DIGIT(ptr[1]))
+ ptr++;
+ *errorcodeptr = ERR61;
+ break;
+ }
+
+ if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+
+ if (c == 0)
+ {
+ *errorcodeptr = ERR58;
+ break;
+ }
+
+ if (negated)
+ {
+ if (c > bracount)
+ {
+ *errorcodeptr = ERR15;
+ break;
+ }
+ c = bracount - (c - 1);
+ }
+
+ c = -(ESC_REF + c);
+ break;
+
+ /* The handling of escape sequences consisting of a string of digits
+ starting with one that is not zero is not straightforward. By experiment,
+ the way Perl works seems to be as follows:
+
+ Outside a character class, the digits are read as a decimal number. If the
+ number is less than 10, or if there are that many previous extracting
+ left brackets, then it is a back reference. Otherwise, up to three octal
+ digits are read to form an escaped byte. Thus \123 is likely to be octal
+ 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
+ value is greater than 377, the least significant 8 bits are taken. Inside a
+ character class, \ followed by a digit is always an octal number. */
+
+ case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
+ case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+
+ if (!isclass)
+ {
+ oldptr = ptr;
+ /* The integer range is limited by the machine's int representation. */
+ c -= CHAR_0;
+ while (IS_DIGIT(ptr[1]))
+ {
+ if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */
+ {
+ c = -1;
+ break;
+ }
+ c = c * 10 + *(++ptr) - CHAR_0;
+ }
+ if (((unsigned int)c) > INT_MAX) /* Integer overflow */
+ {
+ while (IS_DIGIT(ptr[1]))
+ ptr++;
+ *errorcodeptr = ERR61;
+ break;
+ }
+ if (c < 10 || c <= bracount)
+ {
+ c = -(ESC_REF + c);
+ break;
+ }
+ ptr = oldptr; /* Put the pointer back and fall through */
+ }
+
+ /* Handle an octal number following \. If the first digit is 8 or 9, Perl
+ generates a binary zero byte and treats the digit as a following literal.
+ Thus we have to pull back the pointer by one. */
+
+ if ((c = *ptr) >= CHAR_8)
+ {
+ ptr--;
+ c = 0;
+ break;
+ }
+
+ /* \0 always starts an octal number, but we may drop through to here with a
+ larger first octal digit. The original code used just to take the least
+ significant 8 bits of octal numbers (I think this is what early Perls used
+ to do). Nowadays we allow for larger numbers in UTF-8 mode and 16-bit mode,
+ but no more than 3 octal digits. */
+
+ case CHAR_0:
+ c -= CHAR_0;
+ while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
+ c = c * 8 + *(++ptr) - CHAR_0;
+#ifdef COMPILE_PCRE8
+ if (!utf && c > 0xff) *errorcodeptr = ERR51;
+#endif
+ break;
+
+ /* \x is complicated. \x{ddd} is a character number which can be greater
+ than 0xff in utf or non-8bit mode, but only if the ddd are hex digits.
+ If not, { is treated as a data character. */
+
+ case CHAR_x:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ /* In JavaScript, \x must be followed by two hexadecimal numbers.
+ Otherwise it is a lowercase x letter. */
+ if (MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0
+ && MAX_255(ptr[2]) && (digitab[ptr[2]] & ctype_xdigit) != 0)
+ {
+ c = 0;
+ for (i = 0; i < 2; ++i)
+ {
+ register int cc = *(++ptr);
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ }
+ break;
+ }
+
+ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+ {
+ const pcre_uchar *pt = ptr + 2;
+
+ c = 0;
+ while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
+ {
+ register int cc = *pt++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc >= CHAR_a && cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+
+#ifdef COMPILE_PCRE8
+ if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; }
+#else
+#ifdef COMPILE_PCRE16
+ if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; }
+#endif
+#endif
+ }
+
+ if (c < 0)
+ {
+ while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
+ *errorcodeptr = ERR34;
+ }
+
+ if (*pt == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ ptr = pt;
+ break;
+ }
+
+ /* If the sequence of hex digits does not end with '}', then we don't
+ recognize this construct; fall through to the normal \x handling. */
+ }
+
+ /* Read just a single-byte hex-defined char */
+
+ c = 0;
+ while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
+ {
+ int cc; /* Some compilers don't like */
+ cc = *(++ptr); /* ++ in initializers */
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */
+ c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else /* EBCDIC coding */
+ if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+ }
+ break;
+
+ /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
+ An error is given if the byte following \c is not an ASCII character. This
+ coding is ASCII-specific, but then the whole concept of \cx is
+ ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
+
+ case CHAR_c:
+ c = *(++ptr);
+ if (c == 0)
+ {
+ *errorcodeptr = ERR2;
+ break;
+ }
+#ifndef EBCDIC /* ASCII/UTF-8 coding */
+ if (c > 127) /* Excludes all non-ASCII in either mode */
+ {
+ *errorcodeptr = ERR68;
+ break;
+ }
+ if (c >= CHAR_a && c <= CHAR_z) c -= 32;
+ c ^= 0x40;
+#else /* EBCDIC coding */
+ if (c >= CHAR_a && c <= CHAR_z) c += 64;
+ c ^= 0xC0;
+#endif
+ break;
+
+ /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
+ other alphanumeric following \ is an error if PCRE_EXTRA was set;
+ otherwise, for Perl compatibility, it is a literal. This code looks a bit
+ odd, but there used to be some cases other than the default, and there may
+ be again in future, so I haven't "optimized" it. */
+
+ default:
+ if ((options & PCRE_EXTRA) != 0) switch(c)
+ {
+ default:
+ *errorcodeptr = ERR3;
+ break;
+ }
+ break;
+ }
+ }
+
+/* Perl supports \N{name} for character names, as well as plain \N for "not
+newline". PCRE does not support \N{name}. However, it does support
+quantification such as \N{2,3}. */
+
+if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET &&
+ !is_counted_repeat(ptr+2))
+ *errorcodeptr = ERR37;
+
+/* If PCRE_UCP is set, we change the values for \d etc. */
+
+if ((options & PCRE_UCP) != 0 && c <= -ESC_D && c >= -ESC_w)
+ c -= (ESC_DU - ESC_D);
+
+/* Set the pointer to the final character before returning. */
+
+*ptrptr = ptr;
+return c;
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+* Handle \P and \p *
+*************************************************/
+
+/* This function is called after \P or \p has been encountered, provided that
+PCRE is compiled with support for Unicode properties. On entry, ptrptr is
+pointing at the P or p. On exit, it is pointing at the final character of the
+escape sequence.
+
+Argument:
+ ptrptr points to the pattern position pointer
+ negptr points to a boolean that is set TRUE for negation else FALSE
+ dptr points to an int that is set to the detailed property value
+ errorcodeptr points to the error code variable
+
+Returns: type value from ucp_type_table, or -1 for an invalid type
+*/
+
+static int
+get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
+{
+int c, i, bot, top;
+const pcre_uchar *ptr = *ptrptr;
+pcre_uchar name[32];
+
+c = *(++ptr);
+if (c == 0) goto ERROR_RETURN;
+
+*negptr = FALSE;
+
+/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
+negation. */
+
+if (c == CHAR_LEFT_CURLY_BRACKET)
+ {
+ if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ *negptr = TRUE;
+ ptr++;
+ }
+ for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++)
+ {
+ c = *(++ptr);
+ if (c == 0) goto ERROR_RETURN;
+ if (c == CHAR_RIGHT_CURLY_BRACKET) break;
+ name[i] = c;
+ }
+ if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
+ name[i] = 0;
+ }
+
+/* Otherwise there is just one following character */
+
+else
+ {
+ name[0] = c;
+ name[1] = 0;
+ }
+
+*ptrptr = ptr;
+
+/* Search for a recognized property name using binary chop */
+
+bot = 0;
+top = PRIV(utt_size);
+
+while (bot < top)
+ {
+ i = (bot + top) >> 1;
+ c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset);
+ if (c == 0)
+ {
+ *dptr = PRIV(utt)[i].value;
+ return PRIV(utt)[i].type;
+ }
+ if (c > 0) bot = i + 1; else top = i;
+ }
+
+*errorcodeptr = ERR47;
+*ptrptr = ptr;
+return -1;
+
+ERROR_RETURN:
+*errorcodeptr = ERR46;
+*ptrptr = ptr;
+return -1;
+}
+#endif
+
+
+
+
+/*************************************************
+* Read repeat counts *
+*************************************************/
+
+/* Read an item of the form {n,m} and return the values. This is called only
+after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
+so the syntax is guaranteed to be correct, but we need to check the values.
+
+Arguments:
+ p pointer to first char after '{'
+ minp pointer to int for min
+ maxp pointer to int for max
+ returned as -1 if no max
+ errorcodeptr points to error code variable
+
+Returns: pointer to '}' on success;
+ current ptr on error, with errorcodeptr set non-zero
+*/
+
+static const pcre_uchar *
+read_repeat_counts(const pcre_uchar *p, int *minp, int *maxp, int *errorcodeptr)
+{
+int min = 0;
+int max = -1;
+
+/* Read the minimum value and do a paranoid check: a negative value indicates
+an integer overflow. */
+
+while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0;
+if (min < 0 || min > 65535)
+ {
+ *errorcodeptr = ERR5;
+ return p;
+ }
+
+/* Read the maximum value if there is one, and again do a paranoid on its size.
+Also, max must not be less than min. */
+
+if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
+ {
+ if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
+ {
+ max = 0;
+ while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0;
+ if (max < 0 || max > 65535)
+ {
+ *errorcodeptr = ERR5;
+ return p;
+ }
+ if (max < min)
+ {
+ *errorcodeptr = ERR4;
+ return p;
+ }
+ }
+ }
+
+/* Fill in the required variables, and pass back the pointer to the terminating
+'}'. */
+
+*minp = min;
+*maxp = max;
+return p;
+}
+
+
+
+/*************************************************
+* Subroutine for finding forward reference *
+*************************************************/
+
+/* This recursive function is called only from find_parens() below. The
+top-level call starts at the beginning of the pattern. All other calls must
+start at a parenthesis. It scans along a pattern's text looking for capturing
+subpatterns, and counting them. If it finds a named pattern that matches the
+name it is given, it returns its number. Alternatively, if the name is NULL, it
+returns when it reaches a given numbered subpattern. Recursion is used to keep
+track of subpatterns that reset the capturing group numbers - the (?| feature.
+
+This function was originally called only from the second pass, in which we know
+that if (?< or (?' or (?P< is encountered, the name will be correctly
+terminated because that is checked in the first pass. There is now one call to
+this function in the first pass, to check for a recursive back reference by
+name (so that we can make the whole group atomic). In this case, we need check
+only up to the current position in the pattern, and that is still OK because
+and previous occurrences will have been checked. To make this work, the test
+for "end of pattern" is a check against cd->end_pattern in the main loop,
+instead of looking for a binary zero. This means that the special first-pass
+call can adjust cd->end_pattern temporarily. (Checks for binary zero while
+processing items within the loop are OK, because afterwards the main loop will
+terminate.)
+
+Arguments:
+ ptrptr address of the current character pointer (updated)
+ cd compile background data
+ name name to seek, or NULL if seeking a numbered subpattern
+ lorn name length, or subpattern number if name is NULL
+ xmode TRUE if we are in /x mode
+ utf TRUE if we are in UTF-8 / UTF-16 mode
+ count pointer to the current capturing subpattern number (updated)
+
+Returns: the number of the named subpattern, or -1 if not found
+*/
+
+static int
+find_parens_sub(pcre_uchar **ptrptr, compile_data *cd, const pcre_uchar *name, int lorn,
+ BOOL xmode, BOOL utf, int *count)
+{
+pcre_uchar *ptr = *ptrptr;
+int start_count = *count;
+int hwm_count = start_count;
+BOOL dup_parens = FALSE;
+
+/* If the first character is a parenthesis, check on the type of group we are
+dealing with. The very first call may not start with a parenthesis. */
+
+if (ptr[0] == CHAR_LEFT_PARENTHESIS)
+ {
+ /* Handle specials such as (*SKIP) or (*UTF8) etc. */
+
+ if (ptr[1] == CHAR_ASTERISK) ptr += 2;
+
+ /* Handle a normal, unnamed capturing parenthesis. */
+
+ else if (ptr[1] != CHAR_QUESTION_MARK)
+ {
+ *count += 1;
+ if (name == NULL && *count == lorn) return *count;
+ ptr++;
+ }
+
+ /* All cases now have (? at the start. Remember when we are in a group
+ where the parenthesis numbers are duplicated. */
+
+ else if (ptr[2] == CHAR_VERTICAL_LINE)
+ {
+ ptr += 3;
+ dup_parens = TRUE;
+ }
+
+ /* Handle comments; all characters are allowed until a ket is reached. */
+
+ else if (ptr[2] == CHAR_NUMBER_SIGN)
+ {
+ for (ptr += 3; *ptr != 0; ptr++) if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
+ goto FAIL_EXIT;
+ }
+
+ /* Handle a condition. If it is an assertion, just carry on so that it
+ is processed as normal. If not, skip to the closing parenthesis of the
+ condition (there can't be any nested parens). */
+
+ else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
+ {
+ ptr += 2;
+ if (ptr[1] != CHAR_QUESTION_MARK)
+ {
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ if (*ptr != 0) ptr++;
+ }
+ }
+
+ /* Start with (? but not a condition. */
+
+ else
+ {
+ ptr += 2;
+ if (*ptr == CHAR_P) ptr++; /* Allow optional P */
+
+ /* We have to disambiguate (? for named groups */
+
+ if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
+ ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
+ {
+ int term;
+ const pcre_uchar *thisname;
+ *count += 1;
+ if (name == NULL && *count == lorn) return *count;
+ term = *ptr++;
+ if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
+ thisname = ptr;
+ while (*ptr != term) ptr++;
+ if (name != NULL && lorn == ptr - thisname &&
+ STRNCMP_UC_UC(name, thisname, lorn) == 0)
+ return *count;
+ term++;
+ }
+ }
+ }
+
+/* Past any initial parenthesis handling, scan for parentheses or vertical
+bars. Stop if we get to cd->end_pattern. Note that this is important for the
+first-pass call when this value is temporarily adjusted to stop at the current
+position. So DO NOT change this to a test for binary zero. */
+
+for (; ptr < cd->end_pattern; ptr++)
+ {
+ /* Skip over backslashed characters and also entire \Q...\E */
+
+ if (*ptr == CHAR_BACKSLASH)
+ {
+ if (*(++ptr) == 0) goto FAIL_EXIT;
+ if (*ptr == CHAR_Q) for (;;)
+ {
+ while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
+ if (*ptr == 0) goto FAIL_EXIT;
+ if (*(++ptr) == CHAR_E) break;
+ }
+ continue;
+ }
+
+ /* Skip over character classes; this logic must be similar to the way they
+ are handled for real. If the first character is '^', skip it. Also, if the
+ first few characters (either before or after ^) are \Q\E or \E we skip them
+ too. This makes for compatibility with Perl. Note the use of STR macros to
+ encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
+
+ if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
+ {
+ BOOL negate_class = FALSE;
+ for (;;)
+ {
+ if (ptr[1] == CHAR_BACKSLASH)
+ {
+ if (ptr[2] == CHAR_E)
+ ptr+= 2;
+ else if (STRNCMP_UC_C8(ptr + 2,
+ STR_Q STR_BACKSLASH STR_E, 3) == 0)
+ ptr += 4;
+ else
+ break;
+ }
+ else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ negate_class = TRUE;
+ ptr++;
+ }
+ else break;
+ }
+
+ /* If the next character is ']', it is a data character that must be
+ skipped, except in JavaScript compatibility mode. */
+
+ if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
+ (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
+ ptr++;
+
+ while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET)
+ {
+ if (*ptr == 0) return -1;
+ if (*ptr == CHAR_BACKSLASH)
+ {
+ if (*(++ptr) == 0) goto FAIL_EXIT;
+ if (*ptr == CHAR_Q) for (;;)
+ {
+ while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
+ if (*ptr == 0) goto FAIL_EXIT;
+ if (*(++ptr) == CHAR_E) break;
+ }
+ continue;
+ }
+ }
+ continue;
+ }
+
+ /* Skip comments in /x mode */
+
+ if (xmode && *ptr == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ if (*ptr == 0) goto FAIL_EXIT;
+ continue;
+ }
+
+ /* Check for the special metacharacters */
+
+ if (*ptr == CHAR_LEFT_PARENTHESIS)
+ {
+ int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count);
+ if (rc > 0) return rc;
+ if (*ptr == 0) goto FAIL_EXIT;
+ }
+
+ else if (*ptr == CHAR_RIGHT_PARENTHESIS)
+ {
+ if (dup_parens && *count < hwm_count) *count = hwm_count;
+ goto FAIL_EXIT;
+ }
+
+ else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
+ {
+ if (*count > hwm_count) hwm_count = *count;
+ *count = start_count;
+ }
+ }
+
+FAIL_EXIT:
+*ptrptr = ptr;
+return -1;
+}
+
+
+
+
+/*************************************************
+* Find forward referenced subpattern *
+*************************************************/
+
+/* This function scans along a pattern's text looking for capturing
+subpatterns, and counting them. If it finds a named pattern that matches the
+name it is given, it returns its number. Alternatively, if the name is NULL, it
+returns when it reaches a given numbered subpattern. This is used for forward
+references to subpatterns. We used to be able to start this scan from the
+current compiling point, using the current count value from cd->bracount, and
+do it all in a single loop, but the addition of the possibility of duplicate
+subpattern numbers means that we have to scan from the very start, in order to
+take account of such duplicates, and to use a recursive function to keep track
+of the different types of group.
+
+Arguments:
+ cd compile background data
+ name name to seek, or NULL if seeking a numbered subpattern
+ lorn name length, or subpattern number if name is NULL
+ xmode TRUE if we are in /x mode
+ utf TRUE if we are in UTF-8 / UTF-16 mode
+
+Returns: the number of the found subpattern, or -1 if not found
+*/
+
+static int
+find_parens(compile_data *cd, const pcre_uchar *name, int lorn, BOOL xmode,
+ BOOL utf)
+{
+pcre_uchar *ptr = (pcre_uchar *)cd->start_pattern;
+int count = 0;
+int rc;
+
+/* If the pattern does not start with an opening parenthesis, the first call
+to find_parens_sub() will scan right to the end (if necessary). However, if it
+does start with a parenthesis, find_parens_sub() will return when it hits the
+matching closing parens. That is why we have to have a loop. */
+
+for (;;)
+ {
+ rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count);
+ if (rc > 0 || *ptr++ == 0) break;
+ }
+
+return rc;
+}
+
+
+
+
+/*************************************************
+* Find first significant op code *
+*************************************************/
+
+/* This is called by several functions that scan a compiled expression looking
+for a fixed first character, or an anchoring op code etc. It skips over things
+that do not influence this. For some calls, it makes sense to skip negative
+forward and all backward assertions, and also the \b assertion; for others it
+does not.
+
+Arguments:
+ code pointer to the start of the group
+ skipassert TRUE if certain assertions are to be skipped
+
+Returns: pointer to the first significant opcode
+*/
+
+static const pcre_uchar*
+first_significant_code(const pcre_uchar *code, BOOL skipassert)
+{
+for (;;)
+ {
+ switch ((int)*code)
+ {
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ if (!skipassert) return code;
+ do code += GET(code, 1); while (*code == OP_ALT);
+ code += PRIV(OP_lengths)[*code];
+ break;
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ if (!skipassert) return code;
+ /* Fall through */
+
+ case OP_CALLOUT:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_DEF:
+ code += PRIV(OP_lengths)[*code];
+ break;
+
+ default:
+ return code;
+ }
+ }
+/* Control never reaches here */
+}
+
+
+
+
+/*************************************************
+* Find the fixed length of a branch *
+*************************************************/
+
+/* Scan a branch and compute the fixed length of subject that will match it,
+if the length is fixed. This is needed for dealing with backward assertions.
+In UTF8 mode, the result is in characters rather than bytes. The branch is
+temporarily terminated with OP_END when this function is called.
+
+This function is called when a backward assertion is encountered, so that if it
+fails, the error message can point to the correct place in the pattern.
+However, we cannot do this when the assertion contains subroutine calls,
+because they can be forward references. We solve this by remembering this case
+and doing the check at the end; a flag specifies which mode we are running in.
+
+Arguments:
+ code points to the start of the pattern (the bracket)
+ utf TRUE in UTF-8 / UTF-16 mode
+ atend TRUE if called when the pattern is complete
+ cd the "compile data" structure
+
+Returns: the fixed length,
+ or -1 if there is no fixed length,
+ or -2 if \C was encountered (in UTF-8 mode only)
+ or -3 if an OP_RECURSE item was encountered and atend is FALSE
+ or -4 if an unknown opcode was encountered (internal error)
+*/
+
+static int
+find_fixedlength(pcre_uchar *code, BOOL utf, BOOL atend, compile_data *cd)
+{
+int length = -1;
+
+register int branchlength = 0;
+register pcre_uchar *cc = code + 1 + LINK_SIZE;
+
+/* Scan along the opcodes for this branch. If we get to the end of the
+branch, check the length against that of the other branches. */
+
+for (;;)
+ {
+ int d;
+ pcre_uchar *ce, *cs;
+ register int op = *cc;
+
+ switch (op)
+ {
+ /* We only need to continue for OP_CBRA (normal capturing bracket) and
+ OP_BRA (normal non-capturing bracket) because the other variants of these
+ opcodes are all concerned with unlimited repeated groups, which of course
+ are not of fixed length. */
+
+ case OP_CBRA:
+ case OP_BRA:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_COND:
+ d = find_fixedlength(cc + ((op == OP_CBRA)? IMM2_SIZE : 0), utf, atend, cd);
+ if (d < 0) return d;
+ branchlength += d;
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Reached end of a branch; if it's a ket it is the end of a nested call.
+ If it's ALT it is an alternation in a nested call. An ACCEPT is effectively
+ an ALT. If it is END it's the end of the outer call. All can be handled by
+ the same code. Note that we must not include the OP_KETRxxx opcodes here,
+ because they all imply an unlimited repeat. */
+
+ case OP_ALT:
+ case OP_KET:
+ case OP_END:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ if (length < 0) length = branchlength;
+ else if (length != branchlength) return -1;
+ if (*cc != OP_ALT) return length;
+ cc += 1 + LINK_SIZE;
+ branchlength = 0;
+ break;
+
+ /* A true recursion implies not fixed length, but a subroutine call may
+ be OK. If the subroutine is a forward reference, we can't deal with
+ it until the end of the pattern, so return -3. */
+
+ case OP_RECURSE:
+ if (!atend) return -3;
+ cs = ce = (pcre_uchar *)cd->start_code + GET(cc, 1); /* Start subpattern */
+ do ce += GET(ce, 1); while (*ce == OP_ALT); /* End subpattern */
+ if (cc > cs && cc < ce) return -1; /* Recursion */
+ d = find_fixedlength(cs + IMM2_SIZE, utf, atend, cd);
+ if (d < 0) return d;
+ branchlength += d;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Skip over assertive subpatterns */
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ /* Skip over things that don't match chars */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += cc[1] + PRIV(OP_lengths)[*cc];
+ break;
+
+ case OP_CALLOUT:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_CREF:
+ case OP_DEF:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_FAIL:
+ case OP_NCREF:
+ case OP_NRREF:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_PRUNE:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
+ case OP_WORD_BOUNDARY:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ /* Handle literal characters */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ branchlength++;
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ /* Handle exact repetitions. The count is already in characters, but we
+ need to skip over a multibyte character in UTF8 mode. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEEXACT:
+ branchlength += GET2(cc,1);
+ if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+
+ /* Handle single-char matchers */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ cc += 2;
+ /* Fall through */
+
+ case OP_HSPACE:
+ case OP_VSPACE:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ branchlength++;
+ cc++;
+ break;
+
+ /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;
+ otherwise \C is coded as OP_ALLANY. */
+
+ case OP_ANYBYTE:
+ return -2;
+
+ /* Check a class for variable quantification */
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
+ /* Fall through */
+#endif
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ cc += PRIV(OP_lengths)[OP_CLASS];
+
+ switch (*cc)
+ {
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ return -1;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
+ branchlength += GET2(cc,1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ branchlength++;
+ }
+ break;
+
+ /* Anything else is variable length */
+
+ case OP_ANYNL:
+ case OP_BRAMINZERO:
+ case OP_BRAPOS:
+ case OP_BRAPOSZERO:
+ case OP_BRAZERO:
+ case OP_CBRAPOS:
+ case OP_EXTUNI:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_REF:
+ case OP_REFI:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ case OP_SCOND:
+ case OP_SKIPZERO:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSUPTO:
+ case OP_TYPEQUERY:
+ case OP_TYPESTAR:
+ case OP_TYPEUPTO:
+ case OP_UPTO:
+ case OP_UPTOI:
+ return -1;
+
+ /* Catch unrecognized opcodes so that when new ones are added they
+ are not forgotten, as has happened in the past. */
+
+ default:
+ return -4;
+ }
+ }
+/* Control never gets here */
+}
+
+
+
+
+/*************************************************
+* Scan compiled regex for specific bracket *
+*************************************************/
+
+/* This little function scans through a compiled pattern until it finds a
+capturing bracket with the given number, or, if the number is negative, an
+instance of OP_REVERSE for a lookbehind. The function is global in the C sense
+so that it can be called from pcre_study() when finding the minimum matching
+length.
+
+Arguments:
+ code points to start of expression
+ utf TRUE in UTF-8 / UTF-16 mode
+ number the required bracket number or negative to find a lookbehind
+
+Returns: pointer to the opcode for the bracket, or NULL if not found
+*/
+
+const pcre_uchar *
+PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number)
+{
+for (;;)
+ {
+ register int c = *code;
+
+ if (c == OP_END) return NULL;
+
+ /* XCLASS is used for classes that cannot be represented just by a bit
+ map. This includes negated single high-valued characters. The length in
+ the table is zero; the actual length is stored in the compiled code. */
+
+ if (c == OP_XCLASS) code += GET(code, 1);
+
+ /* Handle recursion */
+
+ else if (c == OP_REVERSE)
+ {
+ if (number < 0) return (pcre_uchar *)code;
+ code += PRIV(OP_lengths)[c];
+ }
+
+ /* Handle capturing bracket */
+
+ else if (c == OP_CBRA || c == OP_SCBRA ||
+ c == OP_CBRAPOS || c == OP_SCBRAPOS)
+ {
+ int n = GET2(code, 1+LINK_SIZE);
+ if (n == number) return (pcre_uchar *)code;
+ code += PRIV(OP_lengths)[c];
+ }
+
+ /* Otherwise, we can get the item's length from the table, except that for
+ repeated character types, we have to test for \p and \P, which have an extra
+ two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
+ must add in its length. */
+
+ else
+ {
+ switch(c)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ code += code[1];
+ break;
+
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 mode, opcodes that are followed by a character may be followed by
+ a multi-byte character. The length in the table is a minimum, so we have to
+ arrange to skip the extra bytes. */
+
+#ifdef SUPPORT_UTF
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif
+ }
+ }
+}
+
+
+
+/*************************************************
+* Scan compiled regex for recursion reference *
+*************************************************/
+
+/* This little function scans through a compiled pattern until it finds an
+instance of OP_RECURSE.
+
+Arguments:
+ code points to start of expression
+ utf TRUE in UTF-8 / UTF-16 mode
+
+Returns: pointer to the opcode for OP_RECURSE, or NULL if not found
+*/
+
+static const pcre_uchar *
+find_recurse(const pcre_uchar *code, BOOL utf)
+{
+for (;;)
+ {
+ register int c = *code;
+ if (c == OP_END) return NULL;
+ if (c == OP_RECURSE) return code;
+
+ /* XCLASS is used for classes that cannot be represented just by a bit
+ map. This includes negated single high-valued characters. The length in
+ the table is zero; the actual length is stored in the compiled code. */
+
+ if (c == OP_XCLASS) code += GET(code, 1);
+
+ /* Otherwise, we can get the item's length from the table, except that for
+ repeated character types, we have to test for \p and \P, which have an extra
+ two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we
+ must add in its length. */
+
+ else
+ {
+ switch(c)
+ {
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_TYPEPOSUPTO:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
+ break;
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ code += code[1];
+ break;
+
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+ }
+
+ /* Add in the fixed length from the table */
+
+ code += PRIV(OP_lengths)[c];
+
+ /* In UTF-8 mode, opcodes that are followed by a character may be followed
+ by a multi-byte character. The length in the table is a minimum, so we have
+ to arrange to skip the extra bytes. */
+
+#ifdef SUPPORT_UTF
+ if (utf) switch(c)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif
+ }
+ }
+}
+
+
+
+/*************************************************
+* Scan compiled branch for non-emptiness *
+*************************************************/
+
+/* This function scans through a branch of a compiled pattern to see whether it
+can match the empty string or not. It is called from could_be_empty()
+below and from compile_branch() when checking for an unlimited repeat of a
+group that can match nothing. Note that first_significant_code() skips over
+backward and negative forward assertions when its final argument is TRUE. If we
+hit an unclosed bracket, we return "empty" - this means we've struck an inner
+bracket whose current branch will already have been scanned.
+
+Arguments:
+ code points to start of search
+ endcode points to where to stop
+ utf TRUE if in UTF-8 / UTF-16 mode
+ cd contains pointers to tables etc.
+
+Returns: TRUE if what is matched could be empty
+*/
+
+static BOOL
+could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
+ BOOL utf, compile_data *cd)
+{
+register int c;
+for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
+ code < endcode;
+ code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
+ {
+ const pcre_uchar *ccode;
+
+ c = *code;
+
+ /* Skip over forward assertions; the other assertions are skipped by
+ first_significant_code() with a TRUE final argument. */
+
+ if (c == OP_ASSERT)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* For a recursion/subroutine call, if its end has been reached, which
+ implies a backward reference subroutine call, we can scan it. If it's a
+ forward reference subroutine call, we can't. To detect forward reference
+ we have to scan up the list that is kept in the workspace. This function is
+ called only when doing the real compile, not during the pre-compile that
+ measures the size of the compiled pattern. */
+
+ if (c == OP_RECURSE)
+ {
+ const pcre_uchar *scode;
+ BOOL empty_branch;
+
+ /* Test for forward reference */
+
+ for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
+ if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE;
+
+ /* Not a forward reference, test for completed backward reference */
+
+ empty_branch = FALSE;
+ scode = cd->start_code + GET(code, 1);
+ if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+
+ /* Completed backwards reference */
+
+ do
+ {
+ if (could_be_empty_branch(scode, endcode, utf, cd))
+ {
+ empty_branch = TRUE;
+ break;
+ }
+ scode += GET(scode, 1);
+ }
+ while (*scode == OP_ALT);
+
+ if (!empty_branch) return FALSE; /* All branches are non-empty */
+ continue;
+ }
+
+ /* Groups with zero repeats can of course be empty; skip them. */
+
+ if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO ||
+ c == OP_BRAPOSZERO)
+ {
+ code += PRIV(OP_lengths)[c];
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* A nested group that is already marked as "could be empty" can just be
+ skipped. */
+
+ if (c == OP_SBRA || c == OP_SBRAPOS ||
+ c == OP_SCBRA || c == OP_SCBRAPOS)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ continue;
+ }
+
+ /* For other groups, scan the branches. */
+
+ if (c == OP_BRA || c == OP_BRAPOS ||
+ c == OP_CBRA || c == OP_CBRAPOS ||
+ c == OP_ONCE || c == OP_ONCE_NC ||
+ c == OP_COND)
+ {
+ BOOL empty_branch;
+ if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
+
+ /* If a conditional group has only one branch, there is a second, implied,
+ empty branch, so just skip over the conditional, because it could be empty.
+ Otherwise, scan the individual branches of the group. */
+
+ if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
+ code += GET(code, 1);
+ else
+ {
+ empty_branch = FALSE;
+ do
+ {
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
+ empty_branch = TRUE;
+ code += GET(code, 1);
+ }
+ while (*code == OP_ALT);
+ if (!empty_branch) return FALSE; /* All branches are non-empty */
+ }
+
+ c = *code;
+ continue;
+ }
+
+ /* Handle the other opcodes */
+
+ switch (c)
+ {
+ /* Check for quantifiers after a class. XCLASS is used for classes that
+ cannot be represented just by a bit map. This includes negated single
+ high-valued characters. The length in PRIV(OP_lengths)[] is zero; the
+ actual length is stored in the compiled code, so we must update "code"
+ here. */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ ccode = code += GET(code, 1);
+ goto CHECK_CLASS_REPEAT;
+#endif
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ ccode = code + PRIV(OP_lengths)[OP_CLASS];
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ CHECK_CLASS_REPEAT:
+#endif
+
+ switch (*ccode)
+ {
+ case OP_CRSTAR: /* These could be empty; continue */
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ break;
+
+ default: /* Non-repeat => class must match */
+ case OP_CRPLUS: /* These repeats aren't empty */
+ case OP_CRMINPLUS:
+ return FALSE;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
+ break;
+ }
+ break;
+
+ /* Opcodes that must match a character */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ case OP_EXTUNI:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_EXACT:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ case OP_NOTEXACT:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEEXACT:
+ return FALSE;
+
+ /* These are going to continue, as they may be empty, but we have to
+ fudge the length for the \p and \P cases. */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+ break;
+
+ /* Same for these */
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ if (code[1 + IMM2_SIZE] == OP_PROP
+ || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2;
+ break;
+
+ /* End of branch */
+
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_ALT:
+ return TRUE;
+
+ /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
+ MINUPTO, and POSUPTO may be followed by a multibyte character */
+
+#ifdef SUPPORT_UTF
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
+ break;
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
+ break;
+#endif
+
+ /* MARK, and PRUNE/SKIP/THEN with an argument must skip over the argument
+ string. */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ code += code[1];
+ break;
+
+ case OP_THEN_ARG:
+ code += code[1];
+ break;
+
+ /* None of the remaining opcodes are required to match a character. */
+
+ default:
+ break;
+ }
+ }
+
+return TRUE;
+}
+
+
+
+/*************************************************
+* Scan compiled regex for non-emptiness *
+*************************************************/
+
+/* This function is called to check for left recursive calls. We want to check
+the current branch of the current pattern to see if it could match the empty
+string. If it could, we must look outwards for branches at other levels,
+stopping when we pass beyond the bracket which is the subject of the recursion.
+This function is called only during the real compile, not during the
+pre-compile.
+
+Arguments:
+ code points to start of the recursion
+ endcode points to where to stop (current RECURSE item)
+ bcptr points to the chain of current (unclosed) branch starts
+ utf TRUE if in UTF-8 / UTF-16 mode
+ cd pointers to tables etc
+
+Returns: TRUE if what is matched could be empty
+*/
+
+static BOOL
+could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
+ branch_chain *bcptr, BOOL utf, compile_data *cd)
+{
+while (bcptr != NULL && bcptr->current_branch >= code)
+ {
+ if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
+ return FALSE;
+ bcptr = bcptr->outer;
+ }
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for POSIX class syntax *
+*************************************************/
+
+/* This function is called when the sequence "[:" or "[." or "[=" is
+encountered in a character class. It checks whether this is followed by a
+sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
+reach an unescaped ']' without the special preceding character, return FALSE.
+
+Originally, this function only recognized a sequence of letters between the
+terminators, but it seems that Perl recognizes any sequence of characters,
+though of course unknown POSIX names are subsequently rejected. Perl gives an
+"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
+didn't consider this to be a POSIX class. Likewise for [:1234:].
+
+The problem in trying to be exactly like Perl is in the handling of escapes. We
+have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
+class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
+below handles the special case of \], but does not try to do any other escape
+processing. This makes it different from Perl for cases such as [:l\ower:]
+where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
+"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
+I think.
+
+A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
+It seems that the appearance of a nested POSIX class supersedes an apparent
+external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or
+a digit.
+
+In Perl, unescaped square brackets may also appear as part of class names. For
+example, [:a[:abc]b:] gives unknown POSIX class "[:abc]b:]". However, for
+[:a[:abc]b][b:] it gives unknown POSIX class "[:abc]b][b:]", which does not
+seem right at all. PCRE does not allow closing square brackets in POSIX class
+names.
+
+Arguments:
+ ptr pointer to the initial [
+ endptr where to return the end pointer
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr)
+{
+int terminator; /* Don't combine these lines; the Solaris cc */
+terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
+for (++ptr; *ptr != 0; ptr++)
+ {
+ if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+ ptr++;
+ else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
+ else
+ {
+ if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+ {
+ *endptr = ptr;
+ return TRUE;
+ }
+ if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, endptr))
+ return FALSE;
+ }
+ }
+return FALSE;
+}
+
+
+
+
+/*************************************************
+* Check POSIX class name *
+*************************************************/
+
+/* This function is called to check the name given in a POSIX-style class entry
+such as [:alnum:].
+
+Arguments:
+ ptr points to the first letter
+ len the length of the name
+
+Returns: a value representing the name, or -1 if unknown
+*/
+
+static int
+check_posix_name(const pcre_uchar *ptr, int len)
+{
+const char *pn = posix_names;
+register int yield = 0;
+while (posix_name_lengths[yield] != 0)
+ {
+ if (len == posix_name_lengths[yield] &&
+ STRNCMP_UC_C8(ptr, pn, len) == 0) return yield;
+ pn += posix_name_lengths[yield] + 1;
+ yield++;
+ }
+return -1;
+}
+
+
+/*************************************************
+* Adjust OP_RECURSE items in repeated group *
+*************************************************/
+
+/* OP_RECURSE items contain an offset from the start of the regex to the group
+that is referenced. This means that groups can be replicated for fixed
+repetition simply by copying (because the recursion is allowed to refer to
+earlier groups that are outside the current group). However, when a group is
+optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
+inserted before it, after it has been compiled. This means that any OP_RECURSE
+items within it that refer to the group itself or any contained groups have to
+have their offsets adjusted. That one of the jobs of this function. Before it
+is called, the partially compiled regex must be temporarily terminated with
+OP_END.
+
+This function has been extended with the possibility of forward references for
+recursions and subroutine calls. It must also check the list of such references
+for the group we are dealing with. If it finds that one of the recursions in
+the current group is on this list, it adjusts the offset in the list, not the
+value in the reference (which is a group number).
+
+Arguments:
+ group points to the start of the group
+ adjust the amount by which the group is to be moved
+ utf TRUE in UTF-8 / UTF-16 mode
+ cd contains pointers to tables etc.
+ save_hwm the hwm forward reference pointer at the start of the group
+
+Returns: nothing
+*/
+
+static void
+adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
+ pcre_uchar *save_hwm)
+{
+pcre_uchar *ptr = group;
+
+while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
+ {
+ int offset;
+ pcre_uchar *hc;
+
+ /* See if this recursion is on the forward reference list. If so, adjust the
+ reference. */
+
+ for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
+ {
+ offset = GET(hc, 0);
+ if (cd->start_code + offset == ptr + 1)
+ {
+ PUT(hc, 0, offset + adjust);
+ break;
+ }
+ }
+
+ /* Otherwise, adjust the recursion offset if it's after the start of this
+ group. */
+
+ if (hc >= cd->hwm)
+ {
+ offset = GET(ptr, 1);
+ if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
+ }
+
+ ptr += 1 + LINK_SIZE;
+ }
+}
+
+
+
+/*************************************************
+* Insert an automatic callout point *
+*************************************************/
+
+/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert
+callout points before each pattern item.
+
+Arguments:
+ code current code pointer
+ ptr current pattern pointer
+ cd pointers to tables etc
+
+Returns: new code pointer
+*/
+
+static pcre_uchar *
+auto_callout(pcre_uchar *code, const pcre_uchar *ptr, compile_data *cd)
+{
+*code++ = OP_CALLOUT;
+*code++ = 255;
+PUT(code, 0, (int)(ptr - cd->start_pattern)); /* Pattern offset */
+PUT(code, LINK_SIZE, 0); /* Default length */
+return code + 2 * LINK_SIZE;
+}
+
+
+
+/*************************************************
+* Complete a callout item *
+*************************************************/
+
+/* A callout item contains the length of the next item in the pattern, which
+we can't fill in till after we have reached the relevant point. This is used
+for both automatic and manual callouts.
+
+Arguments:
+ previous_callout points to previous callout item
+ ptr current pattern pointer
+ cd pointers to tables etc
+
+Returns: nothing
+*/
+
+static void
+complete_callout(pcre_uchar *previous_callout, const pcre_uchar *ptr, compile_data *cd)
+{
+int length = (int)(ptr - cd->start_pattern - GET(previous_callout, 2));
+PUT(previous_callout, 2 + LINK_SIZE, length);
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+* Get othercase range *
+*************************************************/
+
+/* This function is passed the start and end of a class range, in UTF-8 mode
+with UCP support. It searches up the characters, looking for internal ranges of
+characters in the "other" case. Each call returns the next one, updating the
+start address.
+
+Arguments:
+ cptr points to starting character value; updated
+ d end value
+ ocptr where to put start of othercase range
+ odptr where to put end of othercase range
+
+Yield: TRUE when range returned; FALSE when no more
+*/
+
+static BOOL
+get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr,
+ unsigned int *odptr)
+{
+unsigned int c, othercase, next;
+
+for (c = *cptr; c <= d; c++)
+ { if ((othercase = UCD_OTHERCASE(c)) != c) break; }
+
+if (c > d) return FALSE;
+
+*ocptr = othercase;
+next = othercase + 1;
+
+for (++c; c <= d; c++)
+ {
+ if (UCD_OTHERCASE(c) != next) break;
+ next++;
+ }
+
+*odptr = next - 1;
+*cptr = c;
+
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check a character and a property *
+*************************************************/
+
+/* This function is called by check_auto_possessive() when a property item
+is adjacent to a fixed character.
+
+Arguments:
+ c the character
+ ptype the property type
+ pdata the data for the type
+ negated TRUE if it's a negated property (\P or \p{^)
+
+Returns: TRUE if auto-possessifying is OK
+*/
+
+static BOOL
+check_char_prop(int c, int ptype, int pdata, BOOL negated)
+{
+const ucd_record *prop = GET_UCD(c);
+switch(ptype)
+ {
+ case PT_LAMP:
+ return (prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == negated;
+
+ case PT_GC:
+ return (pdata == PRIV(ucp_gentype)[prop->chartype]) == negated;
+
+ case PT_PC:
+ return (pdata == prop->chartype) == negated;
+
+ case PT_SC:
+ return (pdata == prop->script) == negated;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == negated;
+
+ case PT_SPACE: /* Perl space */
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
+ == negated;
+
+ case PT_PXSPACE: /* POSIX space */
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR)
+ == negated;
+
+ case PT_WORD:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == negated;
+ }
+return FALSE;
+}
+#endif /* SUPPORT_UCP */
+
+
+
+/*************************************************
+* Check if auto-possessifying is possible *
+*************************************************/
+
+/* This function is called for unlimited repeats of certain items, to see
+whether the next thing could possibly match the repeated item. If not, it makes
+sense to automatically possessify the repeated item.
+
+Arguments:
+ previous pointer to the repeated opcode
+ utf TRUE in UTF-8 / UTF-16 mode
+ ptr next character in pattern
+ options options bits
+ cd contains pointers to tables etc.
+
+Returns: TRUE if possessifying is wanted
+*/
+
+static BOOL
+check_auto_possessive(const pcre_uchar *previous, BOOL utf,
+ const pcre_uchar *ptr, int options, compile_data *cd)
+{
+pcre_int32 c, next;
+int op_code = *previous++;
+
+/* Skip whitespace and comments in extended mode */
+
+if ((options & PCRE_EXTENDED) != 0)
+ {
+ for (;;)
+ {
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+ if (*ptr == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ }
+ else break;
+ }
+ }
+
+/* If the next item is one that we can handle, get its value. A non-negative
+value is a character, a negative value is an escape value. */
+
+if (*ptr == CHAR_BACKSLASH)
+ {
+ int temperrorcode = 0;
+ next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE);
+ if (temperrorcode != 0) return FALSE;
+ ptr++; /* Point after the escape sequence */
+ }
+else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0)
+ {
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARINC(next, ptr); } else
+#endif
+ next = *ptr++;
+ }
+else return FALSE;
+
+/* Skip whitespace and comments in extended mode */
+
+if ((options & PCRE_EXTENDED) != 0)
+ {
+ for (;;)
+ {
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+ if (*ptr == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ }
+ else break;
+ }
+ }
+
+/* If the next thing is itself optional, we have to give up. */
+
+if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
+ STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+ return FALSE;
+
+/* Now compare the next item with the previous opcode. First, handle cases when
+the next item is a character. */
+
+if (next >= 0) switch(op_code)
+ {
+ case OP_CHAR:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ return c != next;
+
+ /* For CHARI (caseless character) we must check the other case. If we have
+ Unicode property support, we can use it to test the other case of
+ high-valued characters. */
+
+ case OP_CHARI:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ if (c == next) return FALSE;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ unsigned int othercase;
+ if (next < 128) othercase = cd->fcc[next]; else
+#ifdef SUPPORT_UCP
+ othercase = UCD_OTHERCASE((unsigned int)next);
+#else
+ othercase = NOTACHAR;
+#endif
+ return (unsigned int)c != othercase;
+ }
+ else
+#endif /* SUPPORT_UTF */
+ return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */
+
+ /* For OP_NOT and OP_NOTI, the data is always a single-byte character. These
+ opcodes are not used for multi-byte characters, because they are coded using
+ an XCLASS instead. */
+
+ case OP_NOT:
+ return (c = *previous) == next;
+
+ case OP_NOTI:
+ if ((c = *previous) == next) return TRUE;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ unsigned int othercase;
+ if (next < 128) othercase = cd->fcc[next]; else
+#ifdef SUPPORT_UCP
+ othercase = UCD_OTHERCASE(next);
+#else
+ othercase = NOTACHAR;
+#endif
+ return (unsigned int)c == othercase;
+ }
+ else
+#endif /* SUPPORT_UTF */
+ return (c == (int)(TABLE_GET((unsigned int)next, cd->fcc, next))); /* Non-UTF-8 mode */
+
+ /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set.
+ When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */
+
+ case OP_DIGIT:
+ return next > 127 || (cd->ctypes[next] & ctype_digit) == 0;
+
+ case OP_NOT_DIGIT:
+ return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0;
+
+ case OP_WHITESPACE:
+ return next > 127 || (cd->ctypes[next] & ctype_space) == 0;
+
+ case OP_NOT_WHITESPACE:
+ return next <= 127 && (cd->ctypes[next] & ctype_space) != 0;
+
+ case OP_WORDCHAR:
+ return next > 127 || (cd->ctypes[next] & ctype_word) == 0;
+
+ case OP_NOT_WORDCHAR:
+ return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
+
+ case OP_HSPACE:
+ case OP_NOT_HSPACE:
+ switch(next)
+ {
+ case 0x09:
+ case 0x20:
+ case 0xa0:
+ case 0x1680:
+ case 0x180e:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2007:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x202f:
+ case 0x205f:
+ case 0x3000:
+ return op_code == OP_NOT_HSPACE;
+ default:
+ return op_code != OP_NOT_HSPACE;
+ }
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ case OP_NOT_VSPACE:
+ switch(next)
+ {
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x85:
+ case 0x2028:
+ case 0x2029:
+ return op_code == OP_NOT_VSPACE;
+ default:
+ return op_code != OP_NOT_VSPACE;
+ }
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ return check_char_prop(next, previous[0], previous[1], FALSE);
+
+ case OP_NOTPROP:
+ return check_char_prop(next, previous[0], previous[1], TRUE);
+#endif
+
+ default:
+ return FALSE;
+ }
+
+
+/* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP
+is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are
+generated only when PCRE_UCP is *not* set, that is, when only ASCII
+characteristics are recognized. Similarly, the opcodes OP_DIGIT etc. are
+replaced by OP_PROP codes when PCRE_UCP is set. */
+
+switch(op_code)
+ {
+ case OP_CHAR:
+ case OP_CHARI:
+#ifdef SUPPORT_UTF
+ GETCHARTEST(c, previous);
+#else
+ c = *previous;
+#endif
+ switch(-next)
+ {
+ case ESC_d:
+ return c > 127 || (cd->ctypes[c] & ctype_digit) == 0;
+
+ case ESC_D:
+ return c <= 127 && (cd->ctypes[c] & ctype_digit) != 0;
+
+ case ESC_s:
+ return c > 127 || (cd->ctypes[c] & ctype_space) == 0;
+
+ case ESC_S:
+ return c <= 127 && (cd->ctypes[c] & ctype_space) != 0;
+
+ case ESC_w:
+ return c > 127 || (cd->ctypes[c] & ctype_word) == 0;
+
+ case ESC_W:
+ return c <= 127 && (cd->ctypes[c] & ctype_word) != 0;
+
+ case ESC_h:
+ case ESC_H:
+ switch(c)
+ {
+ case 0x09:
+ case 0x20:
+ case 0xa0:
+ case 0x1680:
+ case 0x180e:
+ case 0x2000:
+ case 0x2001:
+ case 0x2002:
+ case 0x2003:
+ case 0x2004:
+ case 0x2005:
+ case 0x2006:
+ case 0x2007:
+ case 0x2008:
+ case 0x2009:
+ case 0x200A:
+ case 0x202f:
+ case 0x205f:
+ case 0x3000:
+ return -next != ESC_h;
+ default:
+ return -next == ESC_h;
+ }
+
+ case ESC_v:
+ case ESC_V:
+ switch(c)
+ {
+ case 0x0a:
+ case 0x0b:
+ case 0x0c:
+ case 0x0d:
+ case 0x85:
+ case 0x2028:
+ case 0x2029:
+ return -next != ESC_v;
+ default:
+ return -next == ESC_v;
+ }
+
+ /* When PCRE_UCP is set, these values get generated for \d etc. Find
+ their substitutions and process them. The result will always be either
+ -ESC_p or -ESC_P. Then fall through to process those values. */
+
+#ifdef SUPPORT_UCP
+ case ESC_du:
+ case ESC_DU:
+ case ESC_wu:
+ case ESC_WU:
+ case ESC_su:
+ case ESC_SU:
+ {
+ int temperrorcode = 0;
+ ptr = substitutes[-next - ESC_DU];
+ next = check_escape(&ptr, &temperrorcode, 0, options, FALSE);
+ if (temperrorcode != 0) return FALSE;
+ ptr++; /* For compatibility */
+ }
+ /* Fall through */
+
+ case ESC_p:
+ case ESC_P:
+ {
+ int ptype, pdata, errorcodeptr;
+ BOOL negated;
+
+ ptr--; /* Make ptr point at the p or P */
+ ptype = get_ucp(&ptr, &negated, &pdata, &errorcodeptr);
+ if (ptype < 0) return FALSE;
+ ptr++; /* Point past the final curly ket */
+
+ /* If the property item is optional, we have to give up. (When generated
+ from \d etc by PCRE_UCP, this test will have been applied much earlier,
+ to the original \d etc. At this point, ptr will point to a zero byte. */
+
+ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
+ STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+ return FALSE;
+
+ /* Do the property check. */
+
+ return check_char_prop(c, ptype, pdata, (next == -ESC_P) != negated);
+ }
+#endif
+
+ default:
+ return FALSE;
+ }
+
+ /* In principle, support for Unicode properties should be integrated here as
+ well. It means re-organizing the above code so as to get hold of the property
+ values before switching on the op-code. However, I wonder how many patterns
+ combine ASCII \d etc with Unicode properties? (Note that if PCRE_UCP is set,
+ these op-codes are never generated.) */
+
+ case OP_DIGIT:
+ return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
+ next == -ESC_h || next == -ESC_v || next == -ESC_R;
+
+ case OP_NOT_DIGIT:
+ return next == -ESC_d;
+
+ case OP_WHITESPACE:
+ return next == -ESC_S || next == -ESC_d || next == -ESC_w || next == -ESC_R;
+
+ case OP_NOT_WHITESPACE:
+ return next == -ESC_s || next == -ESC_h || next == -ESC_v;
+
+ case OP_HSPACE:
+ return next == -ESC_S || next == -ESC_H || next == -ESC_d ||
+ next == -ESC_w || next == -ESC_v || next == -ESC_R;
+
+ case OP_NOT_HSPACE:
+ return next == -ESC_h;
+
+ /* Can't have \S in here because VT matches \S (Perl anomaly) */
+ case OP_ANYNL:
+ case OP_VSPACE:
+ return next == -ESC_V || next == -ESC_d || next == -ESC_w;
+
+ case OP_NOT_VSPACE:
+ return next == -ESC_v || next == -ESC_R;
+
+ case OP_WORDCHAR:
+ return next == -ESC_W || next == -ESC_s || next == -ESC_h ||
+ next == -ESC_v || next == -ESC_R;
+
+ case OP_NOT_WORDCHAR:
+ return next == -ESC_w || next == -ESC_d;
+
+ default:
+ return FALSE;
+ }
+
+/* Control does not reach here */
+}
+
+
+
+/*************************************************
+* Compile one branch *
+*************************************************/
+
+/* Scan the pattern, compiling it into the a vector. If the options are
+changed during the branch, the pointer is used to change the external options
+bits. This function is used during the pre-compile phase when we are trying
+to find out the amount of memory needed, as well as during the real compile
+phase. The value of lengthptr distinguishes the two phases.
+
+Arguments:
+ optionsptr pointer to the option bits
+ codeptr points to the pointer to the current code point
+ ptrptr points to the current pattern pointer
+ errorcodeptr points to error code variable
+ firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
+ reqcharptr set to the last literal character required, else < 0
+ bcptr points to current branch chain
+ cond_depth conditional nesting depth
+ cd contains pointers to tables etc.
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE on success
+ FALSE, with *errorcodeptr set non-zero on error
+*/
+
+static BOOL
+compile_branch(int *optionsptr, pcre_uchar **codeptr,
+ const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr,
+ pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth,
+ compile_data *cd, int *lengthptr)
+{
+int repeat_type, op_type;
+int repeat_min = 0, repeat_max = 0; /* To please picky compilers */
+int bravalue = 0;
+int greedy_default, greedy_non_default;
+pcre_int32 firstchar, reqchar;
+pcre_int32 zeroreqchar, zerofirstchar;
+pcre_int32 req_caseopt, reqvary, tempreqvary;
+int options = *optionsptr; /* May change dynamically */
+int after_manual_callout = 0;
+int length_prevgroup = 0;
+register int c;
+register pcre_uchar *code = *codeptr;
+pcre_uchar *last_code = code;
+pcre_uchar *orig_code = code;
+pcre_uchar *tempcode;
+BOOL inescq = FALSE;
+BOOL groupsetfirstchar = FALSE;
+const pcre_uchar *ptr = *ptrptr;
+const pcre_uchar *tempptr;
+const pcre_uchar *nestptr = NULL;
+pcre_uchar *previous = NULL;
+pcre_uchar *previous_callout = NULL;
+pcre_uchar *save_hwm = NULL;
+pcre_uint8 classbits[32];
+
+/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
+must not do this for other options (e.g. PCRE_EXTENDED) because they may change
+dynamically as we process the pattern. */
+
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+pcre_uchar utf_chars[6];
+#else
+BOOL utf = FALSE;
+#endif
+
+/* Helper variables for OP_XCLASS opcode (for characters > 255). */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+BOOL xclass;
+pcre_uchar *class_uchardata;
+pcre_uchar *class_uchardata_base;
+#endif
+
+#ifdef PCRE_DEBUG
+if (lengthptr != NULL) DPRINTF((">> start branch\n"));
+#endif
+
+/* Set up the default and non-default settings for greediness */
+
+greedy_default = ((options & PCRE_UNGREEDY) != 0);
+greedy_non_default = greedy_default ^ 1;
+
+/* Initialize no first byte, no required byte. REQ_UNSET means "no char
+matching encountered yet". It gets changed to REQ_NONE if we hit something that
+matches a non-fixed char first char; reqchar just remains unset if we never
+find one.
+
+When we hit a repeat whose minimum is zero, we may have to adjust these values
+to take the zero repeat into account. This is implemented by setting them to
+zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual
+item types that can be repeated set these backoff variables appropriately. */
+
+firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET;
+
+/* The variable req_caseopt contains either the REQ_CASELESS value
+or zero, according to the current setting of the caseless flag. The
+REQ_CASELESS leaves the lower 28 bit empty. It is added into the
+firstchar or reqchar variables to record the case status of the
+value. This is used only for ASCII characters. */
+
+req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
+
+/* Switch on next character until the end of the branch */
+
+for (;; ptr++)
+ {
+ BOOL negate_class;
+ BOOL should_flip_negation;
+ BOOL possessive_quantifier;
+ BOOL is_quantifier;
+ BOOL is_recurse;
+ BOOL reset_bracount;
+ int class_has_8bitchar;
+ int class_single_char;
+ int newoptions;
+ int recno;
+ int refsign;
+ int skipbytes;
+ int subreqchar;
+ int subfirstchar;
+ int terminator;
+ int mclength;
+ int tempbracount;
+ pcre_uchar mcbuffer[8];
+
+ /* Get next character in the pattern */
+
+ c = *ptr;
+
+ /* If we are at the end of a nested substitution, revert to the outer level
+ string. Nesting only happens one level deep. */
+
+ if (c == 0 && nestptr != NULL)
+ {
+ ptr = nestptr;
+ nestptr = NULL;
+ c = *ptr;
+ }
+
+ /* If we are in the pre-compile phase, accumulate the length used for the
+ previous cycle of this loop. */
+
+ if (lengthptr != NULL)
+ {
+#ifdef PCRE_DEBUG
+ if (code > cd->hwm) cd->hwm = code; /* High water info */
+#endif
+ if (code > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
+ {
+ *errorcodeptr = ERR52;
+ goto FAILED;
+ }
+
+ /* There is at least one situation where code goes backwards: this is the
+ case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
+ the class is simply eliminated. However, it is created first, so we have to
+ allow memory for it. Therefore, don't ever reduce the length at this point.
+ */
+
+ if (code < last_code) code = last_code;
+
+ /* Paranoid check for integer overflow */
+
+ if (OFLOW_MAX - *lengthptr < code - last_code)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+
+ *lengthptr += (int)(code - last_code);
+ DPRINTF(("length=%d added %d c=%c (0x%x)\n", *lengthptr,
+ (int)(code - last_code), c, c));
+
+ /* If "previous" is set and it is not at the start of the work space, move
+ it back to there, in order to avoid filling up the work space. Otherwise,
+ if "previous" is NULL, reset the current code pointer to the start. */
+
+ if (previous != NULL)
+ {
+ if (previous > orig_code)
+ {
+ memmove(orig_code, previous, IN_UCHARS(code - previous));
+ code -= previous - orig_code;
+ previous = orig_code;
+ }
+ }
+ else code = orig_code;
+
+ /* Remember where this code item starts so we can pick up the length
+ next time round. */
+
+ last_code = code;
+ }
+
+ /* In the real compile phase, just check the workspace used by the forward
+ reference list. */
+
+ else if (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN)
+ {
+ *errorcodeptr = ERR52;
+ goto FAILED;
+ }
+
+ /* If in \Q...\E, check for the end; if not, we have a literal */
+
+ if (inescq && c != 0)
+ {
+ if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
+ {
+ inescq = FALSE;
+ ptr++;
+ continue;
+ }
+ else
+ {
+ if (previous_callout != NULL)
+ {
+ if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
+ complete_callout(previous_callout, ptr, cd);
+ previous_callout = NULL;
+ }
+ if ((options & PCRE_AUTO_CALLOUT) != 0)
+ {
+ previous_callout = code;
+ code = auto_callout(code, ptr, cd);
+ }
+ goto NORMAL_CHAR;
+ }
+ }
+
+ /* Fill in length of a previous callout, except when the next thing is
+ a quantifier. */
+
+ is_quantifier =
+ c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
+ (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
+
+ if (!is_quantifier && previous_callout != NULL &&
+ after_manual_callout-- <= 0)
+ {
+ if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
+ complete_callout(previous_callout, ptr, cd);
+ previous_callout = NULL;
+ }
+
+ /* In extended mode, skip white space and comments. */
+
+ if ((options & PCRE_EXTENDED) != 0)
+ {
+ if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
+ if (c == CHAR_NUMBER_SIGN)
+ {
+ ptr++;
+ while (*ptr != 0)
+ {
+ if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+ ptr++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(ptr);
+#endif
+ }
+ if (*ptr != 0) continue;
+
+ /* Else fall through to handle end of string */
+ c = 0;
+ }
+ }
+
+ /* No auto callout for quantifiers. */
+
+ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
+ {
+ previous_callout = code;
+ code = auto_callout(code, ptr, cd);
+ }
+
+ switch(c)
+ {
+ /* ===================================================================*/
+ case 0: /* The branch terminates at string end */
+ case CHAR_VERTICAL_LINE: /* or | or ) */
+ case CHAR_RIGHT_PARENTHESIS:
+ *firstcharptr = firstchar;
+ *reqcharptr = reqchar;
+ *codeptr = code;
+ *ptrptr = ptr;
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < code - last_code)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += (int)(code - last_code); /* To include callout length */
+ DPRINTF((">> end branch\n"));
+ }
+ return TRUE;
+
+
+ /* ===================================================================*/
+ /* Handle single-character metacharacters. In multiline mode, ^ disables
+ the setting of any following char as a first character. */
+
+ case CHAR_CIRCUMFLEX_ACCENT:
+ previous = NULL;
+ if ((options & PCRE_MULTILINE) != 0)
+ {
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ *code++ = OP_CIRCM;
+ }
+ else *code++ = OP_CIRC;
+ break;
+
+ case CHAR_DOLLAR_SIGN:
+ previous = NULL;
+ *code++ = ((options & PCRE_MULTILINE) != 0)? OP_DOLLM : OP_DOLL;
+ break;
+
+ /* There can never be a first char if '.' is first, whatever happens about
+ repeats. The value of reqchar doesn't change either. */
+
+ case CHAR_DOT:
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+ previous = code;
+ *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
+ break;
+
+
+ /* ===================================================================*/
+ /* Character classes. If the included characters are all < 256, we build a
+ 32-byte bitmap of the permitted characters, except in the special case
+ where there is only one such character. For negated classes, we build the
+ map as usual, then invert it at the end. However, we use a different opcode
+ so that data characters > 255 can be handled correctly.
+
+ If the class contains characters outside the 0-255 range, a different
+ opcode is compiled. It may optionally have a bit map for characters < 256,
+ but those above are are explicitly listed afterwards. A flag byte tells
+ whether the bitmap is present, and whether this is a negated class or not.
+
+ In JavaScript compatibility mode, an isolated ']' causes an error. In
+ default (Perl) mode, it is treated as a data character. */
+
+ case CHAR_RIGHT_SQUARE_BRACKET:
+ if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ *errorcodeptr = ERR64;
+ goto FAILED;
+ }
+ goto NORMAL_CHAR;
+
+ case CHAR_LEFT_SQUARE_BRACKET:
+ previous = code;
+
+ /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
+ they are encountered at the top level, so we'll do that too. */
+
+ if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, &tempptr))
+ {
+ *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31;
+ goto FAILED;
+ }
+
+ /* If the first character is '^', set the negation flag and skip it. Also,
+ if the first few characters (either before or after ^) are \Q\E or \E we
+ skip them too. This makes for compatibility with Perl. */
+
+ negate_class = FALSE;
+ for (;;)
+ {
+ c = *(++ptr);
+ if (c == CHAR_BACKSLASH)
+ {
+ if (ptr[1] == CHAR_E)
+ ptr++;
+ else if (STRNCMP_UC_C8(ptr + 1, STR_Q STR_BACKSLASH STR_E, 3) == 0)
+ ptr += 3;
+ else
+ break;
+ }
+ else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
+ negate_class = TRUE;
+ else break;
+ }
+
+ /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
+ an initial ']' is taken as a data character -- the code below handles
+ that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
+ [^] must match any character, so generate OP_ALLANY. */
+
+ if (c == CHAR_RIGHT_SQUARE_BRACKET &&
+ (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
+ {
+ *code++ = negate_class? OP_ALLANY : OP_FAIL;
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ break;
+ }
+
+ /* If a class contains a negative special such as \S, we need to flip the
+ negation flag at the end, so that support for characters > 255 works
+ correctly (they are all included in the class). */
+
+ should_flip_negation = FALSE;
+
+ /* For optimization purposes, we track some properties of the class.
+ class_has_8bitchar will be non-zero, if the class contains at least one
+ < 256 character. class_single_char will be 1 if the class contains only
+ a single character. */
+
+ class_has_8bitchar = 0;
+ class_single_char = 0;
+
+ /* Initialize the 32-char bit map to all zeros. We build the map in a
+ temporary bit of memory, in case the class contains only 1 character (less
+ than 256), because in that case the compiled code doesn't use the bit map.
+ */
+
+ memset(classbits, 0, 32 * sizeof(pcre_uint8));
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ xclass = FALSE; /* No chars >= 256 */
+ class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */
+ class_uchardata_base = class_uchardata; /* For resetting in pass 1 */
+#endif
+
+ /* Process characters until ] is reached. By writing this as a "do" it
+ means that an initial ] is taken as a data character. At the start of the
+ loop, c contains the first byte of the character. */
+
+ if (c != 0) do
+ {
+ const pcre_uchar *oldptr;
+
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(c))
+ { /* Braces are required because the */
+ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */
+ }
+#endif
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ /* In the pre-compile phase, accumulate the length of any extra
+ data and reset the pointer. This is so that very large classes that
+ contain a zillion > 255 characters no longer overwrite the work space
+ (which is on the stack). */
+
+ if (lengthptr != NULL)
+ {
+ *lengthptr += class_uchardata - class_uchardata_base;
+ class_uchardata = class_uchardata_base;
+ }
+#endif
+
+ /* Inside \Q...\E everything is literal except \E */
+
+ if (inescq)
+ {
+ if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) /* If we are at \E */
+ {
+ inescq = FALSE; /* Reset literal state */
+ ptr++; /* Skip the 'E' */
+ continue; /* Carry on with next */
+ }
+ goto CHECK_RANGE; /* Could be range if \E follows */
+ }
+
+ /* Handle POSIX class names. Perl allows a negation extension of the
+ form [:^name:]. A square bracket that doesn't match the syntax is
+ treated as a literal. We also recognize the POSIX constructions
+ [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
+ 5.6 and 5.8 do. */
+
+ if (c == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
+ {
+ BOOL local_negate = FALSE;
+ int posix_class, taboffset, tabopt;
+ register const pcre_uint8 *cbits = cd->cbits;
+ pcre_uint8 pbits[32];
+
+ if (ptr[1] != CHAR_COLON)
+ {
+ *errorcodeptr = ERR31;
+ goto FAILED;
+ }
+
+ ptr += 2;
+ if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
+ {
+ local_negate = TRUE;
+ should_flip_negation = TRUE; /* Note negative special */
+ ptr++;
+ }
+
+ posix_class = check_posix_name(ptr, (int)(tempptr - ptr));
+ if (posix_class < 0)
+ {
+ *errorcodeptr = ERR30;
+ goto FAILED;
+ }
+
+ /* If matching is caseless, upper and lower are converted to
+ alpha. This relies on the fact that the class table starts with
+ alpha, lower, upper as the first 3 entries. */
+
+ if ((options & PCRE_CASELESS) != 0 && posix_class <= 2)
+ posix_class = 0;
+
+ /* When PCRE_UCP is set, some of the POSIX classes are converted to
+ different escape sequences that use Unicode properties. */
+
+#ifdef SUPPORT_UCP
+ if ((options & PCRE_UCP) != 0)
+ {
+ int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
+ if (posix_substitutes[pc] != NULL)
+ {
+ nestptr = tempptr + 1;
+ ptr = posix_substitutes[pc] - 1;
+ continue;
+ }
+ }
+#endif
+ /* In the non-UCP case, we build the bit map for the POSIX class in a
+ chunk of local store because we may be adding and subtracting from it,
+ and we don't want to subtract bits that may be in the main map already.
+ At the end we or the result into the bit map that is being built. */
+
+ posix_class *= 3;
+
+ /* Copy in the first table (always present) */
+
+ memcpy(pbits, cbits + posix_class_maps[posix_class],
+ 32 * sizeof(pcre_uint8));
+
+ /* If there is a second table, add or remove it as required. */
+
+ taboffset = posix_class_maps[posix_class + 1];
+ tabopt = posix_class_maps[posix_class + 2];
+
+ if (taboffset >= 0)
+ {
+ if (tabopt >= 0)
+ for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset];
+ else
+ for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset];
+ }
+
+ /* Not see if we need to remove any special characters. An option
+ value of 1 removes vertical space and 2 removes underscore. */
+
+ if (tabopt < 0) tabopt = -tabopt;
+ if (tabopt == 1) pbits[1] &= ~0x3c;
+ else if (tabopt == 2) pbits[11] &= 0x7f;
+
+ /* Add the POSIX table or its complement into the main table that is
+ being built and we are done. */
+
+ if (local_negate)
+ for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
+ else
+ for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
+
+ ptr = tempptr + 1;
+ /* Every class contains at least one < 256 characters. */
+ class_has_8bitchar = 1;
+ /* Every class contains at least two characters. */
+ class_single_char = 2;
+ continue; /* End of POSIX syntax handling */
+ }
+
+ /* Backslash may introduce a single character, or it may introduce one
+ of the specials, which just set a flag. The sequence \b is a special
+ case. Inside a class (and only there) it is treated as backspace. We
+ assume that other escapes have more than one character in them, so
+ speculatively set both class_has_8bitchar and class_single_char bigger
+ than one. Unrecognized escapes fall through and are either treated
+ as literal characters (by default), or are faulted if
+ PCRE_EXTRA is set. */
+
+ if (c == CHAR_BACKSLASH)
+ {
+ c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
+ if (*errorcodeptr != 0) goto FAILED;
+
+ if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
+ else if (-c == ESC_N) /* \N is not supported in a class */
+ {
+ *errorcodeptr = ERR71;
+ goto FAILED;
+ }
+ else if (-c == ESC_Q) /* Handle start of quoted string */
+ {
+ if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+ {
+ ptr += 2; /* avoid empty string */
+ }
+ else inescq = TRUE;
+ continue;
+ }
+ else if (-c == ESC_E) continue; /* Ignore orphan \E */
+
+ if (c < 0)
+ {
+ register const pcre_uint8 *cbits = cd->cbits;
+ /* Every class contains at least two < 256 characters. */
+ class_has_8bitchar++;
+ /* Every class contains at least two characters. */
+ class_single_char += 2;
+
+ switch (-c)
+ {
+#ifdef SUPPORT_UCP
+ case ESC_du: /* These are the values given for \d etc */
+ case ESC_DU: /* when PCRE_UCP is set. We replace the */
+ case ESC_wu: /* escape sequence with an appropriate \p */
+ case ESC_WU: /* or \P to test Unicode properties instead */
+ case ESC_su: /* of the default ASCII testing. */
+ case ESC_SU:
+ nestptr = ptr;
+ ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
+ class_has_8bitchar--; /* Undo! */
+ continue;
+#endif
+ case ESC_d:
+ for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
+ continue;
+
+ case ESC_D:
+ should_flip_negation = TRUE;
+ for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
+ continue;
+
+ case ESC_w:
+ for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
+ continue;
+
+ case ESC_W:
+ should_flip_negation = TRUE;
+ for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
+ continue;
+
+ /* Perl 5.004 onwards omits VT from \s, but we must preserve it
+ if it was previously set by something earlier in the character
+ class. */
+
+ case ESC_s:
+ classbits[0] |= cbits[cbit_space];
+ classbits[1] |= cbits[cbit_space+1] & ~0x08;
+ for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
+ continue;
+
+ case ESC_S:
+ should_flip_negation = TRUE;
+ for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
+ classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */
+ continue;
+
+ case ESC_h:
+ SETBIT(classbits, 0x09); /* VT */
+ SETBIT(classbits, 0x20); /* SPACE */
+ SETBIT(classbits, 0xa0); /* NSBP */
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x1680;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x180e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2000;
+ *class_uchardata++ = 0x200a;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x202f;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x205f;
+ *class_uchardata++ = XCL_SINGLE;
+ *class_uchardata++ = 0x3000;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata);
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata);
+ }
+#endif
+ continue;
+
+ case ESC_H:
+ for (c = 0; c < 32; c++)
+ {
+ int x = 0xff;
+ switch (c)
+ {
+ case 0x09/8: x ^= 1 << (0x09%8); break;
+ case 0x20/8: x ^= 1 << (0x20%8); break;
+ case 0xa0/8: x ^= 1 << (0xa0%8); break;
+ default: break;
+ }
+ classbits[c] |= x;
+ }
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x0100;
+ *class_uchardata++ = 0x167f;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x1681;
+ *class_uchardata++ = 0x180d;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x180f;
+ *class_uchardata++ = 0x1fff;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x200b;
+ *class_uchardata++ = 0x202e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2030;
+ *class_uchardata++ = 0x205e;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2060;
+ *class_uchardata++ = 0x2fff;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x3001;
+#ifdef SUPPORT_UTF
+ if (utf)
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ else
+#endif
+ *class_uchardata++ = 0xffff;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ }
+#endif
+ continue;
+
+ case ESC_v:
+ SETBIT(classbits, 0x0a); /* LF */
+ SETBIT(classbits, 0x0b); /* VT */
+ SETBIT(classbits, 0x0c); /* FF */
+ SETBIT(classbits, 0x0d); /* CR */
+ SETBIT(classbits, 0x85); /* NEL */
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x2028;
+ *class_uchardata++ = 0x2029;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata);
+ }
+#endif
+ continue;
+
+ case ESC_V:
+ for (c = 0; c < 32; c++)
+ {
+ int x = 0xff;
+ switch (c)
+ {
+ case 0x0a/8: x ^= 1 << (0x0a%8);
+ x ^= 1 << (0x0b%8);
+ x ^= 1 << (0x0c%8);
+ x ^= 1 << (0x0d%8);
+ break;
+ case 0x85/8: x ^= 1 << (0x85%8); break;
+ default: break;
+ }
+ classbits[c] |= x;
+ }
+
+#ifndef COMPILE_PCRE8
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x0100;
+ *class_uchardata++ = 0x2027;
+ *class_uchardata++ = XCL_RANGE;
+ *class_uchardata++ = 0x202a;
+#ifdef SUPPORT_UTF
+ if (utf)
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ else
+#endif
+ *class_uchardata++ = 0xffff;
+#elif defined SUPPORT_UTF
+ if (utf)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata);
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
+ }
+#endif
+ continue;
+
+#ifdef SUPPORT_UCP
+ case ESC_p:
+ case ESC_P:
+ {
+ BOOL negated;
+ int pdata;
+ int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
+ if (ptype < 0) goto FAILED;
+ xclass = TRUE;
+ *class_uchardata++ = ((-c == ESC_p) != negated)?
+ XCL_PROP : XCL_NOTPROP;
+ *class_uchardata++ = ptype;
+ *class_uchardata++ = pdata;
+ class_has_8bitchar--; /* Undo! */
+ continue;
+ }
+#endif
+ /* Unrecognized escapes are faulted if PCRE is running in its
+ strict mode. By default, for compatibility with Perl, they are
+ treated as literals. */
+
+ default:
+ if ((options & PCRE_EXTRA) != 0)
+ {
+ *errorcodeptr = ERR7;
+ goto FAILED;
+ }
+ class_has_8bitchar--; /* Undo the speculative increase. */
+ class_single_char -= 2; /* Undo the speculative increase. */
+ c = *ptr; /* Get the final character and fall through */
+ break;
+ }
+ }
+
+ /* Fall through if we have a single character (c >= 0). This may be
+ greater than 256. */
+
+ } /* End of backslash handling */
+
+ /* A single character may be followed by '-' to form a range. However,
+ Perl does not permit ']' to be the end of the range. A '-' character
+ at the end is treated as a literal. Perl ignores orphaned \E sequences
+ entirely. The code for handling \Q and \E is messy. */
+
+ CHECK_RANGE:
+ while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+ {
+ inescq = FALSE;
+ ptr += 2;
+ }
+
+ oldptr = ptr;
+
+ /* Remember \r or \n */
+
+ if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+
+ /* Check for range */
+
+ if (!inescq && ptr[1] == CHAR_MINUS)
+ {
+ int d;
+ ptr += 2;
+ while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2;
+
+ /* If we hit \Q (not followed by \E) at this point, go into escaped
+ mode. */
+
+ while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
+ {
+ ptr += 2;
+ if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
+ { ptr += 2; continue; }
+ inescq = TRUE;
+ break;
+ }
+
+ if (*ptr == 0 || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET))
+ {
+ ptr = oldptr;
+ goto LONE_SINGLE_CHARACTER;
+ }
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ { /* Braces are required because the */
+ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */
+ }
+ else
+#endif
+ d = *ptr; /* Not UTF-8 mode */
+
+ /* The second part of a range can be a single-character escape, but
+ not any of the other escapes. Perl 5.6 treats a hyphen as a literal
+ in such circumstances. */
+
+ if (!inescq && d == CHAR_BACKSLASH)
+ {
+ d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
+ if (*errorcodeptr != 0) goto FAILED;
+
+ /* \b is backspace; any other special means the '-' was literal */
+
+ if (d < 0)
+ {
+ if (d == -ESC_b) d = CHAR_BS; else
+ {
+ ptr = oldptr;
+ goto LONE_SINGLE_CHARACTER; /* A few lines below */
+ }
+ }
+ }
+
+ /* Check that the two values are in the correct order. Optimize
+ one-character ranges */
+
+ if (d < c)
+ {
+ *errorcodeptr = ERR8;
+ goto FAILED;
+ }
+
+ if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */
+
+ /* Remember \r or \n */
+
+ if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+
+ /* Since we found a character range, single character optimizations
+ cannot be done anymore. */
+ class_single_char = 2;
+
+ /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless
+ matching, we have to use an XCLASS with extra data items. Caseless
+ matching for characters > 127 is available only if UCP support is
+ available. */
+
+#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
+ if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127)))
+#elif defined SUPPORT_UTF
+ if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
+#elif !(defined COMPILE_PCRE8)
+ if (d > 255)
+#endif
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ {
+ xclass = TRUE;
+
+ /* With UCP support, we can find the other case equivalents of
+ the relevant characters. There may be several ranges. Optimize how
+ they fit with the basic range. */
+
+#ifdef SUPPORT_UCP
+#ifndef COMPILE_PCRE8
+ if (utf && (options & PCRE_CASELESS) != 0)
+#else
+ if ((options & PCRE_CASELESS) != 0)
+#endif
+ {
+ unsigned int occ, ocd;
+ unsigned int cc = c;
+ unsigned int origd = d;
+ while (get_othercase_range(&cc, origd, &occ, &ocd))
+ {
+ if (occ >= (unsigned int)c &&
+ ocd <= (unsigned int)d)
+ continue; /* Skip embedded ranges */
+
+ if (occ < (unsigned int)c &&
+ ocd >= (unsigned int)c - 1) /* Extend the basic range */
+ { /* if there is overlap, */
+ c = occ; /* noting that if occ < c */
+ continue; /* we can't have ocd > d */
+ } /* because a subrange is */
+ if (ocd > (unsigned int)d &&
+ occ <= (unsigned int)d + 1) /* always shorter than */
+ { /* the basic range. */
+ d = ocd;
+ continue;
+ }
+
+ if (occ == ocd)
+ {
+ *class_uchardata++ = XCL_SINGLE;
+ }
+ else
+ {
+ *class_uchardata++ = XCL_RANGE;
+ class_uchardata += PRIV(ord2utf)(occ, class_uchardata);
+ }
+ class_uchardata += PRIV(ord2utf)(ocd, class_uchardata);
+ }
+ }
+#endif /* SUPPORT_UCP */
+
+ /* Now record the original range, possibly modified for UCP caseless
+ overlapping ranges. */
+
+ *class_uchardata++ = XCL_RANGE;
+#ifdef SUPPORT_UTF
+#ifndef COMPILE_PCRE8
+ if (utf)
+ {
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(d, class_uchardata);
+ }
+ else
+ {
+ *class_uchardata++ = c;
+ *class_uchardata++ = d;
+ }
+#else
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+ class_uchardata += PRIV(ord2utf)(d, class_uchardata);
+#endif
+#else /* SUPPORT_UTF */
+ *class_uchardata++ = c;
+ *class_uchardata++ = d;
+#endif /* SUPPORT_UTF */
+
+ /* With UCP support, we are done. Without UCP support, there is no
+ caseless matching for UTF characters > 127; we can use the bit map
+ for the smaller ones. As for 16 bit characters without UTF, we
+ can still use */
+
+#ifdef SUPPORT_UCP
+#ifndef COMPILE_PCRE8
+ if (utf)
+#endif
+ continue; /* With next character in the class */
+#endif /* SUPPORT_UCP */
+
+#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8)
+ if (utf)
+ {
+ if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 127;
+ }
+ else
+ {
+ if (c > 255) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 255;
+ }
+#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP)
+ if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 127;
+#else
+ if (c > 255) continue;
+ /* Adjust upper limit and fall through to set up the map */
+ d = 255;
+#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */
+ }
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+
+ /* We use the bit map for 8 bit mode, or when the characters fall
+ partially or entirely to [0-255] ([0-127] for UCP) ranges. */
+
+ class_has_8bitchar = 1;
+
+ /* We can save a bit of time by skipping this in the pre-compile. */
+
+ if (lengthptr == NULL) for (; c <= d; c++)
+ {
+ classbits[c/8] |= (1 << (c&7));
+ if ((options & PCRE_CASELESS) != 0)
+ {
+ int uc = cd->fcc[c]; /* flip case */
+ classbits[uc/8] |= (1 << (uc&7));
+ }
+ }
+
+ continue; /* Go get the next char in the class */
+ }
+
+ /* Handle a lone single character - we can get here for a normal
+ non-escape char, or after \ that introduces a single character or for an
+ apparent range that isn't. */
+
+ LONE_SINGLE_CHARACTER:
+
+ /* Only the value of 1 matters for class_single_char. */
+ if (class_single_char < 2) class_single_char++;
+
+ /* If class_charcount is 1, we saw precisely one character. As long as
+ there were no negated characters >= 128 and there was no use of \p or \P,
+ in other words, no use of any XCLASS features, we can optimize.
+
+ In UTF-8 mode, we can optimize the negative case only if there were no
+ characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR
+ operate on single-bytes characters only. This is an historical hangover.
+ Maybe one day we can tidy these opcodes to handle multi-byte characters.
+
+ The optimization throws away the bit map. We turn the item into a
+ 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative.
+ Note that OP_NOT[I] does not support multibyte characters. In the positive
+ case, it can cause firstchar to be set. Otherwise, there can be no first
+ char if this item is first, whatever repeat count may follow. In the case
+ of reqchar, save the previous value for reinstating. */
+
+#ifdef SUPPORT_UTF
+ if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET
+ && (!utf || !negate_class || c < (MAX_VALUE_FOR_SINGLE_CHAR + 1)))
+#else
+ if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+#endif
+ {
+ ptr++;
+ zeroreqchar = reqchar;
+
+ /* The OP_NOT[I] opcodes work on single characters only. */
+
+ if (negate_class)
+ {
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT;
+ *code++ = c;
+ goto NOT_CHAR;
+ }
+
+ /* For a single, positive character, get the value into mcbuffer, and
+ then we can handle this with the normal one-character code. */
+
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ mclength = PRIV(ord2utf)(c, mcbuffer);
+ else
+#endif
+ {
+ mcbuffer[0] = c;
+ mclength = 1;
+ }
+ goto ONE_CHAR;
+ } /* End of 1-char optimization */
+
+ /* Handle a character that cannot go in the bit map. */
+
+#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8)
+ if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127)))
+#elif defined SUPPORT_UTF
+ if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
+#elif !(defined COMPILE_PCRE8)
+ if (c > 255)
+#endif
+
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ {
+ xclass = TRUE;
+ *class_uchardata++ = XCL_SINGLE;
+#ifdef SUPPORT_UTF
+#ifndef COMPILE_PCRE8
+ /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
+ if (!utf)
+ *class_uchardata++ = c;
+ else
+#endif
+ class_uchardata += PRIV(ord2utf)(c, class_uchardata);
+#else /* SUPPORT_UTF */
+ *class_uchardata++ = c;
+#endif /* SUPPORT_UTF */
+
+#ifdef SUPPORT_UCP
+#ifdef COMPILE_PCRE8
+ if ((options & PCRE_CASELESS) != 0)
+#else
+ /* In non 8 bit mode, we can get here even if we are not in UTF mode. */
+ if (utf && (options & PCRE_CASELESS) != 0)
+#endif
+ {
+ unsigned int othercase;
+ if ((int)(othercase = UCD_OTHERCASE(c)) != c)
+ {
+ *class_uchardata++ = XCL_SINGLE;
+ class_uchardata += PRIV(ord2utf)(othercase, class_uchardata);
+ }
+ }
+#endif /* SUPPORT_UCP */
+
+ }
+ else
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+
+ /* Handle a single-byte character */
+ {
+ class_has_8bitchar = 1;
+ classbits[c/8] |= (1 << (c&7));
+ if ((options & PCRE_CASELESS) != 0)
+ {
+ c = cd->fcc[c]; /* flip case */
+ classbits[c/8] |= (1 << (c&7));
+ }
+ }
+ }
+
+ /* Loop until ']' reached. This "while" is the end of the "do" far above.
+ If we are at the end of an internal nested string, revert to the outer
+ string. */
+
+ while (((c = *(++ptr)) != 0 ||
+ (nestptr != NULL &&
+ (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != 0)) &&
+ (c != CHAR_RIGHT_SQUARE_BRACKET || inescq));
+
+ /* Check for missing terminating ']' */
+
+ if (c == 0)
+ {
+ *errorcodeptr = ERR6;
+ goto FAILED;
+ }
+
+ /* If this is the first thing in the branch, there can be no first char
+ setting, whatever the repeat count. Any reqchar setting must remain
+ unchanged after any kind of repeat. */
+
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+
+ /* If there are characters with values > 255, we have to compile an
+ extended class, with its own opcode, unless there was a negated special
+ such as \S in the class, and PCRE_UCP is not set, because in that case all
+ characters > 255 are in the class, so any that were explicitly given as
+ well can be ignored. If (when there are explicit characters > 255 that must
+ be listed) there are no characters < 256, we can omit the bitmap in the
+ actual compiled code. */
+
+#ifdef SUPPORT_UTF
+ if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0))
+#elif !defined COMPILE_PCRE8
+ if (xclass && !should_flip_negation)
+#endif
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ {
+ *class_uchardata++ = XCL_END; /* Marks the end of extra data */
+ *code++ = OP_XCLASS;
+ code += LINK_SIZE;
+ *code = negate_class? XCL_NOT:0;
+
+ /* If the map is required, move up the extra data to make room for it;
+ otherwise just move the code pointer to the end of the extra data. */
+
+ if (class_has_8bitchar > 0)
+ {
+ *code++ |= XCL_MAP;
+ memmove(code + (32 / sizeof(pcre_uchar)), code,
+ IN_UCHARS(class_uchardata - code));
+ memcpy(code, classbits, 32);
+ code = class_uchardata + (32 / sizeof(pcre_uchar));
+ }
+ else code = class_uchardata;
+
+ /* Now fill in the complete length of the item */
+
+ PUT(previous, 1, (int)(code - previous));
+ break; /* End of class handling */
+ }
+#endif
+
+ /* If there are no characters > 255, or they are all to be included or
+ excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
+ whole class was negated and whether there were negative specials such as \S
+ (non-UCP) in the class. Then copy the 32-byte map into the code vector,
+ negating it if necessary. */
+
+ *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
+ if (lengthptr == NULL) /* Save time in the pre-compile phase */
+ {
+ if (negate_class)
+ for (c = 0; c < 32; c++) classbits[c] = ~classbits[c];
+ memcpy(code, classbits, 32);
+ }
+ code += 32 / sizeof(pcre_uchar);
+ NOT_CHAR:
+ break;
+
+
+ /* ===================================================================*/
+ /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
+ has been tested above. */
+
+ case CHAR_LEFT_CURLY_BRACKET:
+ if (!is_quantifier) goto NORMAL_CHAR;
+ ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
+ if (*errorcodeptr != 0) goto FAILED;
+ goto REPEAT;
+
+ case CHAR_ASTERISK:
+ repeat_min = 0;
+ repeat_max = -1;
+ goto REPEAT;
+
+ case CHAR_PLUS:
+ repeat_min = 1;
+ repeat_max = -1;
+ goto REPEAT;
+
+ case CHAR_QUESTION_MARK:
+ repeat_min = 0;
+ repeat_max = 1;
+
+ REPEAT:
+ if (previous == NULL)
+ {
+ *errorcodeptr = ERR9;
+ goto FAILED;
+ }
+
+ if (repeat_min == 0)
+ {
+ firstchar = zerofirstchar; /* Adjust for zero repeat */
+ reqchar = zeroreqchar; /* Ditto */
+ }
+
+ /* Remember whether this is a variable length repeat */
+
+ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
+
+ op_type = 0; /* Default single-char op codes */
+ possessive_quantifier = FALSE; /* Default not possessive quantifier */
+
+ /* Save start of previous item, in case we have to move it up in order to
+ insert something before it. */
+
+ tempcode = previous;
+
+ /* If the next character is '+', we have a possessive quantifier. This
+ implies greediness, whatever the setting of the PCRE_UNGREEDY option.
+ If the next character is '?' this is a minimizing repeat, by default,
+ but if PCRE_UNGREEDY is set, it works the other way round. We change the
+ repeat type to the non-default. */
+
+ if (ptr[1] == CHAR_PLUS)
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ ptr++;
+ }
+ else if (ptr[1] == CHAR_QUESTION_MARK)
+ {
+ repeat_type = greedy_non_default;
+ ptr++;
+ }
+ else repeat_type = greedy_default;
+
+ /* If previous was a recursion call, wrap it in atomic brackets so that
+ previous becomes the atomic group. All recursions were so wrapped in the
+ past, but it no longer happens for non-repeated recursions. In fact, the
+ repeated ones could be re-implemented independently so as not to need this,
+ but for the moment we rely on the code for repeating groups. */
+
+ if (*previous == OP_RECURSE)
+ {
+ memmove(previous + 1 + LINK_SIZE, previous, IN_UCHARS(1 + LINK_SIZE));
+ *previous = OP_ONCE;
+ PUT(previous, 1, 2 + 2*LINK_SIZE);
+ previous[2 + 2*LINK_SIZE] = OP_KET;
+ PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
+ code += 2 + 2 * LINK_SIZE;
+ length_prevgroup = 3 + 3*LINK_SIZE;
+
+ /* When actually compiling, we need to check whether this was a forward
+ reference, and if so, adjust the offset. */
+
+ if (lengthptr == NULL && cd->hwm >= cd->start_workspace + LINK_SIZE)
+ {
+ int offset = GET(cd->hwm, -LINK_SIZE);
+ if (offset == previous + 1 - cd->start_code)
+ PUT(cd->hwm, -LINK_SIZE, offset + 1 + LINK_SIZE);
+ }
+ }
+
+ /* Now handle repetition for the different types of item. */
+
+ /* If previous was a character match, abolish the item and generate a
+ repeat item instead. If a char item has a minumum of more than one, ensure
+ that it is set in reqchar - it might not be if a sequence such as x{3} is
+ the first thing in a branch because the x will have gone into firstchar
+ instead. */
+
+ if (*previous == OP_CHAR || *previous == OP_CHARI)
+ {
+ op_type = (*previous == OP_CHAR)? 0 : OP_STARI - OP_STAR;
+
+ /* Deal with UTF characters that take up more than one character. It's
+ easier to write this out separately than try to macrify it. Use c to
+ hold the length of the character in bytes, plus UTF_LENGTH to flag that
+ it's a length rather than a small character. */
+
+#ifdef SUPPORT_UTF
+ if (utf && NOT_FIRSTCHAR(code[-1]))
+ {
+ pcre_uchar *lastchar = code - 1;
+ BACKCHAR(lastchar);
+ c = (int)(code - lastchar); /* Length of UTF-8 character */
+ memcpy(utf_chars, lastchar, IN_UCHARS(c)); /* Save the char */
+ c |= UTF_LENGTH; /* Flag c as a length */
+ }
+ else
+#endif /* SUPPORT_UTF */
+
+ /* Handle the case of a single charater - either with no UTF support, or
+ with UTF disabled, or for a single character UTF character. */
+ {
+ c = code[-1];
+ if (repeat_min > 1) reqchar = c | req_caseopt | cd->req_varyopt;
+ }
+
+ /* If the repetition is unlimited, it pays to see if the next thing on
+ the line is something that cannot possibly match this character. If so,
+ automatically possessifying this item gains some performance in the case
+ where the match fails. */
+
+ if (!possessive_quantifier &&
+ repeat_max < 0 &&
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ }
+
+ goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */
+ }
+
+ /* If previous was a single negated character ([^a] or similar), we use
+ one of the special opcodes, replacing it. The code is shared with single-
+ character repeats by setting opt_type to add a suitable offset into
+ repeat_type. We can also test for auto-possessification. OP_NOT and OP_NOTI
+ are currently used only for single-byte chars. */
+
+ else if (*previous == OP_NOT || *previous == OP_NOTI)
+ {
+ op_type = ((*previous == OP_NOT)? OP_NOTSTAR : OP_NOTSTARI) - OP_STAR;
+ c = previous[1];
+ if (!possessive_quantifier &&
+ repeat_max < 0 &&
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ }
+ goto OUTPUT_SINGLE_REPEAT;
+ }
+
+ /* If previous was a character type match (\d or similar), abolish it and
+ create a suitable repeat item. The code is shared with single-character
+ repeats by setting op_type to add a suitable offset into repeat_type. Note
+ the the Unicode property types will be present only when SUPPORT_UCP is
+ defined, but we don't wrap the little bits of code here because it just
+ makes it horribly messy. */
+
+ else if (*previous < OP_EODN)
+ {
+ pcre_uchar *oldcode;
+ int prop_type, prop_value;
+ op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
+ c = *previous;
+
+ if (!possessive_quantifier &&
+ repeat_max < 0 &&
+ check_auto_possessive(previous, utf, ptr + 1, options, cd))
+ {
+ repeat_type = 0; /* Force greedy */
+ possessive_quantifier = TRUE;
+ }
+
+ OUTPUT_SINGLE_REPEAT:
+ if (*previous == OP_PROP || *previous == OP_NOTPROP)
+ {
+ prop_type = previous[1];
+ prop_value = previous[2];
+ }
+ else prop_type = prop_value = -1;
+
+ oldcode = code;
+ code = previous; /* Usually overwrite previous item */
+
+ /* If the maximum is zero then the minimum must also be zero; Perl allows
+ this case, so we do too - by simply omitting the item altogether. */
+
+ if (repeat_max == 0) goto END_REPEAT;
+
+ /*--------------------------------------------------------------------*/
+ /* This code is obsolete from release 8.00; the restriction was finally
+ removed: */
+
+ /* All real repeats make it impossible to handle partial matching (maybe
+ one day we will be able to remove this restriction). */
+
+ /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
+ /*--------------------------------------------------------------------*/
+
+ /* Combine the op_type with the repeat_type */
+
+ repeat_type += op_type;
+
+ /* A minimum of zero is handled either as the special case * or ?, or as
+ an UPTO, with the maximum given. */
+
+ if (repeat_min == 0)
+ {
+ if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
+ else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
+ else
+ {
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+
+ /* A repeat minimum of 1 is optimized into some special cases. If the
+ maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
+ left in place and, if the maximum is greater than 1, we use OP_UPTO with
+ one less than the maximum. */
+
+ else if (repeat_min == 1)
+ {
+ if (repeat_max == -1)
+ *code++ = OP_PLUS + repeat_type;
+ else
+ {
+ code = oldcode; /* leave previous item in place */
+ if (repeat_max == 1) goto END_REPEAT;
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max - 1);
+ }
+ }
+
+ /* The case {n,n} is just an EXACT, while the general case {n,m} is
+ handled as an EXACT followed by an UPTO. */
+
+ else
+ {
+ *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */
+ PUT2INC(code, 0, repeat_min);
+
+ /* If the maximum is unlimited, insert an OP_STAR. Before doing so,
+ we have to insert the character for the previous code. For a repeated
+ Unicode property match, there are two extra bytes that define the
+ required property. In UTF-8 mode, long characters have their length in
+ c, with the UTF_LENGTH bit as a flag. */
+
+ if (repeat_max < 0)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
+ {
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
+ code += c & 7;
+ }
+ else
+#endif
+ {
+ *code++ = c;
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+ }
+ *code++ = OP_STAR + repeat_type;
+ }
+
+ /* Else insert an UPTO if the max is greater than the min, again
+ preceded by the character, for the previously inserted code. If the
+ UPTO is just for 1 instance, we can use QUERY instead. */
+
+ else if (repeat_max != repeat_min)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
+ {
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
+ code += c & 7;
+ }
+ else
+#endif
+ *code++ = c;
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+ repeat_max -= repeat_min;
+
+ if (repeat_max == 1)
+ {
+ *code++ = OP_QUERY + repeat_type;
+ }
+ else
+ {
+ *code++ = OP_UPTO + repeat_type;
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+ }
+
+ /* The character or character type itself comes last in all cases. */
+
+#ifdef SUPPORT_UTF
+ if (utf && (c & UTF_LENGTH) != 0)
+ {
+ memcpy(code, utf_chars, IN_UCHARS(c & 7));
+ code += c & 7;
+ }
+ else
+#endif
+ *code++ = c;
+
+ /* For a repeated Unicode property match, there are two extra bytes that
+ define the required property. */
+
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ *code++ = prop_type;
+ *code++ = prop_value;
+ }
+#endif
+ }
+
+ /* If previous was a character class or a back reference, we put the repeat
+ stuff after it, but just skip the item if the repeat was {0,0}. */
+
+ else if (*previous == OP_CLASS ||
+ *previous == OP_NCLASS ||
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ *previous == OP_XCLASS ||
+#endif
+ *previous == OP_REF ||
+ *previous == OP_REFI)
+ {
+ if (repeat_max == 0)
+ {
+ code = previous;
+ goto END_REPEAT;
+ }
+
+ /*--------------------------------------------------------------------*/
+ /* This code is obsolete from release 8.00; the restriction was finally
+ removed: */
+
+ /* All real repeats make it impossible to handle partial matching (maybe
+ one day we will be able to remove this restriction). */
+
+ /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
+ /*--------------------------------------------------------------------*/
+
+ if (repeat_min == 0 && repeat_max == -1)
+ *code++ = OP_CRSTAR + repeat_type;
+ else if (repeat_min == 1 && repeat_max == -1)
+ *code++ = OP_CRPLUS + repeat_type;
+ else if (repeat_min == 0 && repeat_max == 1)
+ *code++ = OP_CRQUERY + repeat_type;
+ else
+ {
+ *code++ = OP_CRRANGE + repeat_type;
+ PUT2INC(code, 0, repeat_min);
+ if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */
+ PUT2INC(code, 0, repeat_max);
+ }
+ }
+
+ /* If previous was a bracket group, we may have to replicate it in certain
+ cases. Note that at this point we can encounter only the "basic" bracket
+ opcodes such as BRA and CBRA, as this is the place where they get converted
+ into the more special varieties such as BRAPOS and SBRA. A test for >=
+ OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
+ ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow
+ repetition of assertions, but now it does, for Perl compatibility. */
+
+ else if (*previous >= OP_ASSERT && *previous <= OP_COND)
+ {
+ register int i;
+ int len = (int)(code - previous);
+ pcre_uchar *bralink = NULL;
+ pcre_uchar *brazeroptr = NULL;
+
+ /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so
+ we just ignore the repeat. */
+
+ if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
+ goto END_REPEAT;
+
+ /* There is no sense in actually repeating assertions. The only potential
+ use of repetition is in cases when the assertion is optional. Therefore,
+ if the minimum is greater than zero, just ignore the repeat. If the
+ maximum is not not zero or one, set it to 1. */
+
+ if (*previous < OP_ONCE) /* Assertion */
+ {
+ if (repeat_min > 0) goto END_REPEAT;
+ if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
+ }
+
+ /* The case of a zero minimum is special because of the need to stick
+ OP_BRAZERO in front of it, and because the group appears once in the
+ data, whereas in other cases it appears the minimum number of times. For
+ this reason, it is simplest to treat this case separately, as otherwise
+ the code gets far too messy. There are several special subcases when the
+ minimum is zero. */
+
+ if (repeat_min == 0)
+ {
+ /* If the maximum is also zero, we used to just omit the group from the
+ output altogether, like this:
+
+ ** if (repeat_max == 0)
+ ** {
+ ** code = previous;
+ ** goto END_REPEAT;
+ ** }
+
+ However, that fails when a group or a subgroup within it is referenced
+ as a subroutine from elsewhere in the pattern, so now we stick in
+ OP_SKIPZERO in front of it so that it is skipped on execution. As we
+ don't have a list of which groups are referenced, we cannot do this
+ selectively.
+
+ If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
+ and do no more at this point. However, we do need to adjust any
+ OP_RECURSE calls inside the group that refer to the group itself or any
+ internal or forward referenced group, because the offset is from the
+ start of the whole regex. Temporarily terminate the pattern while doing
+ this. */
+
+ if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
+ {
+ *code = OP_END;
+ adjust_recurse(previous, 1, utf, cd, save_hwm);
+ memmove(previous + 1, previous, IN_UCHARS(len));
+ code++;
+ if (repeat_max == 0)
+ {
+ *previous++ = OP_SKIPZERO;
+ goto END_REPEAT;
+ }
+ brazeroptr = previous; /* Save for possessive optimizing */
+ *previous++ = OP_BRAZERO + repeat_type;
+ }
+
+ /* If the maximum is greater than 1 and limited, we have to replicate
+ in a nested fashion, sticking OP_BRAZERO before each set of brackets.
+ The first one has to be handled carefully because it's the original
+ copy, which has to be moved up. The remainder can be handled by code
+ that is common with the non-zero minimum case below. We have to
+ adjust the value or repeat_max, since one less copy is required. Once
+ again, we may have to adjust any OP_RECURSE calls inside the group. */
+
+ else
+ {
+ int offset;
+ *code = OP_END;
+ adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
+ code += 2 + LINK_SIZE;
+ *previous++ = OP_BRAZERO + repeat_type;
+ *previous++ = OP_BRA;
+
+ /* We chain together the bracket offset fields that have to be
+ filled in later when the ends of the brackets are reached. */
+
+ offset = (bralink == NULL)? 0 : (int)(previous - bralink);
+ bralink = previous;
+ PUTINC(previous, 0, offset);
+ }
+
+ repeat_max--;
+ }
+
+ /* If the minimum is greater than zero, replicate the group as many
+ times as necessary, and adjust the maximum to the number of subsequent
+ copies that we need. If we set a first char from the group, and didn't
+ set a required char, copy the latter from the former. If there are any
+ forward reference subroutine calls in the group, there will be entries on
+ the workspace list; replicate these with an appropriate increment. */
+
+ else
+ {
+ if (repeat_min > 1)
+ {
+ /* In the pre-compile phase, we don't actually do the replication. We
+ just adjust the length as if we had. Do some paranoid checks for
+ potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
+ integer type when available, otherwise double. */
+
+ if (lengthptr != NULL)
+ {
+ int delta = (repeat_min - 1)*length_prevgroup;
+ if ((INT64_OR_DOUBLE)(repeat_min - 1)*
+ (INT64_OR_DOUBLE)length_prevgroup >
+ (INT64_OR_DOUBLE)INT_MAX ||
+ OFLOW_MAX - *lengthptr < delta)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += delta;
+ }
+
+ /* This is compiling for real. If there is a set first byte for
+ the group, and we have not yet set a "required byte", set it. Make
+ sure there is enough workspace for copying forward references before
+ doing the copy. */
+
+ else
+ {
+ if (groupsetfirstchar && reqchar < 0) reqchar = firstchar;
+
+ for (i = 1; i < repeat_min; i++)
+ {
+ pcre_uchar *hc;
+ pcre_uchar *this_hwm = cd->hwm;
+ memcpy(code, previous, IN_UCHARS(len));
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+ {
+ int save_offset = save_hwm - cd->start_workspace;
+ int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+ this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
+ for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+ {
+ PUT(cd->hwm, 0, GET(hc, 0) + len);
+ cd->hwm += LINK_SIZE;
+ }
+ save_hwm = this_hwm;
+ code += len;
+ }
+ }
+ }
+
+ if (repeat_max > 0) repeat_max -= repeat_min;
+ }
+
+ /* This code is common to both the zero and non-zero minimum cases. If
+ the maximum is limited, it replicates the group in a nested fashion,
+ remembering the bracket starts on a stack. In the case of a zero minimum,
+ the first one was set up above. In all cases the repeat_max now specifies
+ the number of additional copies needed. Again, we must remember to
+ replicate entries on the forward reference list. */
+
+ if (repeat_max >= 0)
+ {
+ /* In the pre-compile phase, we don't actually do the replication. We
+ just adjust the length as if we had. For each repetition we must add 1
+ to the length for BRAZERO and for all but the last repetition we must
+ add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
+ paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
+ a 64-bit integer type when available, otherwise double. */
+
+ if (lengthptr != NULL && repeat_max > 0)
+ {
+ int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
+ 2 - 2*LINK_SIZE; /* Last one doesn't nest */
+ if ((INT64_OR_DOUBLE)repeat_max *
+ (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
+ > (INT64_OR_DOUBLE)INT_MAX ||
+ OFLOW_MAX - *lengthptr < delta)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += delta;
+ }
+
+ /* This is compiling for real */
+
+ else for (i = repeat_max - 1; i >= 0; i--)
+ {
+ pcre_uchar *hc;
+ pcre_uchar *this_hwm = cd->hwm;
+
+ *code++ = OP_BRAZERO + repeat_type;
+
+ /* All but the final copy start a new nesting, maintaining the
+ chain of brackets outstanding. */
+
+ if (i != 0)
+ {
+ int offset;
+ *code++ = OP_BRA;
+ offset = (bralink == NULL)? 0 : (int)(code - bralink);
+ bralink = code;
+ PUTINC(code, 0, offset);
+ }
+
+ memcpy(code, previous, IN_UCHARS(len));
+
+ /* Ensure there is enough workspace for forward references before
+ copying them. */
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
+ {
+ int save_offset = save_hwm - cd->start_workspace;
+ int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+ this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
+ for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+ {
+ PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
+ cd->hwm += LINK_SIZE;
+ }
+ save_hwm = this_hwm;
+ code += len;
+ }
+
+ /* Now chain through the pending brackets, and fill in their length
+ fields (which are holding the chain links pro tem). */
+
+ while (bralink != NULL)
+ {
+ int oldlinkoffset;
+ int offset = (int)(code - bralink + 1);
+ pcre_uchar *bra = code - offset;
+ oldlinkoffset = GET(bra, 1);
+ bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
+ *code++ = OP_KET;
+ PUTINC(code, 0, offset);
+ PUT(bra, 1, offset);
+ }
+ }
+
+ /* If the maximum is unlimited, set a repeater in the final copy. For
+ ONCE brackets, that's all we need to do. However, possessively repeated
+ ONCE brackets can be converted into non-capturing brackets, as the
+ behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
+ deal with possessive ONCEs specially.
+
+ Otherwise, when we are doing the actual compile phase, check to see
+ whether this group is one that could match an empty string. If so,
+ convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
+ that runtime checking can be done. [This check is also applied to ONCE
+ groups at runtime, but in a different way.]
+
+ Then, if the quantifier was possessive and the bracket is not a
+ conditional, we convert the BRA code to the POS form, and the KET code to
+ KETRPOS. (It turns out to be convenient at runtime to detect this kind of
+ subpattern at both the start and at the end.) The use of special opcodes
+ makes it possible to reduce greatly the stack usage in pcre_exec(). If
+ the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
+
+ Then, if the minimum number of matches is 1 or 0, cancel the possessive
+ flag so that the default action below, of wrapping everything inside
+ atomic brackets, does not happen. When the minimum is greater than 1,
+ there will be earlier copies of the group, and so we still have to wrap
+ the whole thing. */
+
+ else
+ {
+ pcre_uchar *ketcode = code - 1 - LINK_SIZE;
+ pcre_uchar *bracode = ketcode - GET(ketcode, 1);
+
+ /* Convert possessive ONCE brackets to non-capturing */
+
+ if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
+ possessive_quantifier) *bracode = OP_BRA;
+
+ /* For non-possessive ONCE brackets, all we need to do is to
+ set the KET. */
+
+ if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
+ *ketcode = OP_KETRMAX + repeat_type;
+
+ /* Handle non-ONCE brackets and possessive ONCEs (which have been
+ converted to non-capturing above). */
+
+ else
+ {
+ /* In the compile phase, check for empty string matching. */
+
+ if (lengthptr == NULL)
+ {
+ pcre_uchar *scode = bracode;
+ do
+ {
+ if (could_be_empty_branch(scode, ketcode, utf, cd))
+ {
+ *bracode += OP_SBRA - OP_BRA;
+ break;
+ }
+ scode += GET(scode, 1);
+ }
+ while (*scode == OP_ALT);
+ }
+
+ /* Handle possessive quantifiers. */
+
+ if (possessive_quantifier)
+ {
+ /* For COND brackets, we wrap the whole thing in a possessively
+ repeated non-capturing bracket, because we have not invented POS
+ versions of the COND opcodes. Because we are moving code along, we
+ must ensure that any pending recursive references are updated. */
+
+ if (*bracode == OP_COND || *bracode == OP_SCOND)
+ {
+ int nlen = (int)(code - bracode);
+ *code = OP_END;
+ adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
+ code += 1 + LINK_SIZE;
+ nlen += 1 + LINK_SIZE;
+ *bracode = OP_BRAPOS;
+ *code++ = OP_KETRPOS;
+ PUTINC(code, 0, nlen);
+ PUT(bracode, 1, nlen);
+ }
+
+ /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
+
+ else
+ {
+ *bracode += 1; /* Switch to xxxPOS opcodes */
+ *ketcode = OP_KETRPOS;
+ }
+
+ /* If the minimum is zero, mark it as possessive, then unset the
+ possessive flag when the minimum is 0 or 1. */
+
+ if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
+ if (repeat_min < 2) possessive_quantifier = FALSE;
+ }
+
+ /* Non-possessive quantifier */
+
+ else *ketcode = OP_KETRMAX + repeat_type;
+ }
+ }
+ }
+
+ /* If previous is OP_FAIL, it was generated by an empty class [] in
+ JavaScript mode. The other ways in which OP_FAIL can be generated, that is
+ by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
+ error above. We can just ignore the repeat in JS case. */
+
+ else if (*previous == OP_FAIL) goto END_REPEAT;
+
+ /* Else there's some kind of shambles */
+
+ else
+ {
+ *errorcodeptr = ERR11;
+ goto FAILED;
+ }
+
+ /* If the character following a repeat is '+', or if certain optimization
+ tests above succeeded, possessive_quantifier is TRUE. For some opcodes,
+ there are special alternative opcodes for this case. For anything else, we
+ wrap the entire repeated item inside OP_ONCE brackets. Logically, the '+'
+ notation is just syntactic sugar, taken from Sun's Java package, but the
+ special opcodes can optimize it.
+
+ Some (but not all) possessively repeated subpatterns have already been
+ completely handled in the code just above. For them, possessive_quantifier
+ is always FALSE at this stage.
+
+ Note that the repeated item starts at tempcode, not at previous, which
+ might be the first part of a string whose (former) last char we repeated.
+
+ Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
+ an 'upto' may follow. We skip over an 'exact' item, and then test the
+ length of what remains before proceeding. */
+
+ if (possessive_quantifier)
+ {
+ int len;
+
+ if (*tempcode == OP_TYPEEXACT)
+ tempcode += PRIV(OP_lengths)[*tempcode] +
+ ((tempcode[1 + IMM2_SIZE] == OP_PROP
+ || tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+
+ else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
+ {
+ tempcode += PRIV(OP_lengths)[*tempcode];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(tempcode[-1]))
+ tempcode += GET_EXTRALEN(tempcode[-1]);
+#endif
+ }
+
+ len = (int)(code - tempcode);
+ if (len > 0) switch (*tempcode)
+ {
+ case OP_STAR: *tempcode = OP_POSSTAR; break;
+ case OP_PLUS: *tempcode = OP_POSPLUS; break;
+ case OP_QUERY: *tempcode = OP_POSQUERY; break;
+ case OP_UPTO: *tempcode = OP_POSUPTO; break;
+
+ case OP_STARI: *tempcode = OP_POSSTARI; break;
+ case OP_PLUSI: *tempcode = OP_POSPLUSI; break;
+ case OP_QUERYI: *tempcode = OP_POSQUERYI; break;
+ case OP_UPTOI: *tempcode = OP_POSUPTOI; break;
+
+ case OP_NOTSTAR: *tempcode = OP_NOTPOSSTAR; break;
+ case OP_NOTPLUS: *tempcode = OP_NOTPOSPLUS; break;
+ case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
+ case OP_NOTUPTO: *tempcode = OP_NOTPOSUPTO; break;
+
+ case OP_NOTSTARI: *tempcode = OP_NOTPOSSTARI; break;
+ case OP_NOTPLUSI: *tempcode = OP_NOTPOSPLUSI; break;
+ case OP_NOTQUERYI: *tempcode = OP_NOTPOSQUERYI; break;
+ case OP_NOTUPTOI: *tempcode = OP_NOTPOSUPTOI; break;
+
+ case OP_TYPESTAR: *tempcode = OP_TYPEPOSSTAR; break;
+ case OP_TYPEPLUS: *tempcode = OP_TYPEPOSPLUS; break;
+ case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
+ case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
+
+ /* Because we are moving code along, we must ensure that any
+ pending recursive references are updated. */
+
+ default:
+ *code = OP_END;
+ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
+ memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
+ code += 1 + LINK_SIZE;
+ len += 1 + LINK_SIZE;
+ tempcode[0] = OP_ONCE;
+ *code++ = OP_KET;
+ PUTINC(code, 0, len);
+ PUT(tempcode, 1, len);
+ break;
+ }
+ }
+
+ /* In all case we no longer have a previous item. We also set the
+ "follows varying string" flag for subsequently encountered reqchars if
+ it isn't already set and we have just passed a varying length item. */
+
+ END_REPEAT:
+ previous = NULL;
+ cd->req_varyopt |= reqvary;
+ break;
+
+
+ /* ===================================================================*/
+ /* Start of nested parenthesized sub-expression, or comment or lookahead or
+ lookbehind or option setting or condition or all the other extended
+ parenthesis forms. */
+
+ case CHAR_LEFT_PARENTHESIS:
+ newoptions = options;
+ skipbytes = 0;
+ bravalue = OP_CBRA;
+ save_hwm = cd->hwm;
+ reset_bracount = FALSE;
+
+ /* First deal with various "verbs" that can be introduced by '*'. */
+
+ ptr++;
+ if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
+ || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
+ {
+ int i, namelen;
+ int arglen = 0;
+ const char *vn = verbnames;
+ const pcre_uchar *name = ptr + 1;
+ const pcre_uchar *arg = NULL;
+ previous = NULL;
+ ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_letter) != 0) ptr++;
+ namelen = (int)(ptr - name);
+
+ /* It appears that Perl allows any characters whatsoever, other than
+ a closing parenthesis, to appear in arguments, so we no longer insist on
+ letters, digits, and underscores. */
+
+ if (*ptr == CHAR_COLON)
+ {
+ arg = ++ptr;
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ arglen = (int)(ptr - arg);
+ }
+
+ if (*ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR60;
+ goto FAILED;
+ }
+
+ /* Scan the table of verb names */
+
+ for (i = 0; i < verbcount; i++)
+ {
+ if (namelen == verbs[i].len &&
+ STRNCMP_UC_C8(name, vn, namelen) == 0)
+ {
+ /* Check for open captures before ACCEPT and convert it to
+ ASSERT_ACCEPT if in an assertion. */
+
+ if (verbs[i].op == OP_ACCEPT)
+ {
+ open_capitem *oc;
+ if (arglen != 0)
+ {
+ *errorcodeptr = ERR59;
+ goto FAILED;
+ }
+ cd->had_accept = TRUE;
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+ {
+ *code++ = OP_CLOSE;
+ PUT2INC(code, 0, oc->number);
+ }
+ *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT;
+
+ /* Do not set firstchar after *ACCEPT */
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ }
+
+ /* Handle other cases with/without an argument */
+
+ else if (arglen == 0)
+ {
+ if (verbs[i].op < 0) /* Argument is mandatory */
+ {
+ *errorcodeptr = ERR66;
+ goto FAILED;
+ }
+ *code = verbs[i].op;
+ if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN;
+ }
+
+ else
+ {
+ if (verbs[i].op_arg < 0) /* Argument is forbidden */
+ {
+ *errorcodeptr = ERR59;
+ goto FAILED;
+ }
+ *code = verbs[i].op_arg;
+ if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN;
+ *code++ = arglen;
+ memcpy(code, arg, IN_UCHARS(arglen));
+ code += arglen;
+ *code++ = 0;
+ }
+
+ break; /* Found verb, exit loop */
+ }
+
+ vn += verbs[i].len + 1;
+ }
+
+ if (i < verbcount) continue; /* Successfully handled a verb */
+ *errorcodeptr = ERR60; /* Verb not recognized */
+ goto FAILED;
+ }
+
+ /* Deal with the extended parentheses; all are introduced by '?', and the
+ appearance of any of them means that this is not a capturing group. */
+
+ else if (*ptr == CHAR_QUESTION_MARK)
+ {
+ int i, set, unset, namelen;
+ int *optset;
+ const pcre_uchar *name;
+ pcre_uchar *slot;
+
+ switch (*(++ptr))
+ {
+ case CHAR_NUMBER_SIGN: /* Comment; skip to ket */
+ ptr++;
+ while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+ if (*ptr == 0)
+ {
+ *errorcodeptr = ERR18;
+ goto FAILED;
+ }
+ continue;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
+ reset_bracount = TRUE;
+ /* Fall through */
+
+ /* ------------------------------------------------------------ */
+ case CHAR_COLON: /* Non-capturing bracket */
+ bravalue = OP_BRA;
+ ptr++;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_LEFT_PARENTHESIS:
+ bravalue = OP_COND; /* Conditional group */
+
+ /* A condition can be an assertion, a number (referring to a numbered
+ group), a name (referring to a named group), or 'R', referring to
+ recursion. R and R&name are also permitted for recursion tests.
+
+ There are several syntaxes for testing a named group: (?(name)) is used
+ by Python; Perl 5.10 onwards uses (?() or (?('name')).
+
+ There are two unfortunate ambiguities, caused by history. (a) 'R' can
+ be the recursive thing or the name 'R' (and similarly for 'R' followed
+ by digits), and (b) a number could be a name that consists of digits.
+ In both cases, we look for a name first; if not found, we try the other
+ cases. */
+
+ /* For conditions that are assertions, check the syntax, and then exit
+ the switch. This will take control down to where bracketed groups,
+ including assertions, are processed. */
+
+ if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN ||
+ ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN))
+ break;
+
+ /* Most other conditions use OP_CREF (a couple change to OP_RREF
+ below), and all need to skip 1+IMM2_SIZE bytes at the start of the group. */
+
+ code[1+LINK_SIZE] = OP_CREF;
+ skipbytes = 1+IMM2_SIZE;
+ refsign = -1;
+
+ /* Check for a test for recursion in a named group. */
+
+ if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
+ {
+ terminator = -1;
+ ptr += 2;
+ code[1+LINK_SIZE] = OP_RREF; /* Change the type of test */
+ }
+
+ /* Check for a test for a named group's having been set, using the Perl
+ syntax (?() or (?('name') */
+
+ else if (ptr[1] == CHAR_LESS_THAN_SIGN)
+ {
+ terminator = CHAR_GREATER_THAN_SIGN;
+ ptr++;
+ }
+ else if (ptr[1] == CHAR_APOSTROPHE)
+ {
+ terminator = CHAR_APOSTROPHE;
+ ptr++;
+ }
+ else
+ {
+ terminator = 0;
+ if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
+ }
+
+ /* We now expect to read a name; any thing else is an error */
+
+ if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
+ {
+ ptr += 1; /* To get the right offset */
+ *errorcodeptr = ERR28;
+ goto FAILED;
+ }
+
+ /* Read the name, but also get it as a number if it's all digits */
+
+ recno = 0;
+ name = ++ptr;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
+ {
+ if (recno >= 0)
+ recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1;
+ ptr++;
+ }
+ namelen = (int)(ptr - name);
+
+ if ((terminator > 0 && *ptr++ != terminator) ||
+ *ptr++ != CHAR_RIGHT_PARENTHESIS)
+ {
+ ptr--; /* Error offset */
+ *errorcodeptr = ERR26;
+ goto FAILED;
+ }
+
+ /* Do no further checking in the pre-compile phase. */
+
+ if (lengthptr != NULL) break;
+
+ /* In the real compile we do the work of looking for the actual
+ reference. If the string started with "+" or "-" we require the rest to
+ be digits, in which case recno will be set. */
+
+ if (refsign > 0)
+ {
+ if (recno <= 0)
+ {
+ *errorcodeptr = ERR58;
+ goto FAILED;
+ }
+ recno = (refsign == CHAR_MINUS)?
+ cd->bracount - recno + 1 : recno +cd->bracount;
+ if (recno <= 0 || recno > cd->final_bracount)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ PUT2(code, 2+LINK_SIZE, recno);
+ break;
+ }
+
+ /* Otherwise (did not start with "+" or "-"), start by looking for the
+ name. If we find a name, add one to the opcode to change OP_CREF or
+ OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same,
+ except they record that the reference was originally to a name. The
+ information is used to check duplicate names. */
+
+ slot = cd->name_table;
+ for (i = 0; i < cd->names_found; i++)
+ {
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0) break;
+ slot += cd->name_entry_size;
+ }
+
+ /* Found a previous named subpattern */
+
+ if (i < cd->names_found)
+ {
+ recno = GET2(slot, 0);
+ PUT2(code, 2+LINK_SIZE, recno);
+ code[1+LINK_SIZE]++;
+ }
+
+ /* Search the pattern for a forward reference */
+
+ else if ((i = find_parens(cd, name, namelen,
+ (options & PCRE_EXTENDED) != 0, utf)) > 0)
+ {
+ PUT2(code, 2+LINK_SIZE, i);
+ code[1+LINK_SIZE]++;
+ }
+
+ /* If terminator == 0 it means that the name followed directly after
+ the opening parenthesis [e.g. (?(abc)...] and in this case there are
+ some further alternatives to try. For the cases where terminator != 0
+ [things like (?(... or (?('name')... or (?(R&name)... ] we have
+ now checked all the possibilities, so give an error. */
+
+ else if (terminator != 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+
+ /* Check for (?(R) for recursion. Allow digits after R to specify a
+ specific group number. */
+
+ else if (*name == CHAR_R)
+ {
+ recno = 0;
+ for (i = 1; i < namelen; i++)
+ {
+ if (!IS_DIGIT(name[i]))
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ recno = recno * 10 + name[i] - CHAR_0;
+ }
+ if (recno == 0) recno = RREF_ANY;
+ code[1+LINK_SIZE] = OP_RREF; /* Change test type */
+ PUT2(code, 2+LINK_SIZE, recno);
+ }
+
+ /* Similarly, check for the (?(DEFINE) "condition", which is always
+ false. */
+
+ else if (namelen == 6 && STRNCMP_UC_C8(name, STRING_DEFINE, 6) == 0)
+ {
+ code[1+LINK_SIZE] = OP_DEF;
+ skipbytes = 1;
+ }
+
+ /* Check for the "name" actually being a subpattern number. We are
+ in the second pass here, so final_bracount is set. */
+
+ else if (recno > 0 && recno <= cd->final_bracount)
+ {
+ PUT2(code, 2+LINK_SIZE, recno);
+ }
+
+ /* Either an unidentified subpattern, or a reference to (?(0) */
+
+ else
+ {
+ *errorcodeptr = (recno == 0)? ERR35: ERR15;
+ goto FAILED;
+ }
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_EQUALS_SIGN: /* Positive lookahead */
+ bravalue = OP_ASSERT;
+ cd->assert_depth += 1;
+ ptr++;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_EXCLAMATION_MARK: /* Negative lookahead */
+ ptr++;
+ if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */
+ {
+ *code++ = OP_FAIL;
+ previous = NULL;
+ continue;
+ }
+ bravalue = OP_ASSERT_NOT;
+ cd->assert_depth += 1;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_LESS_THAN_SIGN: /* Lookbehind or named define */
+ switch (ptr[1])
+ {
+ case CHAR_EQUALS_SIGN: /* Positive lookbehind */
+ bravalue = OP_ASSERTBACK;
+ cd->assert_depth += 1;
+ ptr += 2;
+ break;
+
+ case CHAR_EXCLAMATION_MARK: /* Negative lookbehind */
+ bravalue = OP_ASSERTBACK_NOT;
+ cd->assert_depth += 1;
+ ptr += 2;
+ break;
+
+ default: /* Could be name define, else bad */
+ if (MAX_255(ptr[1]) && (cd->ctypes[ptr[1]] & ctype_word) != 0)
+ goto DEFINE_NAME;
+ ptr++; /* Correct offset for error */
+ *errorcodeptr = ERR24;
+ goto FAILED;
+ }
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_GREATER_THAN_SIGN: /* One-time brackets */
+ bravalue = OP_ONCE;
+ ptr++;
+ break;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_C: /* Callout - may be followed by digits; */
+ previous_callout = code; /* Save for later completion */
+ after_manual_callout = 1; /* Skip one item before completing */
+ *code++ = OP_CALLOUT;
+ {
+ int n = 0;
+ ptr++;
+ while(IS_DIGIT(*ptr))
+ n = n * 10 + *ptr++ - CHAR_0;
+ if (*ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR39;
+ goto FAILED;
+ }
+ if (n > 255)
+ {
+ *errorcodeptr = ERR38;
+ goto FAILED;
+ }
+ *code++ = n;
+ PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
+ PUT(code, LINK_SIZE, 0); /* Default length */
+ code += 2 * LINK_SIZE;
+ }
+ previous = NULL;
+ continue;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_P: /* Python-style named subpattern handling */
+ if (*(++ptr) == CHAR_EQUALS_SIGN ||
+ *ptr == CHAR_GREATER_THAN_SIGN) /* Reference or recursion */
+ {
+ is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
+ terminator = CHAR_RIGHT_PARENTHESIS;
+ goto NAMED_REF_OR_RECURSE;
+ }
+ else if (*ptr != CHAR_LESS_THAN_SIGN) /* Test for Python-style defn */
+ {
+ *errorcodeptr = ERR41;
+ goto FAILED;
+ }
+ /* Fall through to handle (?P< as (?< is handled */
+
+
+ /* ------------------------------------------------------------ */
+ DEFINE_NAME: /* Come here from (?< handling */
+ case CHAR_APOSTROPHE:
+ {
+ terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+ name = ++ptr;
+
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ namelen = (int)(ptr - name);
+
+ /* In the pre-compile phase, just do a syntax check. */
+
+ if (lengthptr != NULL)
+ {
+ if (*ptr != terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
+ if (cd->names_found >= MAX_NAME_COUNT)
+ {
+ *errorcodeptr = ERR49;
+ goto FAILED;
+ }
+ if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
+ {
+ cd->name_entry_size = namelen + IMM2_SIZE + 1;
+ if (namelen > MAX_NAME_SIZE)
+ {
+ *errorcodeptr = ERR48;
+ goto FAILED;
+ }
+ }
+ }
+
+ /* In the real compile, create the entry in the table, maintaining
+ alphabetical order. Duplicate names for different numbers are
+ permitted only if PCRE_DUPNAMES is set. Duplicate names for the same
+ number are always OK. (An existing number can be re-used if (?|
+ appears in the pattern.) In either event, a duplicate name results in
+ a duplicate entry in the table, even if the number is the same. This
+ is because the number of names, and hence the table size, is computed
+ in the pre-compile, and it affects various numbers and pointers which
+ would all have to be modified, and the compiled code moved down, if
+ duplicates with the same number were omitted from the table. This
+ doesn't seem worth the hassle. However, *different* names for the
+ same number are not permitted. */
+
+ else
+ {
+ BOOL dupname = FALSE;
+ slot = cd->name_table;
+
+ for (i = 0; i < cd->names_found; i++)
+ {
+ int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(namelen));
+ if (crc == 0)
+ {
+ if (slot[IMM2_SIZE+namelen] == 0)
+ {
+ if (GET2(slot, 0) != cd->bracount + 1 &&
+ (options & PCRE_DUPNAMES) == 0)
+ {
+ *errorcodeptr = ERR43;
+ goto FAILED;
+ }
+ else dupname = TRUE;
+ }
+ else crc = -1; /* Current name is a substring */
+ }
+
+ /* Make space in the table and break the loop for an earlier
+ name. For a duplicate or later name, carry on. We do this for
+ duplicates so that in the simple case (when ?(| is not used) they
+ are in order of their numbers. */
+
+ if (crc < 0)
+ {
+ memmove(slot + cd->name_entry_size, slot,
+ IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
+ break;
+ }
+
+ /* Continue the loop for a later or duplicate name */
+
+ slot += cd->name_entry_size;
+ }
+
+ /* For non-duplicate names, check for a duplicate number before
+ adding the new name. */
+
+ if (!dupname)
+ {
+ pcre_uchar *cslot = cd->name_table;
+ for (i = 0; i < cd->names_found; i++)
+ {
+ if (cslot != slot)
+ {
+ if (GET2(cslot, 0) == cd->bracount + 1)
+ {
+ *errorcodeptr = ERR65;
+ goto FAILED;
+ }
+ }
+ else i--;
+ cslot += cd->name_entry_size;
+ }
+ }
+
+ PUT2(slot, 0, cd->bracount + 1);
+ memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
+ slot[IMM2_SIZE + namelen] = 0;
+ }
+ }
+
+ /* In both pre-compile and compile, count the number of names we've
+ encountered. */
+
+ cd->names_found++;
+ ptr++; /* Move past > or ' */
+ goto NUMBERED_GROUP;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_AMPERSAND: /* Perl recursion/subroutine syntax */
+ terminator = CHAR_RIGHT_PARENTHESIS;
+ is_recurse = TRUE;
+ /* Fall through */
+
+ /* We come here from the Python syntax above that handles both
+ references (?P=name) and recursion (?P>name), as well as falling
+ through from the Perl recursion syntax (?&name). We also come here from
+ the Perl \k or \k'name' back reference syntax and the \k{name}
+ .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
+
+ NAMED_REF_OR_RECURSE:
+ name = ++ptr;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ namelen = (int)(ptr - name);
+
+ /* In the pre-compile phase, do a syntax check. We used to just set
+ a dummy reference number, because it was not used in the first pass.
+ However, with the change of recursive back references to be atomic,
+ we have to look for the number so that this state can be identified, as
+ otherwise the incorrect length is computed. If it's not a backwards
+ reference, the dummy number will do. */
+
+ if (lengthptr != NULL)
+ {
+ const pcre_uchar *temp;
+
+ if (namelen == 0)
+ {
+ *errorcodeptr = ERR62;
+ goto FAILED;
+ }
+ if (*ptr != terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
+ if (namelen > MAX_NAME_SIZE)
+ {
+ *errorcodeptr = ERR48;
+ goto FAILED;
+ }
+
+ /* The name table does not exist in the first pass, so we cannot
+ do a simple search as in the code below. Instead, we have to scan the
+ pattern to find the number. It is important that we scan it only as
+ far as we have got because the syntax of named subpatterns has not
+ been checked for the rest of the pattern, and find_parens() assumes
+ correct syntax. In any case, it's a waste of resources to scan
+ further. We stop the scan at the current point by temporarily
+ adjusting the value of cd->endpattern. */
+
+ temp = cd->end_pattern;
+ cd->end_pattern = ptr;
+ recno = find_parens(cd, name, namelen,
+ (options & PCRE_EXTENDED) != 0, utf);
+ cd->end_pattern = temp;
+ if (recno < 0) recno = 0; /* Forward ref; set dummy number */
+ }
+
+ /* In the real compile, seek the name in the table. We check the name
+ first, and then check that we have reached the end of the name in the
+ table. That way, if the name that is longer than any in the table,
+ the comparison will fail without reading beyond the table entry. */
+
+ else
+ {
+ slot = cd->name_table;
+ for (i = 0; i < cd->names_found; i++)
+ {
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) == 0 &&
+ slot[IMM2_SIZE+namelen] == 0)
+ break;
+ slot += cd->name_entry_size;
+ }
+
+ if (i < cd->names_found) /* Back reference */
+ {
+ recno = GET2(slot, 0);
+ }
+ else if ((recno = /* Forward back reference */
+ find_parens(cd, name, namelen,
+ (options & PCRE_EXTENDED) != 0, utf)) <= 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ }
+
+ /* In both phases, we can now go to the code than handles numerical
+ recursion or backreferences. */
+
+ if (is_recurse) goto HANDLE_RECURSION;
+ else goto HANDLE_REFERENCE;
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_R: /* Recursion */
+ ptr++; /* Same as (?0) */
+ /* Fall through */
+
+
+ /* ------------------------------------------------------------ */
+ case CHAR_MINUS: case CHAR_PLUS: /* Recursion or subroutine */
+ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
+ case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+ {
+ const pcre_uchar *called;
+ terminator = CHAR_RIGHT_PARENTHESIS;
+
+ /* Come here from the \g<...> and \g'...' code (Oniguruma
+ compatibility). However, the syntax has been checked to ensure that
+ the ... are a (signed) number, so that neither ERR63 nor ERR29 will
+ be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
+ ever be taken. */
+
+ HANDLE_NUMERICAL_RECURSION:
+
+ if ((refsign = *ptr) == CHAR_PLUS)
+ {
+ ptr++;
+ if (!IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR63;
+ goto FAILED;
+ }
+ }
+ else if (refsign == CHAR_MINUS)
+ {
+ if (!IS_DIGIT(ptr[1]))
+ goto OTHER_CHAR_AFTER_QUERY;
+ ptr++;
+ }
+
+ recno = 0;
+ while(IS_DIGIT(*ptr))
+ recno = recno * 10 + *ptr++ - CHAR_0;
+
+ if (*ptr != terminator)
+ {
+ *errorcodeptr = ERR29;
+ goto FAILED;
+ }
+
+ if (refsign == CHAR_MINUS)
+ {
+ if (recno == 0)
+ {
+ *errorcodeptr = ERR58;
+ goto FAILED;
+ }
+ recno = cd->bracount - recno + 1;
+ if (recno <= 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ }
+ else if (refsign == CHAR_PLUS)
+ {
+ if (recno == 0)
+ {
+ *errorcodeptr = ERR58;
+ goto FAILED;
+ }
+ recno += cd->bracount;
+ }
+
+ /* Come here from code above that handles a named recursion */
+
+ HANDLE_RECURSION:
+
+ previous = code;
+ called = cd->start_code;
+
+ /* When we are actually compiling, find the bracket that is being
+ referenced. Temporarily end the regex in case it doesn't exist before
+ this point. If we end up with a forward reference, first check that
+ the bracket does occur later so we can give the error (and position)
+ now. Then remember this forward reference in the workspace so it can
+ be filled in at the end. */
+
+ if (lengthptr == NULL)
+ {
+ *code = OP_END;
+ if (recno != 0)
+ called = PRIV(find_bracket)(cd->start_code, utf, recno);
+
+ /* Forward reference */
+
+ if (called == NULL)
+ {
+ if (find_parens(cd, NULL, recno,
+ (options & PCRE_EXTENDED) != 0, utf) < 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+
+ /* Fudge the value of "called" so that when it is inserted as an
+ offset below, what it actually inserted is the reference number
+ of the group. Then remember the forward reference. */
+
+ called = cd->start_code + recno;
+ if (cd->hwm >= cd->start_workspace + cd->workspace_size -
+ WORK_SIZE_SAFETY_MARGIN)
+ {
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+ }
+ PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
+ }
+
+ /* If not a forward reference, and the subpattern is still open,
+ this is a recursive call. We check to see if this is a left
+ recursion that could loop for ever, and diagnose that case. We
+ must not, however, do this check if we are in a conditional
+ subpattern because the condition might be testing for recursion in
+ a pattern such as /(?(R)a+|(?R)b)/, which is perfectly valid.
+ Forever loops are also detected at runtime, so those that occur in
+ conditional subpatterns will be picked up then. */
+
+ else if (GET(called, 1) == 0 && cond_depth <= 0 &&
+ could_be_empty(called, code, bcptr, utf, cd))
+ {
+ *errorcodeptr = ERR40;
+ goto FAILED;
+ }
+ }
+
+ /* Insert the recursion/subroutine item. It does not have a set first
+ character (relevant if it is repeated, because it will then be
+ wrapped with ONCE brackets). */
+
+ *code = OP_RECURSE;
+ PUT(code, 1, (int)(called - cd->start_code));
+ code += 1 + LINK_SIZE;
+ groupsetfirstchar = FALSE;
+ }
+
+ /* Can't determine a first byte now */
+
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ continue;
+
+
+ /* ------------------------------------------------------------ */
+ default: /* Other characters: check option setting */
+ OTHER_CHAR_AFTER_QUERY:
+ set = unset = 0;
+ optset = &set;
+
+ while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
+ {
+ switch (*ptr++)
+ {
+ case CHAR_MINUS: optset = &unset; break;
+
+ case CHAR_J: /* Record that it changed in the external options */
+ *optset |= PCRE_DUPNAMES;
+ cd->external_flags |= PCRE_JCHANGED;
+ break;
+
+ case CHAR_i: *optset |= PCRE_CASELESS; break;
+ case CHAR_m: *optset |= PCRE_MULTILINE; break;
+ case CHAR_s: *optset |= PCRE_DOTALL; break;
+ case CHAR_x: *optset |= PCRE_EXTENDED; break;
+ case CHAR_U: *optset |= PCRE_UNGREEDY; break;
+ case CHAR_X: *optset |= PCRE_EXTRA; break;
+
+ default: *errorcodeptr = ERR12;
+ ptr--; /* Correct the offset */
+ goto FAILED;
+ }
+ }
+
+ /* Set up the changed option bits, but don't change anything yet. */
+
+ newoptions = (options | set) & (~unset);
+
+ /* If the options ended with ')' this is not the start of a nested
+ group with option changes, so the options change at this level. If this
+ item is right at the start of the pattern, the options can be
+ abstracted and made external in the pre-compile phase, and ignored in
+ the compile phase. This can be helpful when matching -- for instance in
+ caseless checking of required bytes.
+
+ If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
+ definitely *not* at the start of the pattern because something has been
+ compiled. In the pre-compile phase, however, the code pointer can have
+ that value after the start, because it gets reset as code is discarded
+ during the pre-compile. However, this can happen only at top level - if
+ we are within parentheses, the starting BRA will still be present. At
+ any parenthesis level, the length value can be used to test if anything
+ has been compiled at that level. Thus, a test for both these conditions
+ is necessary to ensure we correctly detect the start of the pattern in
+ both phases.
+
+ If we are not at the pattern start, reset the greedy defaults and the
+ case value for firstchar and reqchar. */
+
+ if (*ptr == CHAR_RIGHT_PARENTHESIS)
+ {
+ if (code == cd->start_code + 1 + LINK_SIZE &&
+ (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
+ {
+ cd->external_options = newoptions;
+ }
+ else
+ {
+ greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
+ greedy_non_default = greedy_default ^ 1;
+ req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0;
+ }
+
+ /* Change options at this level, and pass them back for use
+ in subsequent branches. */
+
+ *optionsptr = options = newoptions;
+ previous = NULL; /* This item can't be repeated */
+ continue; /* It is complete */
+ }
+
+ /* If the options ended with ':' we are heading into a nested group
+ with possible change of options. Such groups are non-capturing and are
+ not assertions of any kind. All we need to do is skip over the ':';
+ the newoptions value is handled below. */
+
+ bravalue = OP_BRA;
+ ptr++;
+ } /* End of switch for character following (? */
+ } /* End of (? handling */
+
+ /* Opening parenthesis not followed by '*' or '?'. If PCRE_NO_AUTO_CAPTURE
+ is set, all unadorned brackets become non-capturing and behave like (?:...)
+ brackets. */
+
+ else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)
+ {
+ bravalue = OP_BRA;
+ }
+
+ /* Else we have a capturing group. */
+
+ else
+ {
+ NUMBERED_GROUP:
+ cd->bracount += 1;
+ PUT2(code, 1+LINK_SIZE, cd->bracount);
+ skipbytes = IMM2_SIZE;
+ }
+
+ /* Process nested bracketed regex. Assertions used not to be repeatable,
+ but this was changed for Perl compatibility, so all kinds can now be
+ repeated. We copy code into a non-register variable (tempcode) in order to
+ be able to pass its address because some compilers complain otherwise. */
+
+ previous = code; /* For handling repetition */
+ *code = bravalue;
+ tempcode = code;
+ tempreqvary = cd->req_varyopt; /* Save value before bracket */
+ tempbracount = cd->bracount; /* Save value before bracket */
+ length_prevgroup = 0; /* Initialize for pre-compile phase */
+
+ if (!compile_regex(
+ newoptions, /* The complete new option state */
+ &tempcode, /* Where to put code (updated) */
+ &ptr, /* Input pointer (updated) */
+ errorcodeptr, /* Where to put an error message */
+ (bravalue == OP_ASSERTBACK ||
+ bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
+ reset_bracount, /* True if (?| group */
+ skipbytes, /* Skip over bracket number */
+ cond_depth +
+ ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */
+ &subfirstchar, /* For possible first char */
+ &subreqchar, /* For possible last char */
+ bcptr, /* Current branch chain */
+ cd, /* Tables block */
+ (lengthptr == NULL)? NULL : /* Actual compile phase */
+ &length_prevgroup /* Pre-compile phase */
+ ))
+ goto FAILED;
+
+ /* If this was an atomic group and there are no capturing groups within it,
+ generate OP_ONCE_NC instead of OP_ONCE. */
+
+ if (bravalue == OP_ONCE && cd->bracount <= tempbracount)
+ *code = OP_ONCE_NC;
+
+ if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
+ cd->assert_depth -= 1;
+
+ /* At the end of compiling, code is still pointing to the start of the
+ group, while tempcode has been updated to point past the end of the group.
+ The pattern pointer (ptr) is on the bracket.
+
+ If this is a conditional bracket, check that there are no more than
+ two branches in the group, or just one if it's a DEFINE group. We do this
+ in the real compile phase, not in the pre-pass, where the whole group may
+ not be available. */
+
+ if (bravalue == OP_COND && lengthptr == NULL)
+ {
+ pcre_uchar *tc = code;
+ int condcount = 0;
+
+ do {
+ condcount++;
+ tc += GET(tc,1);
+ }
+ while (*tc != OP_KET);
+
+ /* A DEFINE group is never obeyed inline (the "condition" is always
+ false). It must have only one branch. */
+
+ if (code[LINK_SIZE+1] == OP_DEF)
+ {
+ if (condcount > 1)
+ {
+ *errorcodeptr = ERR54;
+ goto FAILED;
+ }
+ bravalue = OP_DEF; /* Just a flag to suppress char handling below */
+ }
+
+ /* A "normal" conditional group. If there is just one branch, we must not
+ make use of its firstchar or reqchar, because this is equivalent to an
+ empty second branch. */
+
+ else
+ {
+ if (condcount > 2)
+ {
+ *errorcodeptr = ERR27;
+ goto FAILED;
+ }
+ if (condcount == 1) subfirstchar = subreqchar = REQ_NONE;
+ }
+ }
+
+ /* Error if hit end of pattern */
+
+ if (*ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR14;
+ goto FAILED;
+ }
+
+ /* In the pre-compile phase, update the length by the length of the group,
+ less the brackets at either end. Then reduce the compiled code to just a
+ set of non-capturing brackets so that it doesn't use much memory if it is
+ duplicated by a quantifier.*/
+
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
+ {
+ *errorcodeptr = ERR20;
+ goto FAILED;
+ }
+ *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
+ code++; /* This already contains bravalue */
+ PUTINC(code, 0, 1 + LINK_SIZE);
+ *code++ = OP_KET;
+ PUTINC(code, 0, 1 + LINK_SIZE);
+ break; /* No need to waste time with special character handling */
+ }
+
+ /* Otherwise update the main code pointer to the end of the group. */
+
+ code = tempcode;
+
+ /* For a DEFINE group, required and first character settings are not
+ relevant. */
+
+ if (bravalue == OP_DEF) break;
+
+ /* Handle updating of the required and first characters for other types of
+ group. Update for normal brackets of all kinds, and conditions with two
+ branches (see code above). If the bracket is followed by a quantifier with
+ zero repeat, we have to back off. Hence the definition of zeroreqchar and
+ zerofirstchar outside the main loop so that they can be accessed for the
+ back off. */
+
+ zeroreqchar = reqchar;
+ zerofirstchar = firstchar;
+ groupsetfirstchar = FALSE;
+
+ if (bravalue >= OP_ONCE)
+ {
+ /* If we have not yet set a firstchar in this branch, take it from the
+ subpattern, remembering that it was set here so that a repeat of more
+ than one can replicate it as reqchar if necessary. If the subpattern has
+ no firstchar, set "none" for the whole branch. In both cases, a zero
+ repeat forces firstchar to "none". */
+
+ if (firstchar == REQ_UNSET)
+ {
+ if (subfirstchar >= 0)
+ {
+ firstchar = subfirstchar;
+ groupsetfirstchar = TRUE;
+ }
+ else firstchar = REQ_NONE;
+ zerofirstchar = REQ_NONE;
+ }
+
+ /* If firstchar was previously set, convert the subpattern's firstchar
+ into reqchar if there wasn't one, using the vary flag that was in
+ existence beforehand. */
+
+ else if (subfirstchar >= 0 && subreqchar < 0)
+ subreqchar = subfirstchar | tempreqvary;
+
+ /* If the subpattern set a required byte (or set a first byte that isn't
+ really the first byte - see above), set it. */
+
+ if (subreqchar >= 0) reqchar = subreqchar;
+ }
+
+ /* For a forward assertion, we take the reqchar, if set. This can be
+ helpful if the pattern that follows the assertion doesn't set a different
+ char. For example, it's useful for /(?=abcde).+/. We can't set firstchar
+ for an assertion, however because it leads to incorrect effect for patterns
+ such as /(?=a)a.+/ when the "real" "a" would then become a reqchar instead
+ of a firstchar. This is overcome by a scan at the end if there's no
+ firstchar, looking for an asserted first char. */
+
+ else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar;
+ break; /* End of processing '(' */
+
+
+ /* ===================================================================*/
+ /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
+ are arranged to be the negation of the corresponding OP_values in the
+ default case when PCRE_UCP is not set. For the back references, the values
+ are ESC_REF plus the reference number. Only back references and those types
+ that consume a character may be repeated. We can test for values between
+ ESC_b and ESC_Z for the latter; this may have to change if any new ones are
+ ever created. */
+
+ case CHAR_BACKSLASH:
+ tempptr = ptr;
+ c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE);
+ if (*errorcodeptr != 0) goto FAILED;
+
+ if (c < 0)
+ {
+ if (-c == ESC_Q) /* Handle start of quoted string */
+ {
+ if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+ ptr += 2; /* avoid empty string */
+ else inescq = TRUE;
+ continue;
+ }
+
+ if (-c == ESC_E) continue; /* Perl ignores an orphan \E */
+
+ /* For metasequences that actually match a character, we disable the
+ setting of a first character if it hasn't already been set. */
+
+ if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
+ firstchar = REQ_NONE;
+
+ /* Set values to reset to if this is followed by a zero repeat. */
+
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+
+ /* \g or \g'name' is a subroutine call by name and \g or \g'n'
+ is a subroutine call by number (Oniguruma syntax). In fact, the value
+ -ESC_g is returned only for these cases. So we don't need to check for <
+ or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is
+ -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as
+ that is a synonym for a named back reference). */
+
+ if (-c == ESC_g)
+ {
+ const pcre_uchar *p;
+ save_hwm = cd->hwm; /* Normally this is set when '(' is read */
+ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+
+ /* These two statements stop the compiler for warning about possibly
+ unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
+ fact, because we actually check for a number below, the paths that
+ would actually be in error are never taken. */
+
+ skipbytes = 0;
+ reset_bracount = FALSE;
+
+ /* Test for a name */
+
+ if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
+ {
+ BOOL is_a_number = TRUE;
+ for (p = ptr + 1; *p != 0 && *p != terminator; p++)
+ {
+ if (!MAX_255(*p)) { is_a_number = FALSE; break; }
+ if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE;
+ if ((cd->ctypes[*p] & ctype_word) == 0) break;
+ }
+ if (*p != terminator)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+ if (is_a_number)
+ {
+ ptr++;
+ goto HANDLE_NUMERICAL_RECURSION;
+ }
+ is_recurse = TRUE;
+ goto NAMED_REF_OR_RECURSE;
+ }
+
+ /* Test a signed number in angle brackets or quotes. */
+
+ p = ptr + 2;
+ while (IS_DIGIT(*p)) p++;
+ if (*p != terminator)
+ {
+ *errorcodeptr = ERR57;
+ break;
+ }
+ ptr++;
+ goto HANDLE_NUMERICAL_RECURSION;
+ }
+
+ /* \k or \k'name' is a back reference by name (Perl syntax).
+ We also support \k{name} (.NET syntax). */
+
+ if (-c == ESC_k)
+ {
+ if ((ptr[1] != CHAR_LESS_THAN_SIGN &&
+ ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
+ {
+ *errorcodeptr = ERR69;
+ break;
+ }
+ is_recurse = FALSE;
+ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
+ CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
+ goto NAMED_REF_OR_RECURSE;
+ }
+
+ /* Back references are handled specially; must disable firstchar if
+ not set to cope with cases like (?=(\w+))\1: which would otherwise set
+ ':' later. */
+
+ if (-c >= ESC_REF)
+ {
+ open_capitem *oc;
+ recno = -c - ESC_REF;
+
+ HANDLE_REFERENCE: /* Come here from named backref handling */
+ if (firstchar == REQ_UNSET) firstchar = REQ_NONE;
+ previous = code;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
+ PUT2INC(code, 0, recno);
+ cd->backref_map |= (recno < 32)? (1 << recno) : 1;
+ if (recno > cd->top_backref) cd->top_backref = recno;
+
+ /* Check to see if this back reference is recursive, that it, it
+ is inside the group that it references. A flag is set so that the
+ group can be made atomic. */
+
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+ {
+ if (oc->number == recno)
+ {
+ oc->flag = TRUE;
+ break;
+ }
+ }
+ }
+
+ /* So are Unicode property matches, if supported. */
+
+#ifdef SUPPORT_UCP
+ else if (-c == ESC_P || -c == ESC_p)
+ {
+ BOOL negated;
+ int pdata;
+ int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
+ if (ptype < 0) goto FAILED;
+ previous = code;
+ *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
+ *code++ = ptype;
+ *code++ = pdata;
+ }
+#else
+
+ /* If Unicode properties are not supported, \X, \P, and \p are not
+ allowed. */
+
+ else if (-c == ESC_X || -c == ESC_P || -c == ESC_p)
+ {
+ *errorcodeptr = ERR45;
+ goto FAILED;
+ }
+#endif
+
+ /* For the rest (including \X when Unicode properties are supported), we
+ can obtain the OP value by negating the escape value in the default
+ situation when PCRE_UCP is not set. When it *is* set, we substitute
+ Unicode property tests. */
+
+ else
+ {
+#ifdef SUPPORT_UCP
+ if (-c >= ESC_DU && -c <= ESC_wu)
+ {
+ nestptr = ptr + 1; /* Where to resume */
+ ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */
+ }
+ else
+#endif
+ /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE
+ so that it works in DFA mode and in lookbehinds. */
+
+ {
+ previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
+ *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c;
+ }
+ }
+ continue;
+ }
+
+ /* We have a data character whose value is in c. In UTF-8 mode it may have
+ a value > 127. We set its representation in the length/buffer, and then
+ handle it as a data character. */
+
+#ifdef SUPPORT_UTF
+ if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR)
+ mclength = PRIV(ord2utf)(c, mcbuffer);
+ else
+#endif
+
+ {
+ mcbuffer[0] = c;
+ mclength = 1;
+ }
+ goto ONE_CHAR;
+
+
+ /* ===================================================================*/
+ /* Handle a literal character. It is guaranteed not to be whitespace or #
+ when the extended flag is set. If we are in UTF-8 mode, it may be a
+ multi-byte literal character. */
+
+ default:
+ NORMAL_CHAR:
+ mclength = 1;
+ mcbuffer[0] = c;
+
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(c))
+ ACROSSCHAR(TRUE, ptr[1], mcbuffer[mclength++] = *(++ptr));
+#endif
+
+ /* At this point we have the character's bytes in mcbuffer, and the length
+ in mclength. When not in UTF-8 mode, the length is always 1. */
+
+ ONE_CHAR:
+ previous = code;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR;
+ for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
+
+ /* Remember if \r or \n were seen */
+
+ if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
+ cd->external_flags |= PCRE_HASCRORLF;
+
+ /* Set the first and required bytes appropriately. If no previous first
+ byte, set it from this character, but revert to none on a zero repeat.
+ Otherwise, leave the firstchar value alone, and don't change it on a zero
+ repeat. */
+
+ if (firstchar == REQ_UNSET)
+ {
+ zerofirstchar = REQ_NONE;
+ zeroreqchar = reqchar;
+
+ /* If the character is more than one byte long, we can set firstchar
+ only if it is not to be matched caselessly. */
+
+ if (mclength == 1 || req_caseopt == 0)
+ {
+ firstchar = mcbuffer[0] | req_caseopt;
+ if (mclength != 1) reqchar = code[-1] | cd->req_varyopt;
+ }
+ else firstchar = reqchar = REQ_NONE;
+ }
+
+ /* firstchar was previously set; we can set reqchar only if the length is
+ 1 or the matching is caseful. */
+
+ else
+ {
+ zerofirstchar = firstchar;
+ zeroreqchar = reqchar;
+ if (mclength == 1 || req_caseopt == 0)
+ reqchar = code[-1] | req_caseopt | cd->req_varyopt;
+ }
+
+ break; /* End of literal character handling */
+ }
+ } /* end of big loop */
+
+
+/* Control never reaches here by falling through, only by a goto for all the
+error states. Pass back the position in the pattern so that it can be displayed
+to the user for diagnosing the error. */
+
+FAILED:
+*ptrptr = ptr;
+return FALSE;
+}
+
+
+
+
+/*************************************************
+* Compile sequence of alternatives *
+*************************************************/
+
+/* On entry, ptr is pointing past the bracket character, but on return it
+points to the closing bracket, or vertical bar, or end of string. The code
+variable is pointing at the byte into which the BRA operator has been stored.
+This function is used during the pre-compile phase when we are trying to find
+out the amount of memory needed, as well as during the real compile phase. The
+value of lengthptr distinguishes the two phases.
+
+Arguments:
+ options option bits, including any changes for this subpattern
+ codeptr -> the address of the current code pointer
+ ptrptr -> the address of the current pattern pointer
+ errorcodeptr -> pointer to error code variable
+ lookbehind TRUE if this is a lookbehind assertion
+ reset_bracount TRUE to reset the count for each branch
+ skipbytes skip this many bytes at start (for brackets and OP_COND)
+ cond_depth depth of nesting for conditional subpatterns
+ firstcharptr place to put the first required character, or a negative number
+ reqcharptr place to put the last required character, or a negative number
+ bcptr pointer to the chain of currently open branches
+ cd points to the data block with tables pointers etc.
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE on success
+*/
+
+static BOOL
+compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr,
+ int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
+ int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr,
+ branch_chain *bcptr, compile_data *cd, int *lengthptr)
+{
+const pcre_uchar *ptr = *ptrptr;
+pcre_uchar *code = *codeptr;
+pcre_uchar *last_branch = code;
+pcre_uchar *start_bracket = code;
+pcre_uchar *reverse_count = NULL;
+open_capitem capitem;
+int capnumber = 0;
+pcre_int32 firstchar, reqchar;
+pcre_int32 branchfirstchar, branchreqchar;
+int length;
+int orig_bracount;
+int max_bracount;
+branch_chain bc;
+
+bc.outer = bcptr;
+bc.current_branch = code;
+
+firstchar = reqchar = REQ_UNSET;
+
+/* Accumulate the length for use in the pre-compile phase. Start with the
+length of the BRA and KET and any extra bytes that are required at the
+beginning. We accumulate in a local variable to save frequent testing of
+lenthptr for NULL. We cannot do this by looking at the value of code at the
+start and end of each alternative, because compiled items are discarded during
+the pre-compile phase so that the work space is not exceeded. */
+
+length = 2 + 2*LINK_SIZE + skipbytes;
+
+/* WARNING: If the above line is changed for any reason, you must also change
+the code that abstracts option settings at the start of the pattern and makes
+them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
+pre-compile phase to find out whether anything has yet been compiled or not. */
+
+/* If this is a capturing subpattern, add to the chain of open capturing items
+so that we can detect them if (*ACCEPT) is encountered. This is also used to
+detect groups that contain recursive back references to themselves. Note that
+only OP_CBRA need be tested here; changing this opcode to one of its variants,
+e.g. OP_SCBRAPOS, happens later, after the group has been compiled. */
+
+if (*code == OP_CBRA)
+ {
+ capnumber = GET2(code, 1 + LINK_SIZE);
+ capitem.number = capnumber;
+ capitem.next = cd->open_caps;
+ capitem.flag = FALSE;
+ cd->open_caps = &capitem;
+ }
+
+/* Offset is set zero to mark that this bracket is still open */
+
+PUT(code, 1, 0);
+code += 1 + LINK_SIZE + skipbytes;
+
+/* Loop for each alternative branch */
+
+orig_bracount = max_bracount = cd->bracount;
+for (;;)
+ {
+ /* For a (?| group, reset the capturing bracket count so that each branch
+ uses the same numbers. */
+
+ if (reset_bracount) cd->bracount = orig_bracount;
+
+ /* Set up dummy OP_REVERSE if lookbehind assertion */
+
+ if (lookbehind)
+ {
+ *code++ = OP_REVERSE;
+ reverse_count = code;
+ PUTINC(code, 0, 0);
+ length += 1 + LINK_SIZE;
+ }
+
+ /* Now compile the branch; in the pre-compile phase its length gets added
+ into the length. */
+
+ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar,
+ &branchreqchar, &bc, cond_depth, cd,
+ (lengthptr == NULL)? NULL : &length))
+ {
+ *ptrptr = ptr;
+ return FALSE;
+ }
+
+ /* Keep the highest bracket count in case (?| was used and some branch
+ has fewer than the rest. */
+
+ if (cd->bracount > max_bracount) max_bracount = cd->bracount;
+
+ /* In the real compile phase, there is some post-processing to be done. */
+
+ if (lengthptr == NULL)
+ {
+ /* If this is the first branch, the firstchar and reqchar values for the
+ branch become the values for the regex. */
+
+ if (*last_branch != OP_ALT)
+ {
+ firstchar = branchfirstchar;
+ reqchar = branchreqchar;
+ }
+
+ /* If this is not the first branch, the first char and reqchar have to
+ match the values from all the previous branches, except that if the
+ previous value for reqchar didn't have REQ_VARY set, it can still match,
+ and we set REQ_VARY for the regex. */
+
+ else
+ {
+ /* If we previously had a firstchar, but it doesn't match the new branch,
+ we have to abandon the firstchar for the regex, but if there was
+ previously no reqchar, it takes on the value of the old firstchar. */
+
+ if (firstchar >= 0 && firstchar != branchfirstchar)
+ {
+ if (reqchar < 0) reqchar = firstchar;
+ firstchar = REQ_NONE;
+ }
+
+ /* If we (now or from before) have no firstchar, a firstchar from the
+ branch becomes a reqchar if there isn't a branch reqchar. */
+
+ if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0)
+ branchreqchar = branchfirstchar;
+
+ /* Now ensure that the reqchars match */
+
+ if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY))
+ reqchar = REQ_NONE;
+ else reqchar |= branchreqchar; /* To "or" REQ_VARY */
+ }
+
+ /* If lookbehind, check that this branch matches a fixed-length string, and
+ put the length into the OP_REVERSE item. Temporarily mark the end of the
+ branch with OP_END. If the branch contains OP_RECURSE, the result is -3
+ because there may be forward references that we can't check here. Set a
+ flag to cause another lookbehind check at the end. Why not do it all at the
+ end? Because common, erroneous checks are picked up here and the offset of
+ the problem can be shown. */
+
+ if (lookbehind)
+ {
+ int fixed_length;
+ *code = OP_END;
+ fixed_length = find_fixedlength(last_branch, (options & PCRE_UTF8) != 0,
+ FALSE, cd);
+ DPRINTF(("fixed length = %d\n", fixed_length));
+ if (fixed_length == -3)
+ {
+ cd->check_lookbehind = TRUE;
+ }
+ else if (fixed_length < 0)
+ {
+ *errorcodeptr = (fixed_length == -2)? ERR36 :
+ (fixed_length == -4)? ERR70: ERR25;
+ *ptrptr = ptr;
+ return FALSE;
+ }
+ else { PUT(reverse_count, 0, fixed_length); }
+ }
+ }
+
+ /* Reached end of expression, either ')' or end of pattern. In the real
+ compile phase, go back through the alternative branches and reverse the chain
+ of offsets, with the field in the BRA item now becoming an offset to the
+ first alternative. If there are no alternatives, it points to the end of the
+ group. The length in the terminating ket is always the length of the whole
+ bracketed item. Return leaving the pointer at the terminating char. */
+
+ if (*ptr != CHAR_VERTICAL_LINE)
+ {
+ if (lengthptr == NULL)
+ {
+ int branch_length = (int)(code - last_branch);
+ do
+ {
+ int prev_length = GET(last_branch, 1);
+ PUT(last_branch, 1, branch_length);
+ branch_length = prev_length;
+ last_branch -= branch_length;
+ }
+ while (branch_length > 0);
+ }
+
+ /* Fill in the ket */
+
+ *code = OP_KET;
+ PUT(code, 1, (int)(code - start_bracket));
+ code += 1 + LINK_SIZE;
+
+ /* If it was a capturing subpattern, check to see if it contained any
+ recursive back references. If so, we must wrap it in atomic brackets.
+ In any event, remove the block from the chain. */
+
+ if (capnumber > 0)
+ {
+ if (cd->open_caps->flag)
+ {
+ memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+ IN_UCHARS(code - start_bracket));
+ *start_bracket = OP_ONCE;
+ code += 1 + LINK_SIZE;
+ PUT(start_bracket, 1, (int)(code - start_bracket));
+ *code = OP_KET;
+ PUT(code, 1, (int)(code - start_bracket));
+ code += 1 + LINK_SIZE;
+ length += 2 + 2*LINK_SIZE;
+ }
+ cd->open_caps = cd->open_caps->next;
+ }
+
+ /* Retain the highest bracket number, in case resetting was used. */
+
+ cd->bracount = max_bracount;
+
+ /* Set values to pass back */
+
+ *codeptr = code;
+ *ptrptr = ptr;
+ *firstcharptr = firstchar;
+ *reqcharptr = reqchar;
+ if (lengthptr != NULL)
+ {
+ if (OFLOW_MAX - *lengthptr < length)
+ {
+ *errorcodeptr = ERR20;
+ return FALSE;
+ }
+ *lengthptr += length;
+ }
+ return TRUE;
+ }
+
+ /* Another branch follows. In the pre-compile phase, we can move the code
+ pointer back to where it was for the start of the first branch. (That is,
+ pretend that each branch is the only one.)
+
+ In the real compile phase, insert an ALT node. Its length field points back
+ to the previous branch while the bracket remains open. At the end the chain
+ is reversed. It's done like this so that the start of the bracket has a
+ zero offset until it is closed, making it possible to detect recursion. */
+
+ if (lengthptr != NULL)
+ {
+ code = *codeptr + 1 + LINK_SIZE + skipbytes;
+ length += 1 + LINK_SIZE;
+ }
+ else
+ {
+ *code = OP_ALT;
+ PUT(code, 1, (int)(code - last_branch));
+ bc.current_branch = last_branch = code;
+ code += 1 + LINK_SIZE;
+ }
+
+ ptr++;
+ }
+/* Control never reaches here */
+}
+
+
+
+
+/*************************************************
+* Check for anchored expression *
+*************************************************/
+
+/* Try to find out if this is an anchored regular expression. Consider each
+alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
+all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
+it's anchored. However, if this is a multiline pattern, then only OP_SOD will
+be found, because ^ generates OP_CIRCM in that mode.
+
+We can also consider a regex to be anchored if OP_SOM starts all its branches.
+This is the code for \G, which means "match at start of match position, taking
+into account the match offset".
+
+A branch is also implicitly anchored if it starts with .* and DOTALL is set,
+because that will try the rest of the pattern at all possible matching points,
+so there is no point trying again.... er ....
+
+.... except when the .* appears inside capturing parentheses, and there is a
+subsequent back reference to those parentheses. We haven't enough information
+to catch that case precisely.
+
+At first, the best we could do was to detect when .* was in capturing brackets
+and the highest back reference was greater than or equal to that level.
+However, by keeping a bitmap of the first 31 back references, we can catch some
+of the more common cases more precisely.
+
+Arguments:
+ code points to start of expression (the bracket)
+ bracket_map a bitmap of which brackets we are inside while testing; this
+ handles up to substring 31; after that we just have to take
+ the less precise approach
+ backref_map the back reference bitmap
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_anchored(register const pcre_uchar *code, unsigned int bracket_map,
+ unsigned int backref_map)
+{
+do {
+ const pcre_uchar *scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
+ register int op = *scode;
+
+ /* Non-capturing brackets */
+
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
+ {
+ if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* Capturing brackets */
+
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
+ {
+ int n = GET2(scode, 1+LINK_SIZE);
+ int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+ if (!is_anchored(scode, new_map, backref_map)) return FALSE;
+ }
+
+ /* Other brackets */
+
+ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC ||
+ op == OP_COND)
+ {
+ if (!is_anchored(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
+ it isn't in brackets that are or may be referenced. */
+
+ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
+ op == OP_TYPEPOSSTAR))
+ {
+ if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0)
+ return FALSE;
+ }
+
+ /* Check for explicit anchoring */
+
+ else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE;
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT); /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for starting with ^ or .* *
+*************************************************/
+
+/* This is called to find out if every branch starts with ^ or .* so that
+"first char" processing can be done to speed things up in multiline
+matching and for non-DOTALL patterns that start with .* (which must start at
+the beginning or after \n). As in the case of is_anchored() (see above), we
+have to take account of back references to capturing brackets that contain .*
+because in that case we can't make the assumption.
+
+Arguments:
+ code points to start of expression (the bracket)
+ bracket_map a bitmap of which brackets we are inside while testing; this
+ handles up to substring 31; after that we just have to take
+ the less precise approach
+ backref_map the back reference bitmap
+
+Returns: TRUE or FALSE
+*/
+
+static BOOL
+is_startline(const pcre_uchar *code, unsigned int bracket_map,
+ unsigned int backref_map)
+{
+do {
+ const pcre_uchar *scode = first_significant_code(
+ code + PRIV(OP_lengths)[*code], FALSE);
+ register int op = *scode;
+
+ /* If we are at the start of a conditional assertion group, *both* the
+ conditional assertion *and* what follows the condition must satisfy the test
+ for start of line. Other kinds of condition fail. Note that there may be an
+ auto-callout at the start of a condition. */
+
+ if (op == OP_COND)
+ {
+ scode += 1 + LINK_SIZE;
+ if (*scode == OP_CALLOUT) scode += PRIV(OP_lengths)[OP_CALLOUT];
+ switch (*scode)
+ {
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_DEF:
+ return FALSE;
+
+ default: /* Assertion */
+ if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+ do scode += GET(scode, 1); while (*scode == OP_ALT);
+ scode += 1 + LINK_SIZE;
+ break;
+ }
+ scode = first_significant_code(scode, FALSE);
+ op = *scode;
+ }
+
+ /* Non-capturing brackets */
+
+ if (op == OP_BRA || op == OP_BRAPOS ||
+ op == OP_SBRA || op == OP_SBRAPOS)
+ {
+ if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* Capturing brackets */
+
+ else if (op == OP_CBRA || op == OP_CBRAPOS ||
+ op == OP_SCBRA || op == OP_SCBRAPOS)
+ {
+ int n = GET2(scode, 1+LINK_SIZE);
+ int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+ if (!is_startline(scode, new_map, backref_map)) return FALSE;
+ }
+
+ /* Other brackets */
+
+ else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC)
+ {
+ if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+ }
+
+ /* .* means "start at start or after \n" if it isn't in brackets that
+ may be referenced. */
+
+ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
+ {
+ if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE;
+ }
+
+ /* Check for explicit circumflex */
+
+ else if (op != OP_CIRC && op != OP_CIRCM) return FALSE;
+
+ /* Move on to the next alternative */
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT); /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+* Check for asserted fixed first char *
+*************************************************/
+
+/* During compilation, the "first char" settings from forward assertions are
+discarded, because they can cause conflicts with actual literals that follow.
+However, if we end up without a first char setting for an unanchored pattern,
+it is worth scanning the regex to see if there is an initial asserted first
+char. If all branches start with the same asserted char, or with a bracket all
+of whose alternatives start with the same asserted char (recurse ad lib), then
+we return that char, otherwise -1.
+
+Arguments:
+ code points to start of expression (the bracket)
+ inassert TRUE if in an assertion
+
+Returns: -1 or the fixed first char
+*/
+
+static int
+find_firstassertedchar(const pcre_uchar *code, BOOL inassert)
+{
+register int c = -1;
+do {
+ int d;
+ int xl = (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0;
+ const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl,
+ TRUE);
+ register int op = *scode;
+
+ switch(op)
+ {
+ default:
+ return -1;
+
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_ASSERT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_COND:
+ if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0)
+ return -1;
+ if (c < 0) c = d; else if (c != d) return -1;
+ break;
+
+ case OP_EXACT:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ if (!inassert) return -1;
+ if (c < 0) c = scode[1];
+ else if (c != scode[1]) return -1;
+ break;
+
+ case OP_EXACTI:
+ scode += IMM2_SIZE;
+ /* Fall through */
+
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ if (!inassert) return -1;
+ if (c < 0) c = scode[1] | REQ_CASELESS;
+ else if (c != scode[1]) return -1;
+ break;
+ }
+
+ code += GET(code, 1);
+ }
+while (*code == OP_ALT);
+return c;
+}
+
+
+
+/*************************************************
+* Compile a Regular Expression *
+*************************************************/
+
+/* This function takes a string and returns a pointer to a block of store
+holding a compiled version of the expression. The original API for this
+function had no error code return variable; it is retained for backwards
+compatibility. The new function is given a new name.
+
+Arguments:
+ pattern the regular expression
+ options various option bits
+ errorcodeptr pointer to error code variable (pcre_compile2() only)
+ can be NULL if you don't want a code value
+ errorptr pointer to pointer to error text
+ erroroffset ptr offset in pattern where error was detected
+ tables pointer to character tables or NULL
+
+Returns: pointer to compiled data block, or NULL on error,
+ with errorptr and erroroffset set
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
+pcre_compile(const char *pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+#else
+PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
+pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr,
+ int *erroroffset, const unsigned char *tables)
+#endif
+{
+#ifdef COMPILE_PCRE8
+return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+#else
+return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+#endif
+}
+
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
+pcre_compile2(const char *pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+#else
+PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION
+pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr,
+ const char **errorptr, int *erroroffset, const unsigned char *tables)
+#endif
+{
+REAL_PCRE *re;
+int length = 1; /* For final END opcode */
+pcre_int32 firstchar, reqchar;
+int newline;
+int errorcode = 0;
+int skipatstart = 0;
+BOOL utf;
+size_t size;
+pcre_uchar *code;
+const pcre_uchar *codestart;
+const pcre_uchar *ptr;
+compile_data compile_block;
+compile_data *cd = &compile_block;
+
+/* This space is used for "compiling" into during the first phase, when we are
+computing the amount of memory that is needed. Compiled items are thrown away
+as soon as possible, so that a fairly large buffer should be sufficient for
+this purpose. The same space is used in the second phase for remembering where
+to fill in forward references to subpatterns. That may overflow, in which case
+new memory is obtained from malloc(). */
+
+pcre_uchar cworkspace[COMPILE_WORK_SIZE];
+
+/* Set this early so that early errors get offset 0. */
+
+ptr = (const pcre_uchar *)pattern;
+
+/* We can't pass back an error message if errorptr is NULL; I guess the best we
+can do is just return NULL, but we can set a code value if there is a code
+pointer. */
+
+if (errorptr == NULL)
+ {
+ if (errorcodeptr != NULL) *errorcodeptr = 99;
+ return NULL;
+ }
+
+*errorptr = NULL;
+if (errorcodeptr != NULL) *errorcodeptr = ERR0;
+
+/* However, we can give a message for this error */
+
+if (erroroffset == NULL)
+ {
+ errorcode = ERR16;
+ goto PCRE_EARLY_ERROR_RETURN2;
+ }
+
+*erroroffset = 0;
+
+/* Set up pointers to the individual character tables */
+
+if (tables == NULL) tables = PRIV(default_tables);
+cd->lcc = tables + lcc_offset;
+cd->fcc = tables + fcc_offset;
+cd->cbits = tables + cbits_offset;
+cd->ctypes = tables + ctypes_offset;
+
+/* Check that all undefined public option bits are zero */
+
+if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
+ {
+ errorcode = ERR17;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Check for global one-time settings at the start of the pattern, and remember
+the offset for later. */
+
+while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
+ ptr[skipatstart+1] == CHAR_ASTERISK)
+ {
+ int newnl = 0;
+ int newbsr = 0;
+
+#ifdef COMPILE_PCRE8
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0)
+ { skipatstart += 7; options |= PCRE_UTF8; continue; }
+#endif
+#ifdef COMPILE_PCRE16
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0)
+ { skipatstart += 8; options |= PCRE_UTF16; continue; }
+#endif
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0)
+ { skipatstart += 6; options |= PCRE_UCP; continue; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
+ { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
+
+ if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CR_RIGHTPAR, 3) == 0)
+ { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LF_RIGHTPAR, 3) == 0)
+ { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_CRLF_RIGHTPAR, 5) == 0)
+ { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANY_RIGHTPAR, 4) == 0)
+ { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_ANYCRLF_RIGHTPAR, 8) == 0)
+ { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
+
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
+ { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
+ { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
+
+ if (newnl != 0)
+ options = (options & ~PCRE_NEWLINE_BITS) | newnl;
+ else if (newbsr != 0)
+ options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr;
+ else break;
+ }
+
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (options & PCRE_UTF8) != 0;
+
+/* Can't support UTF unless PCRE has been compiled to include the code. The
+return of an error code from PRIV(valid_utf)() is a new feature, introduced in
+release 8.13. It is passed back from pcre_[dfa_]exec(), but at the moment is
+not used here. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 &&
+ (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0)
+ {
+#ifdef COMPILE_PCRE8
+ errorcode = ERR44;
+#else
+ errorcode = ERR74;
+#endif
+ goto PCRE_EARLY_ERROR_RETURN2;
+ }
+#else
+if (utf)
+ {
+ errorcode = ERR32;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+#endif
+
+/* Can't support UCP unless PCRE has been compiled to include the code. */
+
+#ifndef SUPPORT_UCP
+if ((options & PCRE_UCP) != 0)
+ {
+ errorcode = ERR67;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+#endif
+
+/* Check validity of \R options. */
+
+if ((options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) ==
+ (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+ {
+ errorcode = ERR56;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Handle different types of newline. The three bits give seven cases. The
+current code allows for fixed one- or two-byte sequences, plus "any" and
+"anycrlf". */
+
+switch (options & PCRE_NEWLINE_BITS)
+ {
+ case 0: newline = NEWLINE; break; /* Build-time default */
+ case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+ default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+if (newline == -2)
+ {
+ cd->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
+ {
+ cd->nltype = NLTYPE_ANY;
+ }
+else
+ {
+ cd->nltype = NLTYPE_FIXED;
+ if (newline > 255)
+ {
+ cd->nllen = 2;
+ cd->nl[0] = (newline >> 8) & 255;
+ cd->nl[1] = newline & 255;
+ }
+ else
+ {
+ cd->nllen = 1;
+ cd->nl[0] = newline;
+ }
+ }
+
+/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
+references to help in deciding whether (.*) can be treated as anchored or not.
+*/
+
+cd->top_backref = 0;
+cd->backref_map = 0;
+
+/* Reflect pattern for debugging output */
+
+DPRINTF(("------------------------------------------------------------------\n"));
+#ifdef PCRE_DEBUG
+print_puchar(stdout, (PCRE_PUCHAR)pattern);
+#endif
+DPRINTF(("\n"));
+
+/* Pretend to compile the pattern while actually just accumulating the length
+of memory required. This behaviour is triggered by passing a non-NULL final
+argument to compile_regex(). We pass a block of workspace (cworkspace) for it
+to compile parts of the pattern into; the compiled code is discarded when it is
+no longer needed, so hopefully this workspace will never overflow, though there
+is a test for its doing so. */
+
+cd->bracount = cd->final_bracount = 0;
+cd->names_found = 0;
+cd->name_entry_size = 0;
+cd->name_table = NULL;
+cd->start_code = cworkspace;
+cd->hwm = cworkspace;
+cd->start_workspace = cworkspace;
+cd->workspace_size = COMPILE_WORK_SIZE;
+cd->start_pattern = (const pcre_uchar *)pattern;
+cd->end_pattern = (const pcre_uchar *)(pattern + STRLEN_UC((const pcre_uchar *)pattern));
+cd->req_varyopt = 0;
+cd->assert_depth = 0;
+cd->external_options = options;
+cd->external_flags = 0;
+cd->open_caps = NULL;
+
+/* Now do the pre-compile. On error, errorcode will be set non-zero, so we
+don't need to look at the result of the function here. The initial options have
+been put into the cd block so that they can be changed if an option setting is
+found within the regex right at the beginning. Bringing initial option settings
+outside can help speed up starting point checks. */
+
+ptr += skipatstart;
+code = cworkspace;
+*code = OP_BRA;
+(void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE,
+ FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length);
+if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
+
+DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
+ (int)(cd->hwm - cworkspace)));
+
+if (length > MAX_PATTERN_SIZE)
+ {
+ errorcode = ERR20;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Compute the size of data block needed and get it, either from malloc or
+externally provided function. Integer overflow should no longer be possible
+because nowadays we limit the maximum value of cd->names_found and
+cd->name_entry_size. */
+
+size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
+re = (REAL_PCRE *)(PUBL(malloc))(size);
+
+if (re == NULL)
+ {
+ errorcode = ERR21;
+ goto PCRE_EARLY_ERROR_RETURN;
+ }
+
+/* Put in the magic number, and save the sizes, initial options, internal
+flags, and character table pointer. NULL is used for the default character
+tables. The nullpad field is at the end; it's there to help in the case when a
+regex compiled on a system with 4-byte pointers is run on another with 8-byte
+pointers. */
+
+re->magic_number = MAGIC_NUMBER;
+re->size = (int)size;
+re->options = cd->external_options;
+re->flags = cd->external_flags;
+re->dummy1 = 0;
+re->first_char = 0;
+re->req_char = 0;
+re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
+re->name_entry_size = cd->name_entry_size;
+re->name_count = cd->names_found;
+re->ref_count = 0;
+re->tables = (tables == PRIV(default_tables))? NULL : tables;
+re->nullpad = NULL;
+
+/* The starting points of the name/number translation table and of the code are
+passed around in the compile data block. The start/end pattern and initial
+options are already set from the pre-compile phase, as is the name_entry_size
+field. Reset the bracket count and the names_found field. Also reset the hwm
+field; this time it's used for remembering forward references to subpatterns.
+*/
+
+cd->final_bracount = cd->bracount; /* Save for checking forward references */
+cd->assert_depth = 0;
+cd->bracount = 0;
+cd->names_found = 0;
+cd->name_table = (pcre_uchar *)re + re->name_table_offset;
+codestart = cd->name_table + re->name_entry_size * re->name_count;
+cd->start_code = codestart;
+cd->hwm = (pcre_uchar *)(cd->start_workspace);
+cd->req_varyopt = 0;
+cd->had_accept = FALSE;
+cd->check_lookbehind = FALSE;
+cd->open_caps = NULL;
+
+/* Set up a starting, non-extracting bracket, then compile the expression. On
+error, errorcode will be set non-zero, so we don't need to look at the result
+of the function here. */
+
+ptr = (const pcre_uchar *)pattern + skipatstart;
+code = (pcre_uchar *)codestart;
+*code = OP_BRA;
+(void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0,
+ &firstchar, &reqchar, NULL, cd, NULL);
+re->top_bracket = cd->bracount;
+re->top_backref = cd->top_backref;
+re->flags = cd->external_flags | PCRE_MODE;
+
+if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */
+
+/* If not reached end of pattern on success, there's an excess bracket. */
+
+if (errorcode == 0 && *ptr != 0) errorcode = ERR22;
+
+/* Fill in the terminating state and check for disastrous overflow, but
+if debugging, leave the test till after things are printed out. */
+
+*code++ = OP_END;
+
+#ifndef PCRE_DEBUG
+if (code - codestart > length) errorcode = ERR23;
+#endif
+
+/* Fill in any forward references that are required. There may be repeated
+references; optimize for them, as searching a large regex takes time. */
+
+if (cd->hwm > cd->start_workspace)
+ {
+ int prev_recno = -1;
+ const pcre_uchar *groupptr = NULL;
+ while (errorcode == 0 && cd->hwm > cd->start_workspace)
+ {
+ int offset, recno;
+ cd->hwm -= LINK_SIZE;
+ offset = GET(cd->hwm, 0);
+ recno = GET(codestart, offset);
+ if (recno != prev_recno)
+ {
+ groupptr = PRIV(find_bracket)(codestart, utf, recno);
+ prev_recno = recno;
+ }
+ if (groupptr == NULL) errorcode = ERR53;
+ else PUT(((pcre_uchar *)codestart), offset, (int)(groupptr - codestart));
+ }
+ }
+
+/* If the workspace had to be expanded, free the new memory. */
+
+if (cd->workspace_size > COMPILE_WORK_SIZE)
+ (PUBL(free))((void *)cd->start_workspace);
+
+/* Give an error if there's back reference to a non-existent capturing
+subpattern. */
+
+if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
+
+/* If there were any lookbehind assertions that contained OP_RECURSE
+(recursions or subroutine calls), a flag is set for them to be checked here,
+because they may contain forward references. Actual recursions can't be fixed
+length, but subroutine calls can. It is done like this so that those without
+OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
+exceptional ones forgo this. We scan the pattern to check that they are fixed
+length, and set their lengths. */
+
+if (cd->check_lookbehind)
+ {
+ pcre_uchar *cc = (pcre_uchar *)codestart;
+
+ /* Loop, searching for OP_REVERSE items, and process those that do not have
+ their length set. (Actually, it will also re-process any that have a length
+ of zero, but that is a pathological case, and it does no harm.) When we find
+ one, we temporarily terminate the branch it is in while we scan it. */
+
+ for (cc = (pcre_uchar *)PRIV(find_bracket)(codestart, utf, -1);
+ cc != NULL;
+ cc = (pcre_uchar *)PRIV(find_bracket)(cc, utf, -1))
+ {
+ if (GET(cc, 1) == 0)
+ {
+ int fixed_length;
+ pcre_uchar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
+ int end_op = *be;
+ *be = OP_END;
+ fixed_length = find_fixedlength(cc, (re->options & PCRE_UTF8) != 0, TRUE,
+ cd);
+ *be = end_op;
+ DPRINTF(("fixed length = %d\n", fixed_length));
+ if (fixed_length < 0)
+ {
+ errorcode = (fixed_length == -2)? ERR36 :
+ (fixed_length == -4)? ERR70 : ERR25;
+ break;
+ }
+ PUT(cc, 1, fixed_length);
+ }
+ cc += 1 + LINK_SIZE;
+ }
+ }
+
+/* Failed to compile, or error while post-processing */
+
+if (errorcode != 0)
+ {
+ (PUBL(free))(re);
+ PCRE_EARLY_ERROR_RETURN:
+ *erroroffset = (int)(ptr - (const pcre_uchar *)pattern);
+ PCRE_EARLY_ERROR_RETURN2:
+ *errorptr = find_error_text(errorcode);
+ if (errorcodeptr != NULL) *errorcodeptr = errorcode;
+ return NULL;
+ }
+
+/* If the anchored option was not passed, set the flag if we can determine that
+the pattern is anchored by virtue of ^ characters or \A or anything else (such
+as starting with .* when DOTALL is set).
+
+Otherwise, if we know what the first byte has to be, save it, because that
+speeds up unanchored matches no end. If not, see if we can set the
+PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
+start with ^. and also when all branches start with .* for non-DOTALL matches.
+*/
+
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ if (is_anchored(codestart, 0, cd->backref_map))
+ re->options |= PCRE_ANCHORED;
+ else
+ {
+ if (firstchar < 0)
+ firstchar = find_firstassertedchar(codestart, FALSE);
+ if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */
+ {
+#ifdef COMPILE_PCRE8
+ re->first_char = firstchar & 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ re->first_char = firstchar & 0xffff;
+#endif
+#endif
+ if ((firstchar & REQ_CASELESS) != 0)
+ {
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ /* We ignore non-ASCII first chars in 8 bit mode. */
+ if (utf)
+ {
+ if (re->first_char < 128)
+ {
+ if (cd->fcc[re->first_char] != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+ else if (UCD_OTHERCASE(re->first_char) != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+ else
+#endif
+ if (MAX_255(re->first_char)
+ && cd->fcc[re->first_char] != re->first_char)
+ re->flags |= PCRE_FCH_CASELESS;
+ }
+
+ re->flags |= PCRE_FIRSTSET;
+ }
+ else if (is_startline(codestart, 0, cd->backref_map))
+ re->flags |= PCRE_STARTLINE;
+ }
+ }
+
+/* For an anchored pattern, we use the "required byte" only if it follows a
+variable length item in the regex. Remove the caseless flag for non-caseable
+bytes. */
+
+if (reqchar >= 0 &&
+ ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0))
+ {
+#ifdef COMPILE_PCRE8
+ re->req_char = reqchar & 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ re->req_char = reqchar & 0xffff;
+#endif
+#endif
+ if ((reqchar & REQ_CASELESS) != 0)
+ {
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ /* We ignore non-ASCII first chars in 8 bit mode. */
+ if (utf)
+ {
+ if (re->req_char < 128)
+ {
+ if (cd->fcc[re->req_char] != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+ else if (UCD_OTHERCASE(re->req_char) != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+ else
+#endif
+ if (MAX_255(re->req_char) && cd->fcc[re->req_char] != re->req_char)
+ re->flags |= PCRE_RCH_CASELESS;
+ }
+
+ re->flags |= PCRE_REQCHSET;
+ }
+
+/* Print out the compiled data if debugging is enabled. This is never the
+case when building a production library. */
+
+#ifdef PCRE_DEBUG
+printf("Length = %d top_bracket = %d top_backref = %d\n",
+ length, re->top_bracket, re->top_backref);
+
+printf("Options=%08x\n", re->options);
+
+if ((re->flags & PCRE_FIRSTSET) != 0)
+ {
+ pcre_uchar ch = re->first_char;
+ const char *caseless =
+ ((re->flags & PCRE_FCH_CASELESS) == 0)? "" : " (caseless)";
+ if (PRINTABLE(ch)) printf("First char = %c%s\n", ch, caseless);
+ else printf("First char = \\x%02x%s\n", ch, caseless);
+ }
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+ {
+ pcre_uchar ch = re->req_char;
+ const char *caseless =
+ ((re->flags & PCRE_RCH_CASELESS) == 0)? "" : " (caseless)";
+ if (PRINTABLE(ch)) printf("Req char = %c%s\n", ch, caseless);
+ else printf("Req char = \\x%02x%s\n", ch, caseless);
+ }
+
+#ifdef COMPILE_PCRE8
+pcre_printint((pcre *)re, stdout, TRUE);
+#else
+pcre16_printint((pcre *)re, stdout, TRUE);
+#endif
+
+/* This check is done here in the debugging case so that the code that
+was compiled can be seen. */
+
+if (code - codestart > length)
+ {
+ (PUBL(free))(re);
+ *errorptr = find_error_text(ERR23);
+ *erroroffset = ptr - (pcre_uchar *)pattern;
+ if (errorcodeptr != NULL) *errorcodeptr = ERR23;
+ return NULL;
+ }
+#endif /* PCRE_DEBUG */
+
+#ifdef COMPILE_PCRE8
+return (pcre *)re;
+#else
+return (pcre16 *)re;
+#endif
+}
+
+/* End of pcre_compile.c */
diff --git a/src/3rdparty/pcre/pcre_config.c b/src/3rdparty/pcre/pcre_config.c
new file mode 100644
index 00000000000..6ebafaf06a9
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_config.c
@@ -0,0 +1,170 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_config(). */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Keep the original link size. */
+static int real_link_size = LINK_SIZE;
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return info about what features are configured *
+*************************************************/
+
+/* This function has an extensible interface so that additional items can be
+added compatibly.
+
+Arguments:
+ what what information is required
+ where where to put the information
+
+Returns: 0 if data returned, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_config(int what, void *where)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_config(int what, void *where)
+#endif
+{
+switch (what)
+ {
+ case PCRE_CONFIG_UTF8:
+#if defined COMPILE_PCRE16
+ *((int *)where) = 0;
+ return PCRE_ERROR_BADOPTION;
+#else
+#if defined SUPPORT_UTF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+#endif
+
+ case PCRE_CONFIG_UTF16:
+#if defined COMPILE_PCRE8
+ *((int *)where) = 0;
+ return PCRE_ERROR_BADOPTION;
+#else
+#if defined SUPPORT_UTF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+#endif
+
+ case PCRE_CONFIG_UNICODE_PROPERTIES:
+#ifdef SUPPORT_UCP
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_JIT:
+#ifdef SUPPORT_JIT
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_JITTARGET:
+#ifdef SUPPORT_JIT
+ *((const char **)where) = PRIV(jit_get_target)();
+#else
+ *((const char **)where) = NULL;
+#endif
+ break;
+
+ case PCRE_CONFIG_NEWLINE:
+ *((int *)where) = NEWLINE;
+ break;
+
+ case PCRE_CONFIG_BSR:
+#ifdef BSR_ANYCRLF
+ *((int *)where) = 1;
+#else
+ *((int *)where) = 0;
+#endif
+ break;
+
+ case PCRE_CONFIG_LINK_SIZE:
+ *((int *)where) = real_link_size;
+ break;
+
+ case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
+ *((int *)where) = POSIX_MALLOC_THRESHOLD;
+ break;
+
+ case PCRE_CONFIG_MATCH_LIMIT:
+ *((unsigned long int *)where) = MATCH_LIMIT;
+ break;
+
+ case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
+ *((unsigned long int *)where) = MATCH_LIMIT_RECURSION;
+ break;
+
+ case PCRE_CONFIG_STACKRECURSE:
+#ifdef NO_RECURSE
+ *((int *)where) = 0;
+#else
+ *((int *)where) = 1;
+#endif
+ break;
+
+ default: return PCRE_ERROR_BADOPTION;
+ }
+
+return 0;
+}
+
+/* End of pcre_config.c */
diff --git a/src/3rdparty/pcre/pcre_dfa_exec.c b/src/3rdparty/pcre/pcre_dfa_exec.c
new file mode 100644
index 00000000000..bc89c0de416
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_dfa_exec.c
@@ -0,0 +1,3490 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language (but see
+below for why this module is different).
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_dfa_exec(), which is an
+alternative matching function that uses a sort of DFA algorithm (not a true
+FSM). This is NOT Perl- compatible, but it has advantages in certain
+applications. */
+
+
+/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved
+the performance of his patterns greatly. I could not use it as it stood, as it
+was not thread safe, and made assumptions about pattern sizes. Also, it caused
+test 7 to loop, and test 9 to crash with a segfault.
+
+The issue is the check for duplicate states, which is done by a simple linear
+search up the state list. (Grep for "duplicate" below to find the code.) For
+many patterns, there will never be many states active at one time, so a simple
+linear search is fine. In patterns that have many active states, it might be a
+bottleneck. The suggested code used an indexing scheme to remember which states
+had previously been used for each character, and avoided the linear search when
+it knew there was no chance of a duplicate. This was implemented when adding
+states to the state lists.
+
+I wrote some thread-safe, not-limited code to try something similar at the time
+of checking for duplicates (instead of when adding states), using index vectors
+on the stack. It did give a 13% improvement with one specially constructed
+pattern for certain subject strings, but on other strings and on many of the
+simpler patterns in the test suite it did worse. The major problem, I think,
+was the extra time to initialize the index. This had to be done for each call
+of internal_dfa_exec(). (The supplied patch used a static vector, initialized
+only once - I suspect this was the cause of the problems with the tests.)
+
+Overall, I concluded that the gains in some cases did not outweigh the losses
+in others, so I abandoned this code. */
+
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK md /* Block containing newline information */
+#define PSSTART start_subject /* Field containing processed string start */
+#define PSEND end_subject /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+
+/* For use to indent debugging output */
+
+#define SP " "
+
+
+/*************************************************
+* Code parameters and static tables *
+*************************************************/
+
+/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
+into others, under special conditions. A gap of 20 between the blocks should be
+enough. The resulting opcodes don't have to be less than 256 because they are
+never stored, so we push them well clear of the normal opcodes. */
+
+#define OP_PROP_EXTRA 300
+#define OP_EXTUNI_EXTRA 320
+#define OP_ANYNL_EXTRA 340
+#define OP_HSPACE_EXTRA 360
+#define OP_VSPACE_EXTRA 380
+
+
+/* This table identifies those opcodes that are followed immediately by a
+character that is to be tested in some way. This makes it possible to
+centralize the loading of these characters. In the case of Type * etc, the
+"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
+small value. Non-zero values in the table are the offsets from the opcode where
+the character is to be found. ***NOTE*** If the start of this table is
+modified, the three tables that follow must also be modified. */
+
+static const pcre_uint8 coptable[] = {
+ 0, /* End */
+ 0, 0, 0, 0, 0, /* \A, \G, \K, \B, \b */
+ 0, 0, 0, 0, 0, 0, /* \D, \d, \S, \s, \W, \w */
+ 0, 0, 0, /* Any, AllAny, Anybyte */
+ 0, 0, /* \P, \p */
+ 0, 0, 0, 0, 0, /* \R, \H, \h, \V, \v */
+ 0, /* \X */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
+ 1, /* Char */
+ 1, /* Chari */
+ 1, /* not */
+ 1, /* noti */
+ /* Positive single-char repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto, minupto */
+ 1+IMM2_SIZE, /* exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* upto I, minupto I */
+ 1+IMM2_SIZE, /* exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */
+ /* Negative single-char repeats - only for chars < 256 */
+ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto, minupto */
+ 1+IMM2_SIZE, /* NOT exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* NOT upto I, minupto I */
+ 1+IMM2_SIZE, /* NOT exact I */
+ 1, 1, 1, 1+IMM2_SIZE, /* NOT *+I, ++I, ?+I, upto+I */
+ /* Positive type repeats */
+ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* Type upto, minupto */
+ 1+IMM2_SIZE, /* Type exact */
+ 1, 1, 1, 1+IMM2_SIZE, /* Type *+, ++, ?+, upto+ */
+ /* Character class & ref repeats */
+ 0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
+ 0, 0, /* CRRANGE, CRMINRANGE */
+ 0, /* CLASS */
+ 0, /* NCLASS */
+ 0, /* XCLASS - variable length */
+ 0, /* REF */
+ 0, /* REFI */
+ 0, /* RECURSE */
+ 0, /* CALLOUT */
+ 0, /* Alt */
+ 0, /* Ket */
+ 0, /* KetRmax */
+ 0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
+ 0, /* Assert */
+ 0, /* Assert not */
+ 0, /* Assert behind */
+ 0, /* Assert behind not */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
+ 0, 0, /* CREF, NCREF */
+ 0, 0, /* RREF, NRREF */
+ 0, /* DEF */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0 /* CLOSE, SKIPZERO */
+};
+
+/* This table identifies those opcodes that inspect a character. It is used to
+remember the fact that a character could have been inspected when the end of
+the subject is reached. ***NOTE*** If the start of this table is modified, the
+two tables that follow must also be modified. */
+
+static const pcre_uint8 poptable[] = {
+ 0, /* End */
+ 0, 0, 0, 1, 1, /* \A, \G, \K, \B, \b */
+ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */
+ 1, 1, 1, /* Any, AllAny, Anybyte */
+ 1, 1, /* \P, \p */
+ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */
+ 1, /* \X */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, ^, ^M, $, $M */
+ 1, /* Char */
+ 1, /* Chari */
+ 1, /* not */
+ 1, /* noti */
+ /* Positive single-char repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* upto, minupto, exact */
+ 1, 1, 1, 1, /* *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* *+I, ++I, ?+I, upto+I */
+ /* Negative single-char repeats - only for chars < 256 */
+ 1, 1, 1, 1, 1, 1, /* NOT *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* NOT upto, minupto, exact */
+ 1, 1, 1, 1, /* NOT *+, ++, ?+, upto+ */
+ 1, 1, 1, 1, 1, 1, /* NOT *I, *?I, +I, +?I, ?I, ??I */
+ 1, 1, 1, /* NOT upto I, minupto I, exact I */
+ 1, 1, 1, 1, /* NOT *+I, ++I, ?+I, upto+I */
+ /* Positive type repeats */
+ 1, 1, 1, 1, 1, 1, /* Type *, *?, +, +?, ?, ?? */
+ 1, 1, 1, /* Type upto, minupto, exact */
+ 1, 1, 1, 1, /* Type *+, ++, ?+, upto+ */
+ /* Character class & ref repeats */
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
+ 1, 1, /* CRRANGE, CRMINRANGE */
+ 1, /* CLASS */
+ 1, /* NCLASS */
+ 1, /* XCLASS - variable length */
+ 0, /* REF */
+ 0, /* REFI */
+ 0, /* RECURSE */
+ 0, /* CALLOUT */
+ 0, /* Alt */
+ 0, /* Ket */
+ 0, /* KetRmax */
+ 0, /* KetRmin */
+ 0, /* KetRpos */
+ 0, /* Reverse */
+ 0, /* Assert */
+ 0, /* Assert not */
+ 0, /* Assert behind */
+ 0, /* Assert behind not */
+ 0, 0, /* ONCE, ONCE_NC */
+ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
+ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */
+ 0, 0, /* CREF, NCREF */
+ 0, 0, /* RREF, NRREF */
+ 0, /* DEF */
+ 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
+ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
+ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
+ 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */
+ 0, 0 /* CLOSE, SKIPZERO */
+};
+
+/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
+and \w */
+
+static const pcre_uint8 toptable1[] = {
+ 0, 0, 0, 0, 0, 0,
+ ctype_digit, ctype_digit,
+ ctype_space, ctype_space,
+ ctype_word, ctype_word,
+ 0, 0 /* OP_ANY, OP_ALLANY */
+};
+
+static const pcre_uint8 toptable2[] = {
+ 0, 0, 0, 0, 0, 0,
+ ctype_digit, 0,
+ ctype_space, 0,
+ ctype_word, 0,
+ 1, 1 /* OP_ANY, OP_ALLANY */
+};
+
+
+/* Structure for holding data about a particular state, which is in effect the
+current data for an active path through the match tree. It must consist
+entirely of ints because the working vector we are passed, and which we put
+these structures in, is a vector of ints. */
+
+typedef struct stateblock {
+ int offset; /* Offset to opcode */
+ int count; /* Count for repeats */
+ int data; /* Some use extra data */
+} stateblock;
+
+#define INTS_PER_STATEBLOCK (sizeof(stateblock)/sizeof(int))
+
+
+#ifdef PCRE_DEBUG
+/*************************************************
+* Print character string *
+*************************************************/
+
+/* Character string printing function for debugging.
+
+Arguments:
+ p points to string
+ length number of bytes
+ f where to print
+
+Returns: nothing
+*/
+
+static void
+pchars(const pcre_uchar *p, int length, FILE *f)
+{
+int c;
+while (length-- > 0)
+ {
+ if (isprint(c = *(p++)))
+ fprintf(f, "%c", c);
+ else
+ fprintf(f, "\\x%02x", c);
+ }
+}
+#endif
+
+
+
+/*************************************************
+* Execute a Regular Expression - DFA engine *
+*************************************************/
+
+/* This internal function applies a compiled pattern to a subject string,
+starting at a given point, using a DFA engine. This function is called from the
+external one, possibly multiple times if the pattern is not anchored. The
+function calls itself recursively for some kinds of subpattern.
+
+Arguments:
+ md the match_data block with fixed information
+ this_start_code the opening bracket of this subexpression's code
+ current_subject where we currently are in the subject string
+ start_offset start offset in the subject string
+ offsets vector to contain the matching string offsets
+ offsetcount size of same
+ workspace vector of workspace
+ wscount size of same
+ rlevel function call recursion level
+
+Returns: > 0 => number of match offset pairs placed in offsets
+ = 0 => offsets overflowed; longest matches are present
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+
+The following macros are used for adding states to the two state vectors (one
+for the current character, one for the following character). */
+
+#define ADD_ACTIVE(x,y) \
+ if (active_count++ < wscount) \
+ { \
+ next_active_state->offset = (x); \
+ next_active_state->count = (y); \
+ next_active_state++; \
+ DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_ACTIVE_DATA(x,y,z) \
+ if (active_count++ < wscount) \
+ { \
+ next_active_state->offset = (x); \
+ next_active_state->count = (y); \
+ next_active_state->data = (z); \
+ next_active_state++; \
+ DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_NEW(x,y) \
+ if (new_count++ < wscount) \
+ { \
+ next_new_state->offset = (x); \
+ next_new_state->count = (y); \
+ next_new_state++; \
+ DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_NEW_DATA(x,y,z) \
+ if (new_count++ < wscount) \
+ { \
+ next_new_state->offset = (x); \
+ next_new_state->count = (y); \
+ next_new_state->data = (z); \
+ next_new_state++; \
+ DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+ } \
+ else return PCRE_ERROR_DFA_WSSIZE
+
+/* And now, here is the code */
+
+static int
+internal_dfa_exec(
+ dfa_match_data *md,
+ const pcre_uchar *this_start_code,
+ const pcre_uchar *current_subject,
+ int start_offset,
+ int *offsets,
+ int offsetcount,
+ int *workspace,
+ int wscount,
+ int rlevel)
+{
+stateblock *active_states, *new_states, *temp_states;
+stateblock *next_active_state, *next_new_state;
+
+const pcre_uint8 *ctypes, *lcc, *fcc;
+const pcre_uchar *ptr;
+const pcre_uchar *end_code, *first_op;
+
+dfa_recursion_info new_recursive;
+
+int active_count, new_count, match_count;
+
+/* Some fields in the md block are frequently referenced, so we load them into
+independent variables in the hope that this will perform better. */
+
+const pcre_uchar *start_subject = md->start_subject;
+const pcre_uchar *end_subject = md->end_subject;
+const pcre_uchar *start_code = md->start_code;
+
+#ifdef SUPPORT_UTF
+BOOL utf = (md->poptions & PCRE_UTF8) != 0;
+#else
+BOOL utf = FALSE;
+#endif
+
+rlevel++;
+offsetcount &= (-2);
+
+wscount -= 2;
+wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
+ (2 * INTS_PER_STATEBLOCK);
+
+DPRINTF(("\n%.*s---------------------\n"
+ "%.*sCall to internal_dfa_exec f=%d\n",
+ rlevel*2-2, SP, rlevel*2-2, SP, rlevel));
+
+ctypes = md->tables + ctypes_offset;
+lcc = md->tables + lcc_offset;
+fcc = md->tables + fcc_offset;
+
+match_count = PCRE_ERROR_NOMATCH; /* A negative number */
+
+active_states = (stateblock *)(workspace + 2);
+next_new_state = new_states = active_states + wscount;
+new_count = 0;
+
+first_op = this_start_code + 1 + LINK_SIZE +
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
+
+/* The first thing in any (sub) pattern is a bracket of some sort. Push all
+the alternative states onto the list, and find out where the end is. This
+makes is possible to use this function recursively, when we want to stop at a
+matching internal ket rather than at the end.
+
+If the first opcode in the first alternative is OP_REVERSE, we are dealing with
+a backward assertion. In that case, we have to find out the maximum amount to
+move back, and set up each alternative appropriately. */
+
+if (*first_op == OP_REVERSE)
+ {
+ int max_back = 0;
+ int gone_back;
+
+ end_code = this_start_code;
+ do
+ {
+ int back = GET(end_code, 2+LINK_SIZE);
+ if (back > max_back) max_back = back;
+ end_code += GET(end_code, 1);
+ }
+ while (*end_code == OP_ALT);
+
+ /* If we can't go back the amount required for the longest lookbehind
+ pattern, go back as far as we can; some alternatives may still be viable. */
+
+#ifdef SUPPORT_UTF
+ /* In character mode we have to step back character by character */
+
+ if (utf)
+ {
+ for (gone_back = 0; gone_back < max_back; gone_back++)
+ {
+ if (current_subject <= start_subject) break;
+ current_subject--;
+ ACROSSCHAR(current_subject > start_subject, *current_subject, current_subject--);
+ }
+ }
+ else
+#endif
+
+ /* In byte-mode we can do this quickly. */
+
+ {
+ gone_back = (current_subject - max_back < start_subject)?
+ (int)(current_subject - start_subject) : max_back;
+ current_subject -= gone_back;
+ }
+
+ /* Save the earliest consulted character */
+
+ if (current_subject < md->start_used_ptr)
+ md->start_used_ptr = current_subject;
+
+ /* Now we can process the individual branches. */
+
+ end_code = this_start_code;
+ do
+ {
+ int back = GET(end_code, 2+LINK_SIZE);
+ if (back <= gone_back)
+ {
+ int bstate = (int)(end_code - start_code + 2 + 2*LINK_SIZE);
+ ADD_NEW_DATA(-bstate, 0, gone_back - back);
+ }
+ end_code += GET(end_code, 1);
+ }
+ while (*end_code == OP_ALT);
+ }
+
+/* This is the code for a "normal" subpattern (not a backward assertion). The
+start of a whole pattern is always one of these. If we are at the top level,
+we may be asked to restart matching from the same point that we reached for a
+previous partial match. We still have to scan through the top-level branches to
+find the end state. */
+
+else
+ {
+ end_code = this_start_code;
+
+ /* Restarting */
+
+ if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0)
+ {
+ do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
+ new_count = workspace[1];
+ if (!workspace[0])
+ memcpy(new_states, active_states, new_count * sizeof(stateblock));
+ }
+
+ /* Not restarting */
+
+ else
+ {
+ int length = 1 + LINK_SIZE +
+ ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA ||
+ *this_start_code == OP_CBRAPOS || *this_start_code == OP_SCBRAPOS)
+ ? IMM2_SIZE:0);
+ do
+ {
+ ADD_NEW((int)(end_code - start_code + length), 0);
+ end_code += GET(end_code, 1);
+ length = 1 + LINK_SIZE;
+ }
+ while (*end_code == OP_ALT);
+ }
+ }
+
+workspace[0] = 0; /* Bit indicating which vector is current */
+
+DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, (int)(end_code - start_code)));
+
+/* Loop for scanning the subject */
+
+ptr = current_subject;
+for (;;)
+ {
+ int i, j;
+ int clen, dlen;
+ unsigned int c, d;
+ int forced_fail = 0;
+ BOOL could_continue = FALSE;
+
+ /* Make the new state list into the active state list and empty the
+ new state list. */
+
+ temp_states = active_states;
+ active_states = new_states;
+ new_states = temp_states;
+ active_count = new_count;
+ new_count = 0;
+
+ workspace[0] ^= 1; /* Remember for the restarting feature */
+ workspace[1] = active_count;
+
+#ifdef PCRE_DEBUG
+ printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
+ pchars(ptr, STRLEN_UC(ptr), stdout);
+ printf("\"\n");
+
+ printf("%.*sActive states: ", rlevel*2-2, SP);
+ for (i = 0; i < active_count; i++)
+ printf("%d/%d ", active_states[i].offset, active_states[i].count);
+ printf("\n");
+#endif
+
+ /* Set the pointers for adding new states */
+
+ next_active_state = active_states + active_count;
+ next_new_state = new_states;
+
+ /* Load the current character from the subject outside the loop, as many
+ different states may want to look at it, and we assume that at least one
+ will. */
+
+ if (ptr < end_subject)
+ {
+ clen = 1; /* Number of bytes in the character */
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARLEN(c, ptr, clen); } else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
+ }
+ else
+ {
+ clen = 0; /* This indicates the end of the subject */
+ c = NOTACHAR; /* This value should never actually be used */
+ }
+
+ /* Scan up the active states and act on each one. The result of an action
+ may be to add more states to the currently active list (e.g. on hitting a
+ parenthesis) or it may be to put states on the new list, for considering
+ when we move the character pointer on. */
+
+ for (i = 0; i < active_count; i++)
+ {
+ stateblock *current_state = active_states + i;
+ BOOL caseless = FALSE;
+ const pcre_uchar *code;
+ int state_offset = current_state->offset;
+ int count, codevalue, rrc;
+
+#ifdef PCRE_DEBUG
+ printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
+ if (clen == 0) printf("EOL\n");
+ else if (c > 32 && c < 127) printf("'%c'\n", c);
+ else printf("0x%02x\n", c);
+#endif
+
+ /* A negative offset is a special case meaning "hold off going to this
+ (negated) state until the number of characters in the data field have
+ been skipped". */
+
+ if (state_offset < 0)
+ {
+ if (current_state->data > 0)
+ {
+ DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
+ ADD_NEW_DATA(state_offset, current_state->count,
+ current_state->data - 1);
+ continue;
+ }
+ else
+ {
+ current_state->offset = state_offset = -state_offset;
+ }
+ }
+
+ /* Check for a duplicate state with the same count, and skip if found.
+ See the note at the head of this module about the possibility of improving
+ performance here. */
+
+ for (j = 0; j < i; j++)
+ {
+ if (active_states[j].offset == state_offset &&
+ active_states[j].count == current_state->count)
+ {
+ DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP));
+ goto NEXT_ACTIVE_STATE;
+ }
+ }
+
+ /* The state offset is the offset to the opcode */
+
+ code = start_code + state_offset;
+ codevalue = *code;
+
+ /* If this opcode inspects a character, but we are at the end of the
+ subject, remember the fact for use when testing for a partial match. */
+
+ if (clen == 0 && poptable[codevalue] != 0)
+ could_continue = TRUE;
+
+ /* If this opcode is followed by an inline character, load it. It is
+ tempting to test for the presence of a subject character here, but that
+ is wrong, because sometimes zero repetitions of the subject are
+ permitted.
+
+ We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
+ argument that is not a data character - but is always one byte long. We
+ have to take special action to deal with \P, \p, \H, \h, \V, \v and \X in
+ this case. To keep the other cases fast, convert these ones to new opcodes.
+ */
+
+ if (coptable[codevalue] > 0)
+ {
+ dlen = 1;
+#ifdef SUPPORT_UTF
+ if (utf) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
+#endif /* SUPPORT_UTF */
+ d = code[coptable[codevalue]];
+ if (codevalue >= OP_TYPESTAR)
+ {
+ switch(d)
+ {
+ case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM;
+ case OP_NOTPROP:
+ case OP_PROP: codevalue += OP_PROP_EXTRA; break;
+ case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
+ case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
+ case OP_NOT_HSPACE:
+ case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
+ case OP_NOT_VSPACE:
+ case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
+ default: break;
+ }
+ }
+ }
+ else
+ {
+ dlen = 0; /* Not strictly necessary, but compilers moan */
+ d = NOTACHAR; /* if these variables are not set. */
+ }
+
+
+ /* Now process the individual opcodes */
+
+ switch (codevalue)
+ {
+/* ========================================================================== */
+ /* These cases are never obeyed. This is a fudge that causes a compile-
+ time error if the vectors coptable or poptable, which are indexed by
+ opcode, are not the correct length. It seems to be the only way to do
+ such a check at compile time, as the sizeof() operator does not work
+ in the C preprocessor. */
+
+ case OP_TABLE_LENGTH:
+ case OP_TABLE_LENGTH +
+ ((sizeof(coptable) == OP_TABLE_LENGTH) &&
+ (sizeof(poptable) == OP_TABLE_LENGTH)):
+ break;
+
+/* ========================================================================== */
+ /* Reached a closing bracket. If not at the end of the pattern, carry
+ on with the next opcode. For repeating opcodes, also add the repeat
+ state. Note that KETRPOS will always be encountered at the end of the
+ subpattern, because the possessive subpattern repeats are always handled
+ using recursive calls. Thus, it never adds any new states.
+
+ At the end of the (sub)pattern, unless we have an empty string and
+ PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
+ start of the subject, save the match data, shifting up all previous
+ matches so we always have the longest first. */
+
+ case OP_KET:
+ case OP_KETRMIN:
+ case OP_KETRMAX:
+ case OP_KETRPOS:
+ if (code != end_code)
+ {
+ ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
+ if (codevalue != OP_KET)
+ {
+ ADD_ACTIVE(state_offset - GET(code, 1), 0);
+ }
+ }
+ else
+ {
+ if (ptr > current_subject ||
+ ((md->moptions & PCRE_NOTEMPTY) == 0 &&
+ ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 ||
+ current_subject > start_subject + md->start_offset)))
+ {
+ if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
+ else if (match_count > 0 && ++match_count * 2 > offsetcount)
+ match_count = 0;
+ count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
+ if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
+ if (offsetcount >= 2)
+ {
+ offsets[0] = (int)(current_subject - start_subject);
+ offsets[1] = (int)(ptr - start_subject);
+ DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
+ offsets[1] - offsets[0], current_subject));
+ }
+ if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
+ {
+ DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
+ "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel,
+ match_count, rlevel*2-2, SP));
+ return match_count;
+ }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These opcodes add to the current list of states without looking
+ at the current character. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_ALT:
+ do { code += GET(code, 1); } while (*code == OP_ALT);
+ ADD_ACTIVE((int)(code - start_code), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRA:
+ case OP_SBRA:
+ do
+ {
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ code += GET(code, 1);
+ }
+ while (*code == OP_ALT);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CBRA:
+ case OP_SCBRA:
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE + IMM2_SIZE), 0);
+ code += GET(code, 1);
+ while (*code == OP_ALT)
+ {
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ code += GET(code, 1);
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ ADD_ACTIVE(state_offset + 1, 0);
+ code += 1 + GET(code, 2);
+ while (*code == OP_ALT) code += GET(code, 1);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SKIPZERO:
+ code += 1 + GET(code, 2);
+ while (*code == OP_ALT) code += GET(code, 1);
+ ADD_ACTIVE((int)(code - start_code + 1 + LINK_SIZE), 0);
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRC:
+ if (ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0)
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CIRCM:
+ if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
+ (ptr != end_subject && WAS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EOD:
+ if (ptr >= end_subject)
+ {
+ if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SOD:
+ if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_SOM:
+ if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+
+/* ========================================================================== */
+ /* These opcodes inspect the next subject character, and sometimes
+ the previous one as well, but do not have an argument. The variable
+ clen contains the length of the current character and is zero if we are
+ at the end of the subject. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANY:
+ if (clen > 0 && !IS_NEWLINE(ptr))
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_ALLANY:
+ if (clen > 0)
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EODN:
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLL:
+ if ((md->moptions & PCRE_NOTEOL) == 0)
+ {
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
+ (ptr == end_subject - md->nllen)
+ ))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_DOLLM:
+ if ((md->moptions & PCRE_NOTEOL) == 0)
+ {
+ if (clen == 0 && (md->moptions & PCRE_PARTIAL_HARD) != 0)
+ could_continue = TRUE;
+ else if (clen == 0 ||
+ ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ else if (IS_NEWLINE(ptr))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+
+ case OP_DIGIT:
+ case OP_WHITESPACE:
+ case OP_WORDCHAR:
+ if (clen > 0 && c < 256 &&
+ ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ if (clen > 0 && (c >= 256 ||
+ ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
+ { ADD_NEW(state_offset + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ {
+ int left_word, right_word;
+
+ if (ptr > start_subject)
+ {
+ const pcre_uchar *temp = ptr - 1;
+ if (temp < md->start_used_ptr) md->start_used_ptr = temp;
+#ifdef SUPPORT_UTF
+ if (utf) { BACKCHAR(temp); }
+#endif
+ GETCHARTEST(d, temp);
+#ifdef SUPPORT_UCP
+ if ((md->poptions & PCRE_UCP) != 0)
+ {
+ if (d == '_') left_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(d);
+ left_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
+ }
+ else left_word = FALSE;
+
+ if (clen > 0)
+ {
+#ifdef SUPPORT_UCP
+ if ((md->poptions & PCRE_UCP) != 0)
+ {
+ if (c == '_') right_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ right_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
+ }
+ else right_word = FALSE;
+
+ if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
+ { ADD_ACTIVE(state_offset + 1, 0); }
+ }
+ break;
+
+
+ /*-----------------------------------------------------------------*/
+ /* Check the next character by Unicode property. We will get here only
+ if the support is in the binary; otherwise a compile-time error occurs.
+ */
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[1])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[2];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[2];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[2];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
+ }
+ break;
+#endif
+
+
+
+/* ========================================================================== */
+ /* These opcodes likewise inspect the subject character, but have an
+ argument that is not a data character. It is one of these opcodes:
+ OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
+ OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (count > 0 && codevalue == OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + 2, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEEXACT:
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0);
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+ (c < 256 &&
+ (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+ ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+ {
+ if (codevalue == OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These are virtual opcodes that are used when something like
+ OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
+ argument. It keeps the code above fast for the other cases. The argument
+ is in the d variable. */
+
+#ifdef SUPPORT_UCP
+ case OP_PROP_EXTRA + OP_TYPEPLUS:
+ case OP_PROP_EXTRA + OP_TYPEMINPLUS:
+ case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[2])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[3];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[3];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ while (nptr < end_subject)
+ {
+ int nd;
+ int ndlen = 1;
+ GETCHARLEN(nd, nptr, ndlen);
+ if (UCD_CATEGORY(nd) != ucp_M) break;
+ ncount++;
+ nptr += ndlen;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEPLUS:
+ case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+ goto ANYNL01;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+ /* Fall through */
+
+ ANYNL01:
+ case 0x000a:
+ if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, ncount);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEPLUS:
+ case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_VSPACE))
+ {
+ if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEPLUS:
+ case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW_DATA(-state_offset, count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UCP
+ case OP_PROP_EXTRA + OP_TYPEQUERY:
+ case OP_PROP_EXTRA + OP_TYPEMINQUERY:
+ case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
+ count = 4;
+ goto QS1;
+
+ case OP_PROP_EXTRA + OP_TYPESTAR:
+ case OP_PROP_EXTRA + OP_TYPEMINSTAR:
+ case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS1:
+
+ ADD_ACTIVE(state_offset + 4, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[2])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[3];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[3];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[3];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + count, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS2;
+
+ case OP_EXTUNI_EXTRA + OP_TYPESTAR:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS2:
+
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ while (nptr < end_subject)
+ {
+ int nd;
+ int ndlen = 1;
+ GETCHARLEN(nd, nptr, ndlen);
+ if (UCD_CATEGORY(nd) != ucp_M) break;
+ ncount++;
+ nptr += ndlen;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEQUERY:
+ case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS3;
+
+ case OP_ANYNL_EXTRA + OP_TYPESTAR:
+ case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS3:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+ goto ANYNL02;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+ /* Fall through */
+
+ ANYNL02:
+ case 0x000a:
+ if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEQUERY:
+ case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS4;
+
+ case OP_VSPACE_EXTRA + OP_TYPESTAR:
+ case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS4:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+ if (OK == (d == OP_VSPACE))
+ {
+ if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEQUERY:
+ case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
+ count = 2;
+ goto QS5;
+
+ case OP_HSPACE_EXTRA + OP_TYPESTAR:
+ case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
+ count = 0;
+
+ QS5:
+ ADD_ACTIVE(state_offset + 2, 0);
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
+ codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW_DATA(-(state_offset + count), 0, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UCP
+ case OP_PROP_EXTRA + OP_TYPEEXACT:
+ case OP_PROP_EXTRA + OP_TYPEUPTO:
+ case OP_PROP_EXTRA + OP_TYPEMINUPTO:
+ case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 1 + IMM2_SIZE + 3, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ const ucd_record * prop = GET_UCD(c);
+ switch(code[1 + IMM2_SIZE + 1])
+ {
+ case PT_ANY:
+ OK = TRUE;
+ break;
+
+ case PT_LAMP:
+ OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt;
+ break;
+
+ case PT_GC:
+ OK = PRIV(ucp_gentype)[prop->chartype] == code[1 + IMM2_SIZE + 2];
+ break;
+
+ case PT_PC:
+ OK = prop->chartype == code[1 + IMM2_SIZE + 2];
+ break;
+
+ case PT_SC:
+ OK = prop->script == code[1 + IMM2_SIZE + 2];
+ break;
+
+ /* These are specials for combination cases. */
+
+ case PT_ALNUM:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR;
+ break;
+
+ case PT_WORD:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE;
+ break;
+
+ /* Should never occur, but keep compilers from grumbling. */
+
+ default:
+ OK = codevalue != OP_PROP;
+ break;
+ }
+
+ if (OK == (d == OP_PROP))
+ {
+ if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
+ case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
+ case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
+ case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ while (nptr < end_subject)
+ {
+ int nd;
+ int ndlen = 1;
+ GETCHARLEN(nd, nptr, ndlen);
+ if (UCD_CATEGORY(nd) != ucp_M) break;
+ ncount++;
+ nptr += ndlen;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, ncount); }
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ case OP_ANYNL_EXTRA + OP_TYPEEXACT:
+ case OP_ANYNL_EXTRA + OP_TYPEUPTO:
+ case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
+ case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ int ncount = 0;
+ switch (c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+ goto ANYNL03;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+ /* Fall through */
+
+ ANYNL03:
+ case 0x000a:
+ if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, ncount); }
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE_EXTRA + OP_TYPEEXACT:
+ case OP_VSPACE_EXTRA + OP_TYPEUPTO:
+ case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
+ case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ }
+
+ if (OK == (d == OP_VSPACE))
+ {
+ if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, 0); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE_EXTRA + OP_TYPEEXACT:
+ case OP_HSPACE_EXTRA + OP_TYPEUPTO:
+ case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
+ case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
+ if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
+ { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ BOOL OK;
+ switch (c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ OK = TRUE;
+ break;
+
+ default:
+ OK = FALSE;
+ break;
+ }
+
+ if (OK == (d == OP_HSPACE))
+ {
+ if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
+ else
+ { ADD_NEW_DATA(-state_offset, count, 0); }
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These opcodes are followed by a character that is usually compared
+ to the current subject character; it is loaded into d. We still get
+ here even if there is no subject character, because in some cases zero
+ repetitions are permitted. */
+
+ /*-----------------------------------------------------------------*/
+ case OP_CHAR:
+ if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_CHARI:
+ if (clen == 0) break;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
+ {
+ unsigned int othercase;
+ if (c < 128)
+ othercase = fcc[c];
+ else
+ /* If we have Unicode property support, we can use it to test the
+ other case of the character. */
+#ifdef SUPPORT_UCP
+ othercase = UCD_OTHERCASE(c);
+#else
+ othercase = NOTACHAR;
+#endif
+
+ if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ /* Not UTF mode */
+ {
+ if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
+ { ADD_NEW(state_offset + 2, 0); }
+ }
+ break;
+
+
+#ifdef SUPPORT_UCP
+ /*-----------------------------------------------------------------*/
+ /* This is a tricky one because it can match more than one character.
+ Find out how many characters to skip, and then set up a negative state
+ to wait for them to pass before continuing. */
+
+ case OP_EXTUNI:
+ if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+ {
+ const pcre_uchar *nptr = ptr + clen;
+ int ncount = 0;
+ while (nptr < end_subject)
+ {
+ int nclen = 1;
+ GETCHARLEN(c, nptr, nclen);
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ ncount++;
+ nptr += nclen;
+ }
+ ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
+ }
+ break;
+#endif
+
+ /*-----------------------------------------------------------------*/
+ /* This is a tricky like EXTUNI because it too can match more than one
+ character (when CR is followed by LF). In this case, set up a negative
+ state to wait for one character to pass before continuing. */
+
+ case OP_ANYNL:
+ if (clen > 0) switch(c)
+ {
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+
+ case 0x000a:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ case 0x000d:
+ if (ptr + 1 < end_subject && ptr[1] == 0x0a)
+ {
+ ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+ }
+ else
+ {
+ ADD_NEW(state_offset + 1, 0);
+ }
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_VSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ break;
+
+ default:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_VSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x000a:
+ case 0x000b:
+ case 0x000c:
+ case 0x000d:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+
+ default: break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_NOT_HSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+
+ default:
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_HSPACE:
+ if (clen > 0) switch(c)
+ {
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ ADD_NEW(state_offset + 1, 0);
+ break;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character casefully. This is only used for
+ one-byte characters, that is, we know that d < 256. The character we are
+ checking (c) can be multibyte. */
+
+ case OP_NOT:
+ if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ /* Match a negated single character caselessly. This is only used for
+ one-byte characters, that is, we know that d < 256. The character we are
+ checking (c) can be multibyte. */
+
+ case OP_NOTI:
+ if (clen > 0 && c != d && c != fcc[d])
+ { ADD_NEW(state_offset + dlen + 1, 0); }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUSI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+
+ /* Fall through */
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTPOSPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (count > 0 &&
+ (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSQUERYI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSQUERY:
+ ADD_ACTIVE(state_offset + dlen + 1, 0);
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset + dlen + 1, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPOSSTARI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPOSSTAR:
+ ADD_ACTIVE(state_offset + dlen + 1, 0);
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_EXACTI:
+ case OP_NOTEXACTI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_EXACT:
+ case OP_NOTEXACT:
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPOSUPTOI:
+ caseless = TRUE;
+ codevalue -= OP_STARI - OP_STAR;
+ /* Fall through */
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTPOSUPTO:
+ ADD_ACTIVE(state_offset + dlen + 1 + IMM2_SIZE, 0);
+ count = current_state->count; /* Number already matched */
+ if (clen > 0)
+ {
+ unsigned int otherd = NOTACHAR;
+ if (caseless)
+ {
+#ifdef SUPPORT_UTF
+ if (utf && d >= 128)
+ {
+#ifdef SUPPORT_UCP
+ otherd = UCD_OTHERCASE(d);
+#endif /* SUPPORT_UCP */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ otherd = TABLE_GET(d, fcc, d);
+ }
+ if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+ {
+ if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ if (++count >= GET2(code, 1))
+ { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ }
+ break;
+
+
+/* ========================================================================== */
+ /* These are the class-handling opcodes */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+ {
+ BOOL isinclass = FALSE;
+ int next_state_offset;
+ const pcre_uchar *ecode;
+
+ /* For a simple class, there is always just a 32-byte table, and we
+ can set isinclass from it. */
+
+ if (codevalue != OP_XCLASS)
+ {
+ ecode = code + 1 + (32 / sizeof(pcre_uchar));
+ if (clen > 0)
+ {
+ isinclass = (c > 255)? (codevalue == OP_NCLASS) :
+ ((((pcre_uint8 *)(code + 1))[c/8] & (1 << (c&7))) != 0);
+ }
+ }
+
+ /* An extended class may have a table or a list of single characters,
+ ranges, or both, and it may be positive or negative. There's a
+ function that sorts all this out. */
+
+ else
+ {
+ ecode = code + GET(code, 1);
+ if (clen > 0) isinclass = PRIV(xclass)(c, code + 1 + LINK_SIZE, utf);
+ }
+
+ /* At this point, isinclass is set for all kinds of class, and ecode
+ points to the byte after the end of the class. If there is a
+ quantifier, this is where it will be. */
+
+ next_state_offset = (int)(ecode - start_code);
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ ADD_ACTIVE(next_state_offset + 1, 0);
+ if (isinclass) { ADD_NEW(state_offset, 0); }
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ count = current_state->count; /* Already matched */
+ if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
+ if (isinclass) { count++; ADD_NEW(state_offset, count); }
+ break;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ ADD_ACTIVE(next_state_offset + 1, 0);
+ if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ count = current_state->count; /* Already matched */
+ if (count >= GET2(ecode, 1))
+ { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
+ if (isinclass)
+ {
+ int max = GET2(ecode, 1 + IMM2_SIZE);
+ if (++count >= max && max != 0) /* Max 0 => no limit */
+ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
+ else
+ { ADD_NEW(state_offset, count); }
+ }
+ break;
+
+ default:
+ if (isinclass) { ADD_NEW(next_state_offset, 0); }
+ break;
+ }
+ }
+ break;
+
+/* ========================================================================== */
+ /* These are the opcodes for fancy brackets of various kinds. We have
+ to use recursion in order to handle them. The "always failing" assertion
+ (?!) is optimised to OP_FAIL when compiling, so we have to support that,
+ though the other "backtracking verbs" are not supported. */
+
+ case OP_FAIL:
+ forced_fail++; /* Count FAILs for multiple states */
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ {
+ int rc;
+ int local_offsets[2];
+ int local_workspace[1000];
+ const pcre_uchar *endasscode = code + GET(code, 1);
+
+ while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+ rc = internal_dfa_exec(
+ md, /* static match data */
+ code, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc == PCRE_ERROR_DFA_UITEM) return rc;
+ if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
+ { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_COND:
+ case OP_SCOND:
+ {
+ int local_offsets[1000];
+ int local_workspace[1000];
+ int codelink = GET(code, 1);
+ int condcode;
+
+ /* Because of the way auto-callout works during compile, a callout item
+ is inserted between OP_COND and an assertion condition. This does not
+ happen for the other conditions. */
+
+ if (code[LINK_SIZE+1] == OP_CALLOUT)
+ {
+ rrc = 0;
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 1; /* Version 1 of the callout block */
+ cb.callout_number = code[LINK_SIZE+2];
+ cb.offset_vector = offsets;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)start_subject;
+#endif
+ cb.subject_length = (int)(end_subject - start_subject);
+ cb.start_match = (int)(current_subject - start_subject);
+ cb.current_position = (int)(ptr - start_subject);
+ cb.pattern_position = GET(code, LINK_SIZE + 3);
+ cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);
+ cb.capture_top = 1;
+ cb.capture_last = -1;
+ cb.callout_data = md->callout_data;
+ cb.mark = NULL; /* No (*MARK) support */
+ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
+ }
+ if (rrc > 0) break; /* Fail this thread */
+ code += PRIV(OP_lengths)[OP_CALLOUT]; /* Skip callout data */
+ }
+
+ condcode = code[LINK_SIZE+1];
+
+ /* Back reference conditions are not supported */
+
+ if (condcode == OP_CREF || condcode == OP_NCREF)
+ return PCRE_ERROR_DFA_UCOND;
+
+ /* The DEFINE condition is always false */
+
+ if (condcode == OP_DEF)
+ { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+
+ /* The only supported version of OP_RREF is for the value RREF_ANY,
+ which means "test if in any recursion". We can't test for specifically
+ recursed groups. */
+
+ else if (condcode == OP_RREF || condcode == OP_NRREF)
+ {
+ int value = GET2(code, LINK_SIZE + 2);
+ if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
+ if (md->recursive != NULL)
+ { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); }
+ else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+ }
+
+ /* Otherwise, the condition is an assertion */
+
+ else
+ {
+ int rc;
+ const pcre_uchar *asscode = code + LINK_SIZE + 1;
+ const pcre_uchar *endasscode = asscode + GET(asscode, 1);
+
+ while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+ rc = internal_dfa_exec(
+ md, /* fixed match data */
+ asscode, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc == PCRE_ERROR_DFA_UITEM) return rc;
+ if ((rc >= 0) ==
+ (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
+ { ADD_ACTIVE((int)(endasscode + LINK_SIZE + 1 - start_code), 0); }
+ else
+ { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_RECURSE:
+ {
+ dfa_recursion_info *ri;
+ int local_offsets[1000];
+ int local_workspace[1000];
+ const pcre_uchar *callpat = start_code + GET(code, 1);
+ int recno = (callpat == md->start_code)? 0 :
+ GET2(callpat, 1 + LINK_SIZE);
+ int rc;
+
+ DPRINTF(("%.*sStarting regex recursion\n", rlevel*2-2, SP));
+
+ /* Check for repeating a recursion without advancing the subject
+ pointer. This should catch convoluted mutual recursions. (Some simple
+ cases are caught at compile time.) */
+
+ for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && ptr == ri->subject_position)
+ return PCRE_ERROR_RECURSELOOP;
+
+ /* Remember this recursion and where we started it so as to
+ catch infinite loops. */
+
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = ptr;
+ new_recursive.prevrec = md->recursive;
+ md->recursive = &new_recursive;
+
+ rc = internal_dfa_exec(
+ md, /* fixed match data */
+ callpat, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ md->recursive = new_recursive.prevrec; /* Done this recursion */
+
+ DPRINTF(("%.*sReturn from regex recursion: rc=%d\n", rlevel*2-2, SP,
+ rc));
+
+ /* Ran out of internal offsets */
+
+ if (rc == 0) return PCRE_ERROR_DFA_RECURSE;
+
+ /* For each successful matched substring, set up the next state with a
+ count of characters to skip before trying it. Note that the count is in
+ characters, not bytes. */
+
+ if (rc > 0)
+ {
+ for (rc = rc*2 - 2; rc >= 0; rc -= 2)
+ {
+ int charcount = local_offsets[rc+1] - local_offsets[rc];
+#ifdef SUPPORT_UTF
+ const pcre_uchar *p = start_subject + local_offsets[rc];
+ const pcre_uchar *pp = start_subject + local_offsets[rc+1];
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ if (charcount > 0)
+ {
+ ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
+ }
+ else
+ {
+ ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
+ }
+ }
+ }
+ else if (rc != PCRE_ERROR_NOMATCH) return rc;
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ {
+ int charcount, matched_count;
+ const pcre_uchar *local_ptr = ptr;
+ BOOL allow_zero;
+
+ if (codevalue == OP_BRAPOSZERO)
+ {
+ allow_zero = TRUE;
+ codevalue = *(++code); /* Codevalue will be one of above BRAs */
+ }
+ else allow_zero = FALSE;
+
+ /* Loop to match the subpattern as many times as possible as if it were
+ a complete pattern. */
+
+ for (matched_count = 0;; matched_count++)
+ {
+ int local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_exec(
+ md, /* fixed match data */
+ code, /* this subexpression's code */
+ local_ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ /* Failed to match */
+
+ if (rc < 0)
+ {
+ if (rc != PCRE_ERROR_NOMATCH) return rc;
+ break;
+ }
+
+ /* Matched: break the loop if zero characters matched. */
+
+ charcount = local_offsets[1] - local_offsets[0];
+ if (charcount == 0) break;
+ local_ptr += charcount; /* Advance temporary position ptr */
+ }
+
+ /* At this point we have matched the subpattern matched_count
+ times, and local_ptr is pointing to the character after the end of the
+ last match. */
+
+ if (matched_count > 0 || allow_zero)
+ {
+ const pcre_uchar *end_subpattern = code;
+ int next_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr = local_ptr;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+ }
+ else
+ {
+ const pcre_uchar *p = ptr;
+ const pcre_uchar *pp = local_ptr;
+ charcount = (int)(pp - p);
+#ifdef SUPPORT_UTF
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
+ }
+ }
+ }
+ break;
+
+ /*-----------------------------------------------------------------*/
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ {
+ int local_offsets[2];
+ int local_workspace[1000];
+
+ int rc = internal_dfa_exec(
+ md, /* fixed match data */
+ code, /* this subexpression's code */
+ ptr, /* where we currently are */
+ (int)(ptr - start_subject), /* start offset */
+ local_offsets, /* offset vector */
+ sizeof(local_offsets)/sizeof(int), /* size of same */
+ local_workspace, /* workspace vector */
+ sizeof(local_workspace)/sizeof(int), /* size of same */
+ rlevel); /* function recursion level */
+
+ if (rc >= 0)
+ {
+ const pcre_uchar *end_subpattern = code;
+ int charcount = local_offsets[1] - local_offsets[0];
+ int next_state_offset, repeat_state_offset;
+
+ do { end_subpattern += GET(end_subpattern, 1); }
+ while (*end_subpattern == OP_ALT);
+ next_state_offset =
+ (int)(end_subpattern - start_code + LINK_SIZE + 1);
+
+ /* If the end of this subpattern is KETRMAX or KETRMIN, we must
+ arrange for the repeat state also to be added to the relevant list.
+ Calculate the offset, or set -1 for no repeat. */
+
+ repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
+ *end_subpattern == OP_KETRMIN)?
+ (int)(end_subpattern - start_code - GET(end_subpattern, 1)) : -1;
+
+ /* If we have matched an empty string, add the next state at the
+ current character pointer. This is important so that the duplicate
+ checking kicks in, which is what breaks infinite loops that match an
+ empty string. */
+
+ if (charcount == 0)
+ {
+ ADD_ACTIVE(next_state_offset, 0);
+ }
+
+ /* Optimization: if there are no more active states, and there
+ are no new states yet set up, then skip over the subject string
+ right here, to save looping. Otherwise, set up the new state to swing
+ into action when the end of the matched substring is reached. */
+
+ else if (i + 1 >= active_count && new_count == 0)
+ {
+ ptr += charcount;
+ clen = 0;
+ ADD_NEW(next_state_offset, 0);
+
+ /* If we are adding a repeat state at the new character position,
+ we must fudge things so that it is the only current state.
+ Otherwise, it might be a duplicate of one we processed before, and
+ that would cause it to be skipped. */
+
+ if (repeat_state_offset >= 0)
+ {
+ next_active_state = active_states;
+ active_count = 0;
+ i = -1;
+ ADD_ACTIVE(repeat_state_offset, 0);
+ }
+ }
+ else
+ {
+#ifdef SUPPORT_UTF
+ const pcre_uchar *p = start_subject + local_offsets[0];
+ const pcre_uchar *pp = start_subject + local_offsets[1];
+ while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
+#endif
+ ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
+ if (repeat_state_offset >= 0)
+ { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
+ }
+ }
+ else if (rc != PCRE_ERROR_NOMATCH) return rc;
+ }
+ break;
+
+
+/* ========================================================================== */
+ /* Handle callouts */
+
+ case OP_CALLOUT:
+ rrc = 0;
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 1; /* Version 1 of the callout block */
+ cb.callout_number = code[1];
+ cb.offset_vector = offsets;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)start_subject;
+#endif
+ cb.subject_length = (int)(end_subject - start_subject);
+ cb.start_match = (int)(current_subject - start_subject);
+ cb.current_position = (int)(ptr - start_subject);
+ cb.pattern_position = GET(code, 2);
+ cb.next_item_length = GET(code, 2 + LINK_SIZE);
+ cb.capture_top = 1;
+ cb.capture_last = -1;
+ cb.callout_data = md->callout_data;
+ cb.mark = NULL; /* No (*MARK) support */
+ if ((rrc = (*PUBL(callout))(&cb)) < 0) return rrc; /* Abandon */
+ }
+ if (rrc == 0)
+ { ADD_ACTIVE(state_offset + PRIV(OP_lengths)[OP_CALLOUT], 0); }
+ break;
+
+
+/* ========================================================================== */
+ default: /* Unsupported opcode */
+ return PCRE_ERROR_DFA_UITEM;
+ }
+
+ NEXT_ACTIVE_STATE: continue;
+
+ } /* End of loop scanning active states */
+
+ /* We have finished the processing at the current subject character. If no
+ new states have been set for the next character, we have found all the
+ matches that we are going to find. If we are at the top level and partial
+ matching has been requested, check for appropriate conditions.
+
+ The "forced_ fail" variable counts the number of (*F) encountered for the
+ character. If it is equal to the original active_count (saved in
+ workspace[1]) it means that (*F) was found on every active state. In this
+ case we don't want to give a partial match.
+
+ The "could_continue" variable is true if a state could have continued but
+ for the fact that the end of the subject was reached. */
+
+ if (new_count <= 0)
+ {
+ if (rlevel == 1 && /* Top level, and */
+ could_continue && /* Some could go on */
+ forced_fail != workspace[1] && /* Not all forced fail & */
+ ( /* either... */
+ (md->moptions & PCRE_PARTIAL_HARD) != 0 /* Hard partial */
+ || /* or... */
+ ((md->moptions & PCRE_PARTIAL_SOFT) != 0 && /* Soft partial and */
+ match_count < 0) /* no matches */
+ ) && /* And... */
+ ptr >= end_subject && /* Reached end of subject */
+ ptr > md->start_used_ptr) /* Inspected non-empty string */
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = (int)(md->start_used_ptr - start_subject);
+ offsets[1] = (int)(end_subject - start_subject);
+ }
+ match_count = PCRE_ERROR_PARTIAL;
+ }
+
+ DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
+ "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
+ rlevel*2-2, SP));
+ break; /* In effect, "return", but see the comment below */
+ }
+
+ /* One or more states are active for the next character. */
+
+ ptr += clen; /* Advance to next subject character */
+ } /* Loop to move along the subject string */
+
+/* Control gets here from "break" a few lines above. We do it this way because
+if we use "return" above, we have compiler trouble. Some compilers warn if
+there's nothing here because they think the function doesn't return a value. On
+the other hand, if we put a dummy statement here, some more clever compilers
+complain that it can't be reached. Sigh. */
+
+return match_count;
+}
+
+
+
+
+/*************************************************
+* Execute a Regular Expression - DFA engine *
+*************************************************/
+
+/* This external function applies a compiled re to a subject string using a DFA
+engine. This function calls the internal function multiple times if the pattern
+is not anchored.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ offsets vector of match offsets
+ offsetcount size of same
+ workspace workspace vector
+ wscount size of same
+
+Returns: > 0 => number of match offset pairs placed in offsets
+ = 0 => offsets overflowed; longest matches are present
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
+ const char *subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount, int *workspace, int wscount)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount, int *workspace, int wscount)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+dfa_match_data match_block;
+dfa_match_data *md = &match_block;
+BOOL utf, anchored, startline, firstline;
+const pcre_uchar *current_subject, *end_subject;
+const pcre_study_data *study = NULL;
+
+const pcre_uchar *req_char_ptr;
+const pcre_uint8 *start_bits = NULL;
+BOOL has_first_char = FALSE;
+BOOL has_req_char = FALSE;
+pcre_uchar first_char = 0;
+pcre_uchar first_char2 = 0;
+pcre_uchar req_char = 0;
+pcre_uchar req_char2 = 0;
+int newline;
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
+if (re == NULL || subject == NULL || workspace == NULL ||
+ (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
+if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
+if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
+if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
+
+/* We need to find the pointer to any study data before we test for byte
+flipping, so we scan the extra_data block first. This may set two fields in the
+match block, so we must initialize them beforehand. However, the other fields
+in the match block must not be set until after the byte flipping. */
+
+md->tables = re->tables;
+md->callout_data = NULL;
+
+if (extra_data != NULL)
+ {
+ unsigned int flags = extra_data->flags;
+ if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ study = (const pcre_study_data *)extra_data->study_data;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
+ return PCRE_ERROR_DFA_UMLIMIT;
+ if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
+ md->callout_data = extra_data->callout_data;
+ if ((flags & PCRE_EXTRA_TABLES) != 0)
+ md->tables = extra_data->tables;
+ }
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+/* Set some local values */
+
+current_subject = (const pcre_uchar *)subject + start_offset;
+end_subject = (const pcre_uchar *)subject + length;
+req_char_ptr = current_subject - 1;
+
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = (re->options & PCRE_UTF8) != 0;
+#else
+utf = FALSE;
+#endif
+
+anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
+ (re->options & PCRE_ANCHORED) != 0;
+
+/* The remaining fixed data for passing around. */
+
+md->start_code = (const pcre_uchar *)argument_re +
+ re->name_table_offset + re->name_count * re->name_entry_size;
+md->start_subject = (const pcre_uchar *)subject;
+md->end_subject = end_subject;
+md->start_offset = start_offset;
+md->moptions = options;
+md->poptions = re->options;
+
+/* If the BSR option is not set at match time, copy what was set
+at compile time. */
+
+if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0)
+ {
+ if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
+ md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE);
+#ifdef BSR_ANYCRLF
+ else md->moptions |= PCRE_BSR_ANYCRLF;
+#endif
+ }
+
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
+
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
+ PCRE_NEWLINE_BITS)
+ {
+ case 0: newline = NEWLINE; break; /* Compile-time default */
+ case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+ default: return PCRE_ERROR_BADNEWLINE;
+ }
+
+if (newline == -2)
+ {
+ md->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
+ {
+ md->nltype = NLTYPE_ANY;
+ }
+else
+ {
+ md->nltype = NLTYPE_FIXED;
+ if (newline > 255)
+ {
+ md->nllen = 2;
+ md->nl[0] = (newline >> 8) & 255;
+ md->nl[1] = newline & 255;
+ }
+ else
+ {
+ md->nllen = 1;
+ md->nl[0] = newline;
+ }
+ }
+
+/* Check a UTF-8 string if required. Unfortunately there's no way of passing
+back the character offset. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
+ {
+ int erroroffset;
+ int errorcode = PRIV(valid_utf)((pcre_uchar *)subject, length, &erroroffset);
+ if (errorcode != 0)
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = erroroffset;
+ offsets[1] = errorcode;
+ }
+ return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?
+ PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
+ }
+ if (start_offset > 0 && start_offset < length &&
+ NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
+ return PCRE_ERROR_BADUTF8_OFFSET;
+ }
+#endif
+
+/* If the exec call supplied NULL for tables, use the inbuilt ones. This
+is a feature that makes it possible to save compiled regex and re-use them
+in other programs later. */
+
+if (md->tables == NULL) md->tables = PRIV(default_tables);
+
+/* The "must be at the start of a line" flags are used in a loop when finding
+where to start. */
+
+startline = (re->flags & PCRE_STARTLINE) != 0;
+firstline = (re->options & PCRE_FIRSTLINE) != 0;
+
+/* Set up the first character to match, if available. The first_byte value is
+never set for an anchored regular expression, but the anchoring may be forced
+at run time, so we have to test for anchoring. The first char may be unset for
+an unanchored pattern, of course. If there's no first char and the pattern was
+studied, there may be a bitmap of possible first characters. */
+
+if (!anchored)
+ {
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ {
+ has_first_char = TRUE;
+ first_char = first_char2 = (pcre_uchar)(re->first_char);
+ if ((re->flags & PCRE_FCH_CASELESS) != 0)
+ {
+ first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && first_char > 127)
+ first_char2 = UCD_OTHERCASE(first_char);
+#endif
+ }
+ }
+ else
+ {
+ if (!startline && study != NULL &&
+ (study->flags & PCRE_STUDY_MAPPED) != 0)
+ start_bits = study->start_bits;
+ }
+ }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+ {
+ has_req_char = TRUE;
+ req_char = req_char2 = (pcre_uchar)(re->req_char);
+ if ((re->flags & PCRE_RCH_CASELESS) != 0)
+ {
+ req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && req_char > 127)
+ req_char2 = UCD_OTHERCASE(req_char);
+#endif
+ }
+ }
+
+/* Call the main matching function, looping for a non-anchored regex after a
+failed match. If not restarting, perform certain optimizations at the start of
+a match. */
+
+for (;;)
+ {
+ int rc;
+
+ if ((options & PCRE_DFA_RESTART) == 0)
+ {
+ const pcre_uchar *save_end_subject = end_subject;
+
+ /* If firstline is TRUE, the start of the match is constrained to the first
+ line of a multiline string. Implement this by temporarily adjusting
+ end_subject so that we stop scanning at a newline. If the match fails at
+ the newline, later code breaks this loop. */
+
+ if (firstline)
+ {
+ PCRE_PUCHAR t = current_subject;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (t < md->end_subject && !IS_NEWLINE(t))
+ {
+ t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
+ }
+ }
+ else
+#endif
+ while (t < md->end_subject && !IS_NEWLINE(t)) t++;
+ end_subject = t;
+ }
+
+ /* There are some optimizations that avoid running the match if a known
+ starting point is not found. However, there is an option that disables
+ these, for testing and for ensuring that all callouts do actually occur.
+ The option can be set in the regex by (*NO_START_OPT) or passed in
+ match-time options. */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ /* Advance to a known first char. */
+
+ if (has_first_char)
+ {
+ if (first_char != first_char2)
+ while (current_subject < end_subject &&
+ *current_subject != first_char && *current_subject != first_char2)
+ current_subject++;
+ else
+ while (current_subject < end_subject &&
+ *current_subject != first_char)
+ current_subject++;
+ }
+
+ /* Or to just after a linebreak for a multiline match if possible */
+
+ else if (startline)
+ {
+ if (current_subject > md->start_subject + start_offset)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (current_subject < end_subject &&
+ !WAS_NEWLINE(current_subject))
+ {
+ current_subject++;
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
+ }
+ }
+ else
+#endif
+ while (current_subject < end_subject && !WAS_NEWLINE(current_subject))
+ current_subject++;
+
+ /* If we have just passed a CR and the newline option is ANY or
+ ANYCRLF, and we are now at a LF, advance the match position by one
+ more character. */
+
+ if (current_subject[-1] == CHAR_CR &&
+ (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+ current_subject < end_subject &&
+ *current_subject == CHAR_NL)
+ current_subject++;
+ }
+ }
+
+ /* Or to a non-unique first char after study */
+
+ else if (start_bits != NULL)
+ {
+ while (current_subject < end_subject)
+ {
+ register unsigned int c = *current_subject;
+#ifndef COMPILE_PCRE8
+ if (c > 255) c = 255;
+#endif
+ if ((start_bits[c/8] & (1 << (c&7))) == 0)
+ {
+ current_subject++;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ /* In non 8-bit mode, the iteration will stop for
+ characters > 255 at the beginning or not stop at all. */
+ if (utf)
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
+#endif
+ }
+ else break;
+ }
+ }
+ }
+
+ /* Restore fudged end_subject */
+
+ end_subject = save_end_subject;
+
+ /* The following two optimizations are disabled for partial matching or if
+ disabling is explicitly requested (and of course, by the test above, this
+ code is not obeyed when restarting after a partial match). */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 &&
+ (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
+ {
+ /* If the pattern was studied, a minimum subject length may be set. This
+ is a lower bound; no actual string of that length may actually match the
+ pattern. Although the value is, strictly, in characters, we treat it as
+ bytes to avoid spending too much time in this optimization. */
+
+ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
+ (pcre_uint32)(end_subject - current_subject) < study->minlength)
+ return PCRE_ERROR_NOMATCH;
+
+ /* If req_char is set, we know that that character must appear in the
+ subject for the match to succeed. If the first character is set, req_char
+ must be later in the subject; otherwise the test starts at the match
+ point. This optimization can save a huge amount of work in patterns with
+ nested unlimited repeats that aren't going to match. Writing separate
+ code for cased/caseless versions makes it go faster, as does using an
+ autoincrement and backing off on a match.
+
+ HOWEVER: when the subject string is very, very long, searching to its end
+ can take a long time, and give bad performance on quite ordinary
+ patterns. This showed up when somebody was matching /^C/ on a 32-megabyte
+ string... so we don't do this when the string is sufficiently long. */
+
+ if (has_req_char && end_subject - current_subject < REQ_BYTE_MAX)
+ {
+ register PCRE_PUCHAR p = current_subject + (has_first_char? 1:0);
+
+ /* We don't need to repeat the search if we haven't yet reached the
+ place we found it at last time. */
+
+ if (p > req_char_ptr)
+ {
+ if (req_char != req_char2)
+ {
+ while (p < end_subject)
+ {
+ register int pp = *p++;
+ if (pp == req_char || pp == req_char2) { p--; break; }
+ }
+ }
+ else
+ {
+ while (p < end_subject)
+ {
+ if (*p++ == req_char) { p--; break; }
+ }
+ }
+
+ /* If we can't find the required character, break the matching loop,
+ which will cause a return or PCRE_ERROR_NOMATCH. */
+
+ if (p >= end_subject) break;
+
+ /* If we have found the required character, save the point where we
+ found it, so that we don't search again next time round the loop if
+ the start hasn't passed this character yet. */
+
+ req_char_ptr = p;
+ }
+ }
+ }
+ } /* End of optimizations that are done when not restarting */
+
+ /* OK, now we can do the business */
+
+ md->start_used_ptr = current_subject;
+ md->recursive = NULL;
+
+ rc = internal_dfa_exec(
+ md, /* fixed match data */
+ md->start_code, /* this subexpression's code */
+ current_subject, /* where we currently are */
+ start_offset, /* start offset in subject */
+ offsets, /* offset vector */
+ offsetcount, /* size of same */
+ workspace, /* workspace vector */
+ wscount, /* size of same */
+ 0); /* function recurse level */
+
+ /* Anything other than "no match" means we are done, always; otherwise, carry
+ on only if not anchored. */
+
+ if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;
+
+ /* Advance to the next subject character unless we are at the end of a line
+ and firstline is set. */
+
+ if (firstline && IS_NEWLINE(current_subject)) break;
+ current_subject++;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ ACROSSCHAR(current_subject < end_subject, *current_subject,
+ current_subject++);
+ }
+#endif
+ if (current_subject > end_subject) break;
+
+ /* If we have just passed a CR and we are now at a LF, and the pattern does
+ not contain any explicit matches for \r or \n, and the newline option is CRLF
+ or ANY or ANYCRLF, advance the match position by one more character. */
+
+ if (current_subject[-1] == CHAR_CR &&
+ current_subject < end_subject &&
+ *current_subject == CHAR_NL &&
+ (re->flags & PCRE_HASCRORLF) == 0 &&
+ (md->nltype == NLTYPE_ANY ||
+ md->nltype == NLTYPE_ANYCRLF ||
+ md->nllen == 2))
+ current_subject++;
+
+ } /* "Bumpalong" loop */
+
+return PCRE_ERROR_NOMATCH;
+}
+
+/* End of pcre_dfa_exec.c */
diff --git a/src/3rdparty/pcre/pcre_exec.c b/src/3rdparty/pcre/pcre_exec.c
new file mode 100644
index 00000000000..2905808c838
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_exec.c
@@ -0,0 +1,6960 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains pcre_exec(), the externally visible function that does
+pattern matching using an NFA algorithm, trying to mimic Perl as closely as
+possible. There are also some static supporting functions. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK md /* Block containing newline information */
+#define PSSTART start_subject /* Field containing processed string start */
+#define PSEND end_subject /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+/* Undefine some potentially clashing cpp symbols */
+
+#undef min
+#undef max
+
+/* Values for setting in md->match_function_type to indicate two special types
+of call to match(). We do it this way to save on using another stack variable,
+as stack usage is to be discouraged. */
+
+#define MATCH_CONDASSERT 1 /* Called to check a condition assertion */
+#define MATCH_CBEGROUP 2 /* Could-be-empty unlimited repeat group */
+
+/* Non-error returns from the match() function. Error returns are externally
+defined PCRE_ERROR_xxx codes, which are all negative. */
+
+#define MATCH_MATCH 1
+#define MATCH_NOMATCH 0
+
+/* Special internal returns from the match() function. Make them sufficiently
+negative to avoid the external error codes. */
+
+#define MATCH_ACCEPT (-999)
+#define MATCH_COMMIT (-998)
+#define MATCH_KETRPOS (-997)
+#define MATCH_ONCE (-996)
+#define MATCH_PRUNE (-995)
+#define MATCH_SKIP (-994)
+#define MATCH_SKIP_ARG (-993)
+#define MATCH_THEN (-992)
+
+/* Maximum number of ints of offset to save on the stack for recursive calls.
+If the offset vector is bigger, malloc is used. This should be a multiple of 3,
+because the offset vector is always a multiple of 3 long. */
+
+#define REC_STACK_SAVE_MAX 30
+
+/* Min and max values for the common repeats; for the maxima, 0 => infinity */
+
+static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
+static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
+
+
+
+#ifdef PCRE_DEBUG
+/*************************************************
+* Debugging function to print chars *
+*************************************************/
+
+/* Print a sequence of chars in printable format, stopping at the end of the
+subject if the requested.
+
+Arguments:
+ p points to characters
+ length number to print
+ is_subject TRUE if printing from within md->start_subject
+ md pointer to matching data block, if is_subject is TRUE
+
+Returns: nothing
+*/
+
+static void
+pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
+{
+unsigned int c;
+if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
+while (length-- > 0)
+ if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
+}
+#endif
+
+
+
+/*************************************************
+* Match a back-reference *
+*************************************************/
+
+/* Normally, if a back reference hasn't been set, the length that is passed is
+negative, so the match always fails. However, in JavaScript compatibility mode,
+the length passed is zero. Note that in caseless UTF-8 mode, the number of
+subject bytes matched may be different to the number of reference bytes.
+
+Arguments:
+ offset index into the offset vector
+ eptr pointer into the subject
+ length length of reference to be matched (number of bytes)
+ md points to match data block
+ caseless TRUE if caseless
+
+Returns: < 0 if not matched, otherwise the number of subject bytes matched
+*/
+
+static int
+match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
+ BOOL caseless)
+{
+PCRE_PUCHAR eptr_start = eptr;
+register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
+
+#ifdef PCRE_DEBUG
+if (eptr >= md->end_subject)
+ printf("matching subject ");
+else
+ {
+ printf("matching subject ");
+ pchars(eptr, length, TRUE, md);
+ }
+printf(" against backref ");
+pchars(p, length, FALSE, md);
+printf("\n");
+#endif
+
+/* Always fail if reference not set (and not JavaScript compatible). */
+
+if (length < 0) return -1;
+
+/* Separate the caseless case for speed. In UTF-8 mode we can only do this
+properly if Unicode properties are supported. Otherwise, we can check only
+ASCII characters. */
+
+if (caseless)
+ {
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (md->utf)
+ {
+ /* Match characters up to the end of the reference. NOTE: the number of
+ bytes matched may differ, because there are some characters whose upper and
+ lower case versions code as different numbers of bytes. For example, U+023A
+ (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);
+ a sequence of 3 of the former uses 6 bytes, as does a sequence of two of
+ the latter. It is important, therefore, to check the length along the
+ reference, not along the subject (earlier code did this wrong). */
+
+ PCRE_PUCHAR endptr = p + length;
+ while (p < endptr)
+ {
+ int c, d;
+ if (eptr >= md->end_subject) return -1;
+ GETCHARINC(c, eptr);
+ GETCHARINC(d, p);
+ if (c != d && c != UCD_OTHERCASE(d)) return -1;
+ }
+ }
+ else
+#endif
+#endif
+
+ /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
+ is no UCP support. */
+ {
+ if (eptr + length > md->end_subject) return -1;
+ while (length-- > 0)
+ {
+ if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
+ p++;
+ eptr++;
+ }
+ }
+ }
+
+/* In the caseful case, we can just compare the bytes, whether or not we
+are in UTF-8 mode. */
+
+else
+ {
+ if (eptr + length > md->end_subject) return -1;
+ while (length-- > 0) if (*p++ != *eptr++) return -1;
+ }
+
+return (int)(eptr - eptr_start);
+}
+
+
+
+/***************************************************************************
+****************************************************************************
+ RECURSION IN THE match() FUNCTION
+
+The match() function is highly recursive, though not every recursive call
+increases the recursive depth. Nevertheless, some regular expressions can cause
+it to recurse to a great depth. I was writing for Unix, so I just let it call
+itself recursively. This uses the stack for saving everything that has to be
+saved for a recursive call. On Unix, the stack can be large, and this works
+fine.
+
+It turns out that on some non-Unix-like systems there are problems with
+programs that use a lot of stack. (This despite the fact that every last chip
+has oodles of memory these days, and techniques for extending the stack have
+been known for decades.) So....
+
+There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
+calls by keeping local variables that need to be preserved in blocks of memory
+obtained from malloc() instead instead of on the stack. Macros are used to
+achieve this so that the actual code doesn't look very different to what it
+always used to.
+
+The original heap-recursive code used longjmp(). However, it seems that this
+can be very slow on some operating systems. Following a suggestion from Stan
+Switzer, the use of longjmp() has been abolished, at the cost of having to
+provide a unique number for each call to RMATCH. There is no way of generating
+a sequence of numbers at compile time in C. I have given them names, to make
+them stand out more clearly.
+
+Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
+FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
+tests. Furthermore, not using longjmp() means that local dynamic variables
+don't have indeterminate values; this has meant that the frame size can be
+reduced because the result can be "passed back" by straight setting of the
+variable instead of being passed in the frame.
+****************************************************************************
+***************************************************************************/
+
+/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
+below must be updated in sync. */
+
+enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
+ RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
+ RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
+ RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
+ RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
+ RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
+ RM61, RM62, RM63, RM64, RM65, RM66 };
+
+/* These versions of the macros use the stack, as normal. There are debugging
+versions and production versions. Note that the "rw" argument of RMATCH isn't
+actually used in this definition. */
+
+#ifndef NO_RECURSE
+#define REGISTER register
+
+#ifdef PCRE_DEBUG
+#define RMATCH(ra,rb,rc,rd,re,rw) \
+ { \
+ printf("match() called in line %d\n", __LINE__); \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
+ printf("to line %d\n", __LINE__); \
+ }
+#define RRETURN(ra) \
+ { \
+ printf("match() returned %d from line %d ", ra, __LINE__); \
+ return ra; \
+ }
+#else
+#define RMATCH(ra,rb,rc,rd,re,rw) \
+ rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
+#define RRETURN(ra) return ra
+#endif
+
+#else
+
+
+/* These versions of the macros manage a private stack on the heap. Note that
+the "rd" argument of RMATCH isn't actually used in this definition. It's the md
+argument of match(), which never changes. */
+
+#define REGISTER
+
+#define RMATCH(ra,rb,rc,rd,re,rw)\
+ {\
+ heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
+ if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
+ frame->Xwhere = rw; \
+ newframe->Xeptr = ra;\
+ newframe->Xecode = rb;\
+ newframe->Xmstart = mstart;\
+ newframe->Xoffset_top = rc;\
+ newframe->Xeptrb = re;\
+ newframe->Xrdepth = frame->Xrdepth + 1;\
+ newframe->Xprevframe = frame;\
+ frame = newframe;\
+ DPRINTF(("restarting from line %d\n", __LINE__));\
+ goto HEAP_RECURSE;\
+ L_##rw:\
+ DPRINTF(("jumped back to line %d\n", __LINE__));\
+ }
+
+#define RRETURN(ra)\
+ {\
+ heapframe *oldframe = frame;\
+ frame = oldframe->Xprevframe;\
+ if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\
+ if (frame != NULL)\
+ {\
+ rrc = ra;\
+ goto HEAP_RETURN;\
+ }\
+ return ra;\
+ }
+
+
+/* Structure for remembering the local variables in a private frame */
+
+typedef struct heapframe {
+ struct heapframe *Xprevframe;
+
+ /* Function arguments that may change */
+
+ PCRE_PUCHAR Xeptr;
+ const pcre_uchar *Xecode;
+ PCRE_PUCHAR Xmstart;
+ int Xoffset_top;
+ eptrblock *Xeptrb;
+ unsigned int Xrdepth;
+
+ /* Function local variables */
+
+ PCRE_PUCHAR Xcallpat;
+#ifdef SUPPORT_UTF
+ PCRE_PUCHAR Xcharptr;
+#endif
+ PCRE_PUCHAR Xdata;
+ PCRE_PUCHAR Xnext;
+ PCRE_PUCHAR Xpp;
+ PCRE_PUCHAR Xprev;
+ PCRE_PUCHAR Xsaved_eptr;
+
+ recursion_info Xnew_recursive;
+
+ BOOL Xcur_is_word;
+ BOOL Xcondition;
+ BOOL Xprev_is_word;
+
+#ifdef SUPPORT_UCP
+ int Xprop_type;
+ int Xprop_value;
+ int Xprop_fail_result;
+ int Xoclength;
+ pcre_uchar Xocchars[6];
+#endif
+
+ int Xcodelink;
+ int Xctype;
+ unsigned int Xfc;
+ int Xfi;
+ int Xlength;
+ int Xmax;
+ int Xmin;
+ int Xnumber;
+ int Xoffset;
+ int Xop;
+ int Xsave_capture_last;
+ int Xsave_offset1, Xsave_offset2, Xsave_offset3;
+ int Xstacksave[REC_STACK_SAVE_MAX];
+
+ eptrblock Xnewptrb;
+
+ /* Where to jump back to */
+
+ int Xwhere;
+
+} heapframe;
+
+#endif
+
+
+/***************************************************************************
+***************************************************************************/
+
+
+
+/*************************************************
+* Match from current position *
+*************************************************/
+
+/* This function is called recursively in many circumstances. Whenever it
+returns a negative (error) response, the outer incarnation must also return the
+same response. */
+
+/* These macros pack up tests that are used for partial matching, and which
+appear several times in the code. We set the "hit end" flag if the pointer is
+at the end of the subject and also past the start of the subject (i.e.
+something has been matched). For hard partial matching, we then return
+immediately. The second one is used when we already know we are past the end of
+the subject. */
+
+#define CHECK_PARTIAL()\
+ if (md->partial != 0 && eptr >= md->end_subject && \
+ eptr > md->start_used_ptr) \
+ { \
+ md->hitend = TRUE; \
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
+ }
+
+#define SCHECK_PARTIAL()\
+ if (md->partial != 0 && eptr > md->start_used_ptr) \
+ { \
+ md->hitend = TRUE; \
+ if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
+ }
+
+
+/* Performance note: It might be tempting to extract commonly used fields from
+the md structure (e.g. utf, end_subject) into individual variables to improve
+performance. Tests using gcc on a SPARC disproved this; in the first case, it
+made performance worse.
+
+Arguments:
+ eptr pointer to current character in subject
+ ecode pointer to current position in compiled code
+ mstart pointer to the current match start position (can be modified
+ by encountering \K)
+ offset_top current top pointer
+ md pointer to "static" info for the match
+ eptrb pointer to chain of blocks containing eptr at start of
+ brackets - for testing for empty matches
+ rdepth the recursion depth
+
+Returns: MATCH_MATCH if matched ) these values are >= 0
+ MATCH_NOMATCH if failed to match )
+ a negative MATCH_xxx value for PRUNE, SKIP, etc
+ a negative PCRE_ERROR_xxx value if aborted by an error condition
+ (e.g. stopped by repeated call or recursion limit)
+*/
+
+static int
+match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
+ PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
+ unsigned int rdepth)
+{
+/* These variables do not need to be preserved over recursion in this function,
+so they can be ordinary variables in all cases. Mark some of them with
+"register" because they are used a lot in loops. */
+
+register int rrc; /* Returns from recursive calls */
+register int i; /* Used for loops not involving calls to RMATCH() */
+register unsigned int c; /* Character values not kept over RMATCH() calls */
+register BOOL utf; /* Local copy of UTF flag for speed */
+
+BOOL minimize, possessive; /* Quantifier options */
+BOOL caseless;
+int condcode;
+
+/* When recursion is not being used, all "local" variables that have to be
+preserved over calls to RMATCH() are part of a "frame". We set up the top-level
+frame on the stack here; subsequent instantiations are obtained from the heap
+whenever RMATCH() does a "recursion". See the macro definitions above. Putting
+the top-level on the stack rather than malloc-ing them all gives a performance
+boost in many cases where there is not much "recursion". */
+
+#ifdef NO_RECURSE
+heapframe frame_zero;
+heapframe *frame = &frame_zero;
+frame->Xprevframe = NULL; /* Marks the top level */
+
+/* Copy in the original argument variables */
+
+frame->Xeptr = eptr;
+frame->Xecode = ecode;
+frame->Xmstart = mstart;
+frame->Xoffset_top = offset_top;
+frame->Xeptrb = eptrb;
+frame->Xrdepth = rdepth;
+
+/* This is where control jumps back to to effect "recursion" */
+
+HEAP_RECURSE:
+
+/* Macros make the argument variables come from the current frame */
+
+#define eptr frame->Xeptr
+#define ecode frame->Xecode
+#define mstart frame->Xmstart
+#define offset_top frame->Xoffset_top
+#define eptrb frame->Xeptrb
+#define rdepth frame->Xrdepth
+
+/* Ditto for the local variables */
+
+#ifdef SUPPORT_UTF
+#define charptr frame->Xcharptr
+#endif
+#define callpat frame->Xcallpat
+#define codelink frame->Xcodelink
+#define data frame->Xdata
+#define next frame->Xnext
+#define pp frame->Xpp
+#define prev frame->Xprev
+#define saved_eptr frame->Xsaved_eptr
+
+#define new_recursive frame->Xnew_recursive
+
+#define cur_is_word frame->Xcur_is_word
+#define condition frame->Xcondition
+#define prev_is_word frame->Xprev_is_word
+
+#ifdef SUPPORT_UCP
+#define prop_type frame->Xprop_type
+#define prop_value frame->Xprop_value
+#define prop_fail_result frame->Xprop_fail_result
+#define oclength frame->Xoclength
+#define occhars frame->Xocchars
+#endif
+
+#define ctype frame->Xctype
+#define fc frame->Xfc
+#define fi frame->Xfi
+#define length frame->Xlength
+#define max frame->Xmax
+#define min frame->Xmin
+#define number frame->Xnumber
+#define offset frame->Xoffset
+#define op frame->Xop
+#define save_capture_last frame->Xsave_capture_last
+#define save_offset1 frame->Xsave_offset1
+#define save_offset2 frame->Xsave_offset2
+#define save_offset3 frame->Xsave_offset3
+#define stacksave frame->Xstacksave
+
+#define newptrb frame->Xnewptrb
+
+/* When recursion is being used, local variables are allocated on the stack and
+get preserved during recursion in the normal way. In this environment, fi and
+i, and fc and c, can be the same variables. */
+
+#else /* NO_RECURSE not defined */
+#define fi i
+#define fc c
+
+/* Many of the following variables are used only in small blocks of the code.
+My normal style of coding would have declared them within each of those blocks.
+However, in order to accommodate the version of this code that uses an external
+"stack" implemented on the heap, it is easier to declare them all here, so the
+declarations can be cut out in a block. The only declarations within blocks
+below are for variables that do not have to be preserved over a recursive call
+to RMATCH(). */
+
+#ifdef SUPPORT_UTF
+const pcre_uchar *charptr;
+#endif
+const pcre_uchar *callpat;
+const pcre_uchar *data;
+const pcre_uchar *next;
+PCRE_PUCHAR pp;
+const pcre_uchar *prev;
+PCRE_PUCHAR saved_eptr;
+
+recursion_info new_recursive;
+
+BOOL cur_is_word;
+BOOL condition;
+BOOL prev_is_word;
+
+#ifdef SUPPORT_UCP
+int prop_type;
+int prop_value;
+int prop_fail_result;
+int oclength;
+pcre_uchar occhars[6];
+#endif
+
+int codelink;
+int ctype;
+int length;
+int max;
+int min;
+int number;
+int offset;
+int op;
+int save_capture_last;
+int save_offset1, save_offset2, save_offset3;
+int stacksave[REC_STACK_SAVE_MAX];
+
+eptrblock newptrb;
+
+/* There is a special fudge for calling match() in a way that causes it to
+measure the size of its basic stack frame when the stack is being used for
+recursion. The second argument (ecode) being NULL triggers this behaviour. It
+cannot normally ever be NULL. The return is the negated value of the frame
+size. */
+
+if (ecode == NULL)
+ {
+ if (rdepth == 0)
+ return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
+ else
+ {
+ int len = (char *)&rdepth - (char *)eptr;
+ return (len > 0)? -len : len;
+ }
+ }
+#endif /* NO_RECURSE */
+
+/* To save space on the stack and in the heap frame, I have doubled up on some
+of the local variables that are used only in localised parts of the code, but
+still need to be preserved over recursive calls of match(). These macros define
+the alternative names that are used. */
+
+#define allow_zero cur_is_word
+#define cbegroup condition
+#define code_offset codelink
+#define condassert condition
+#define matched_once prev_is_word
+#define foc number
+#define save_mark data
+
+/* These statements are here to stop the compiler complaining about unitialized
+variables. */
+
+#ifdef SUPPORT_UCP
+prop_value = 0;
+prop_fail_result = 0;
+#endif
+
+
+/* This label is used for tail recursion, which is used in a few cases even
+when NO_RECURSE is not defined, in order to reduce the amount of stack that is
+used. Thanks to Ian Taylor for noticing this possibility and sending the
+original patch. */
+
+TAIL_RECURSE:
+
+/* OK, now we can get on with the real code of the function. Recursive calls
+are specified by the macro RMATCH and RRETURN is used to return. When
+NO_RECURSE is *not* defined, these just turn into a recursive call to match()
+and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
+defined). However, RMATCH isn't like a function call because it's quite a
+complicated macro. It has to be used in one particular way. This shouldn't,
+however, impact performance when true recursion is being used. */
+
+#ifdef SUPPORT_UTF
+utf = md->utf; /* Local copy of the flag */
+#else
+utf = FALSE;
+#endif
+
+/* First check that we haven't called match() too many times, or that we
+haven't exceeded the recursive call limit. */
+
+if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
+if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
+
+/* At the start of a group with an unlimited repeat that may match an empty
+string, the variable md->match_function_type is set to MATCH_CBEGROUP. It is
+done this way to save having to use another function argument, which would take
+up space on the stack. See also MATCH_CONDASSERT below.
+
+When MATCH_CBEGROUP is set, add the current subject pointer to the chain of
+such remembered pointers, to be checked when we hit the closing ket, in order
+to break infinite loops that match no characters. When match() is called in
+other circumstances, don't add to the chain. The MATCH_CBEGROUP feature must
+NOT be used with tail recursion, because the memory block that is used is on
+the stack, so a new one may be required for each match(). */
+
+if (md->match_function_type == MATCH_CBEGROUP)
+ {
+ newptrb.epb_saved_eptr = eptr;
+ newptrb.epb_prev = eptrb;
+ eptrb = &newptrb;
+ md->match_function_type = 0;
+ }
+
+/* Now start processing the opcodes. */
+
+for (;;)
+ {
+ minimize = possessive = FALSE;
+ op = *ecode;
+
+ switch(op)
+ {
+ case OP_MARK:
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM55);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
+
+ /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
+ argument, and we must check whether that argument matches this MARK's
+ argument. It is passed back in md->start_match_ptr (an overloading of that
+ variable). If it does match, we reset that variable to the current subject
+ position and return MATCH_SKIP. Otherwise, pass back the return code
+ unaltered. */
+
+ else if (rrc == MATCH_SKIP_ARG &&
+ STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
+ {
+ md->start_match_ptr = eptr;
+ RRETURN(MATCH_SKIP);
+ }
+ RRETURN(rrc);
+
+ case OP_FAIL:
+ RRETURN(MATCH_NOMATCH);
+
+ /* COMMIT overrides PRUNE, SKIP, and THEN */
+
+ case OP_COMMIT:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM52);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
+ rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
+ rrc != MATCH_THEN)
+ RRETURN(rrc);
+ RRETURN(MATCH_COMMIT);
+
+ /* PRUNE overrides THEN */
+
+ case OP_PRUNE:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM51);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ RRETURN(MATCH_PRUNE);
+
+ case OP_PRUNE_ARG:
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM56);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ RRETURN(MATCH_PRUNE);
+
+ /* SKIP overrides PRUNE and THEN */
+
+ case OP_SKIP:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM53);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
+ RRETURN(rrc);
+ md->start_match_ptr = eptr; /* Pass back current position */
+ RRETURN(MATCH_SKIP);
+
+ /* Note that, for Perl compatibility, SKIP with an argument does NOT set
+ nomatch_mark. There is a flag that disables this opcode when re-matching a
+ pattern that ended with a SKIP for which there was not a matching MARK. */
+
+ case OP_SKIP_ARG:
+ if (md->ignore_skip_arg)
+ {
+ ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
+ break;
+ }
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
+ eptrb, RM57);
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
+ RRETURN(rrc);
+
+ /* Pass back the current skip name by overloading md->start_match_ptr and
+ returning the special MATCH_SKIP_ARG return code. This will either be
+ caught by a matching MARK, or get to the top, where it causes a rematch
+ with the md->ignore_skip_arg flag set. */
+
+ md->start_match_ptr = ecode + 2;
+ RRETURN(MATCH_SKIP_ARG);
+
+ /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
+ the branch in which it occurs can be determined. Overload the start of
+ match pointer to do this. */
+
+ case OP_THEN:
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM54);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
+
+ case OP_THEN_ARG:
+ md->nomatch_mark = ecode + 2;
+ md->mark = NULL; /* In case previously set by assertion */
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
+ md, eptrb, RM58);
+ if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
+ md->mark == NULL) md->mark = ecode + 2;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->start_match_ptr = ecode;
+ RRETURN(MATCH_THEN);
+
+ /* Handle an atomic group that does not contain any capturing parentheses.
+ This can be handled like an assertion. Prior to 8.13, all atomic groups
+ were handled this way. In 8.13, the code was changed as below for ONCE, so
+ that backups pass through the group and thereby reset captured values.
+ However, this uses a lot more stack, so in 8.20, atomic groups that do not
+ contain any captures generate OP_ONCE_NC, which can be handled in the old,
+ less stack intensive way.
+
+ Check the alternative branches in turn - the matching won't pass the KET
+ for this kind of subpattern. If any one branch matches, we carry on as at
+ the end of a normal bracket, leaving the subject pointer, but resetting
+ the start-of-match value in case it was changed by \K. */
+
+ case OP_ONCE_NC:
+ prev = ecode;
+ saved_eptr = eptr;
+ save_mark = md->mark;
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
+ if (rrc == MATCH_MATCH) /* Note: _not_ MATCH_ACCEPT */
+ {
+ mstart = md->start_match_ptr;
+ break;
+ }
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode,1);
+ md->mark = save_mark;
+ }
+ while (*ecode == OP_ALT);
+
+ /* If hit the end of the group (which could be repeated), fail */
+
+ if (*ecode != OP_ONCE_NC && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+
+ /* Continue as from after the group, updating the offsets high water
+ mark, since extracts may have been taken. */
+
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+
+ /* For a non-repeating ket, just continue at this level. This also
+ happens for a repeating ket if no characters were matched in the group.
+ This is the forcible breaking of infinite loops as implemented in Perl
+ 5.005. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ ecode += 1+LINK_SIZE;
+ break;
+ }
+
+ /* The repeating kets try the rest of the pattern or restart from the
+ preceding bracket, in the appropriate order. The second "call" of match()
+ uses tail recursion, to avoid using another stack frame. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM65);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Handle a capturing bracket, other than those that are possessive with an
+ unlimited repeat. If there is space in the offset vector, save the current
+ subject position in the working slot at the top of the vector. We mustn't
+ change the current values of the data slot, because they may be set from a
+ previous iteration of this group, and be referred to by a reference inside
+ the group. A failure to match might occur after the group has succeeded,
+ if something later on doesn't match. For this reason, we need to restore
+ the working value and also the values of the final offsets, in case they
+ were set by a previous iteration of the same bracket.
+
+ If there isn't enough space in the offset vector, treat this as if it were
+ a non-capturing bracket. Don't worry about setting the flag for the error
+ case here; that is handled in the code for KET. */
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("start bracket %d\n", number);
+ printf("subject=");
+ pchars(eptr, 16, TRUE, md);
+ printf("\n");
+#endif
+
+ if (offset < md->offset_max)
+ {
+ save_offset1 = md->offset_vector[offset];
+ save_offset2 = md->offset_vector[offset+1];
+ save_offset3 = md->offset_vector[md->offset_end - number];
+ save_capture_last = md->capture_last;
+ save_mark = md->mark;
+
+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+ md->offset_vector[md->offset_end - number] =
+ (int)(eptr - md->start_subject);
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM1);
+ if (rrc == MATCH_ONCE) break; /* Backing up through an atomic group */
+
+ /* If we backed up to a THEN, check whether it is within the current
+ branch by comparing the address of the THEN that is passed back with
+ the end of the branch. If it is within the current branch, and the
+ branch is one of two or more alternatives (it either starts or ends
+ with OP_ALT), we have reached the limit of THEN's action, so convert
+ the return code to NOMATCH, which will cause normal backtracking to
+ happen from now on. Otherwise, THEN is passed back to an outer
+ alternative. This implements Perl's treatment of parenthesized groups,
+ where a group not containing | does not affect the current alternative,
+ that is, (X) is NOT the same as (X|(*F)). */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ /* Anything other than NOMATCH is passed back. */
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ }
+
+ DPRINTF(("bracket %d failed\n", number));
+ md->offset_vector[offset] = save_offset1;
+ md->offset_vector[offset+1] = save_offset2;
+ md->offset_vector[md->offset_end - number] = save_offset3;
+
+ /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
+
+ RRETURN(rrc);
+ }
+
+ /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+ as a non-capturing bracket. */
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ /* Non-capturing or atomic group, except for possessive with unlimited
+ repeat and ONCE group with no captures. Loop for all the alternatives.
+
+ When we get to the final alternative within the brackets, we used to return
+ the result of a recursive call to match() whatever happened so it was
+ possible to reduce stack usage by turning this into a tail recursion,
+ except in the case of a possibly empty group. However, now that there is
+ the possiblity of (*THEN) occurring in the final alternative, this
+ optimization is no longer always possible.
+
+ We can optimize if we know there are no (*THEN)s in the pattern; at present
+ this is the best that can be done.
+
+ MATCH_ONCE is returned when the end of an atomic group is successfully
+ reached, but subsequent matching fails. It passes back up the tree (causing
+ captured values to be reset) until the original atomic group level is
+ reached. This is tested by comparing md->once_target with the start of the
+ group. At this point, the return is converted into MATCH_NOMATCH so that
+ previous backup points can be taken. */
+
+ case OP_ONCE:
+ case OP_BRA:
+ case OP_SBRA:
+ DPRINTF(("start non-capturing bracket\n"));
+
+ for (;;)
+ {
+ if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;
+
+ /* If this is not a possibly empty group, and there are no (*THEN)s in
+ the pattern, and this is the final alternative, optimize as described
+ above. */
+
+ else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
+ {
+ ecode += PRIV(OP_lengths)[*ecode];
+ goto TAIL_RECURSE;
+ }
+
+ /* In all other cases, we have to make another call to match(). */
+
+ save_mark = md->mark;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
+ RM2);
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH)
+ {
+ if (rrc == MATCH_ONCE)
+ {
+ const pcre_uchar *scode = ecode;
+ if (*scode != OP_ONCE) /* If not at start, find it */
+ {
+ while (*scode == OP_ALT) scode += GET(scode, 1);
+ scode -= GET(scode, 1);
+ }
+ if (md->once_target == scode) rrc = MATCH_NOMATCH;
+ }
+ RRETURN(rrc);
+ }
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ if (*ecode != OP_ALT) break;
+ }
+
+ RRETURN(MATCH_NOMATCH);
+
+ /* Handle possessive capturing brackets with an unlimited repeat. We come
+ here from BRAZERO with allow_zero set TRUE. The offset_vector values are
+ handled similarly to the normal case above. However, the matching is
+ different. The end of these brackets will always be OP_KETRPOS, which
+ returns MATCH_KETRPOS without going further in the pattern. By this means
+ we can handle the group by iteration rather than recursion, thereby
+ reducing the amount of stack needed. */
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_CAPTURE:
+ number = GET2(ecode, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("start possessive bracket %d\n", number);
+ printf("subject=");
+ pchars(eptr, 16, TRUE, md);
+ printf("\n");
+#endif
+
+ if (offset < md->offset_max)
+ {
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
+
+ save_offset1 = md->offset_vector[offset];
+ save_offset2 = md->offset_vector[offset+1];
+ save_offset3 = md->offset_vector[md->offset_end - number];
+ save_capture_last = md->capture_last;
+
+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+
+ /* Each time round the loop, save the current subject position for use
+ when the group matches. For MATCH_MATCH, the group has matched, so we
+ restart it with a new subject starting position, remembering that we had
+ at least one match. For MATCH_NOMATCH, carry on with the alternatives, as
+ usual. If we haven't matched any alternatives in any iteration, check to
+ see if a previous iteration matched. If so, the group has matched;
+ continue from afterwards. Otherwise it has failed; restore the previous
+ capture values before returning NOMATCH. */
+
+ for (;;)
+ {
+ md->offset_vector[md->offset_end - number] =
+ (int)(eptr - md->start_subject);
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM63);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+ ecode = md->start_code + code_offset;
+ save_capture_last = md->capture_last;
+ matched_once = TRUE;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->capture_last = save_capture_last;
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ }
+
+ if (!matched_once)
+ {
+ md->offset_vector[offset] = save_offset1;
+ md->offset_vector[offset+1] = save_offset2;
+ md->offset_vector[md->offset_end - number] = save_offset3;
+ }
+
+ if (allow_zero || matched_once)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+ as a non-capturing bracket. */
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+ /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+ /* Non-capturing possessive bracket with unlimited repeat. We come here
+ from BRAZERO with allow_zero = TRUE. The code is similar to the above,
+ without the capturing complication. It is written out separately for speed
+ and cleanliness. */
+
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ allow_zero = FALSE;
+
+ POSSESSIVE_NON_CAPTURE:
+ matched_once = FALSE;
+ code_offset = (int)(ecode - md->start_code);
+
+ for (;;)
+ {
+ if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
+ eptrb, RM48);
+ if (rrc == MATCH_KETRPOS)
+ {
+ offset_top = md->end_offset_top;
+ eptr = md->end_match_ptr;
+ ecode = md->start_code + code_offset;
+ matched_once = TRUE;
+ continue;
+ }
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
+
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode += GET(ecode, 1);
+ if (*ecode != OP_ALT) break;
+ }
+
+ if (matched_once || allow_zero)
+ {
+ ecode += 1 + LINK_SIZE;
+ break;
+ }
+ RRETURN(MATCH_NOMATCH);
+
+ /* Control never reaches here. */
+
+ /* Conditional group: compilation checked that there are no more than
+ two branches. If the condition is false, skipping the first branch takes us
+ past the end if there is only one branch, but that's OK because that is
+ exactly what going to the ket would do. */
+
+ case OP_COND:
+ case OP_SCOND:
+ codelink = GET(ecode, 1);
+
+ /* Because of the way auto-callout works during compile, a callout item is
+ inserted between OP_COND and an assertion condition. */
+
+ if (ecode[LINK_SIZE+1] == OP_CALLOUT)
+ {
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 2; /* Version 1 of the callout block */
+ cb.callout_number = ecode[LINK_SIZE+2];
+ cb.offset_vector = md->offset_vector;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)md->start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)md->start_subject;
+#endif
+ cb.subject_length = (int)(md->end_subject - md->start_subject);
+ cb.start_match = (int)(mstart - md->start_subject);
+ cb.current_position = (int)(eptr - md->start_subject);
+ cb.pattern_position = GET(ecode, LINK_SIZE + 3);
+ cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
+ cb.capture_top = offset_top/2;
+ cb.capture_last = md->capture_last;
+ cb.callout_data = md->callout_data;
+ cb.mark = md->nomatch_mark;
+ if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
+ if (rrc < 0) RRETURN(rrc);
+ }
+ ecode += PRIV(OP_lengths)[OP_CALLOUT];
+ }
+
+ condcode = ecode[LINK_SIZE+1];
+
+ /* Now see what the actual condition is */
+
+ if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */
+ {
+ if (md->recursive == NULL) /* Not recursing => FALSE */
+ {
+ condition = FALSE;
+ ecode += GET(ecode, 1);
+ }
+ else
+ {
+ int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
+ condition = (recno == RREF_ANY || recno == md->recursive->group_num);
+
+ /* If the test is for recursion into a specific subpattern, and it is
+ false, but the test was set up by name, scan the table to see if the
+ name refers to any other numbers, and test them. The condition is true
+ if any one is set. */
+
+ if (!condition && condcode == OP_NRREF)
+ {
+ pcre_uchar *slotA = md->name_table;
+ for (i = 0; i < md->name_count; i++)
+ {
+ if (GET2(slotA, 0) == recno) break;
+ slotA += md->name_entry_size;
+ }
+
+ /* Found a name for the number - there can be only one; duplicate
+ names for different numbers are allowed, but not vice versa. First
+ scan down for duplicates. */
+
+ if (i < md->name_count)
+ {
+ pcre_uchar *slotB = slotA;
+ while (slotB > md->name_table)
+ {
+ slotB -= md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == md->recursive->group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < md->name_count; i++)
+ {
+ slotB += md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == md->recursive->group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+ }
+
+ /* Chose branch according to the condition */
+
+ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
+ }
+ }
+
+ else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */
+ {
+ offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
+ condition = offset < offset_top && md->offset_vector[offset] >= 0;
+
+ /* If the numbered capture is unset, but the reference was by name,
+ scan the table to see if the name refers to any other numbers, and test
+ them. The condition is true if any one is set. This is tediously similar
+ to the code above, but not close enough to try to amalgamate. */
+
+ if (!condition && condcode == OP_NCREF)
+ {
+ int refno = offset >> 1;
+ pcre_uchar *slotA = md->name_table;
+
+ for (i = 0; i < md->name_count; i++)
+ {
+ if (GET2(slotA, 0) == refno) break;
+ slotA += md->name_entry_size;
+ }
+
+ /* Found a name for the number - there can be only one; duplicate names
+ for different numbers are allowed, but not vice versa. First scan down
+ for duplicates. */
+
+ if (i < md->name_count)
+ {
+ pcre_uchar *slotB = slotA;
+ while (slotB > md->name_table)
+ {
+ slotB -= md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ offset = GET2(slotB, 0) << 1;
+ condition = offset < offset_top &&
+ md->offset_vector[offset] >= 0;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < md->name_count; i++)
+ {
+ slotB += md->name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ offset = GET2(slotB, 0) << 1;
+ condition = offset < offset_top &&
+ md->offset_vector[offset] >= 0;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+ }
+
+ /* Chose branch according to the condition */
+
+ ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
+ }
+
+ else if (condcode == OP_DEF) /* DEFINE - always false */
+ {
+ condition = FALSE;
+ ecode += GET(ecode, 1);
+ }
+
+ /* The condition is an assertion. Call match() to evaluate it - setting
+ md->match_function_type to MATCH_CONDASSERT causes it to stop at the end of
+ an assertion. */
+
+ else
+ {
+ md->match_function_type = MATCH_CONDASSERT;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
+ if (rrc == MATCH_MATCH)
+ {
+ if (md->end_offset_top > offset_top)
+ offset_top = md->end_offset_top; /* Captures may have happened */
+ condition = TRUE;
+ ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
+ while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+ }
+
+ /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
+ assertion; it is therefore treated as NOMATCH. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+ {
+ RRETURN(rrc); /* Need braces because of following else */
+ }
+ else
+ {
+ condition = FALSE;
+ ecode += codelink;
+ }
+ }
+
+ /* We are now at the branch that is to be obeyed. As there is only one, can
+ use tail recursion to avoid using another stack frame, except when there is
+ unlimited repeat of a possibly empty group. In the latter case, a recursive
+ call to match() is always required, unless the second alternative doesn't
+ exist, in which case we can just plough on. Note that, for compatibility
+ with Perl, the | in a conditional group is NOT treated as creating two
+ alternatives. If a THEN is encountered in the branch, it propagates out to
+ the enclosing alternative (unless nested in a deeper set of alternatives,
+ of course). */
+
+ if (condition || *ecode == OP_ALT)
+ {
+ if (op != OP_SCOND)
+ {
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
+ RRETURN(rrc);
+ }
+
+ /* Condition false & no alternative; continue after the group. */
+
+ else
+ {
+ ecode += 1 + LINK_SIZE;
+ }
+ break;
+
+
+ /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
+ to close any currently open capturing brackets. */
+
+ case OP_CLOSE:
+ number = GET2(ecode, 1);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("end bracket %d at *ACCEPT", number);
+ printf("\n");
+#endif
+
+ md->capture_last = number;
+ if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ {
+ md->offset_vector[offset] =
+ md->offset_vector[md->offset_end - number];
+ md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
+ if (offset_top <= offset) offset_top = offset + 2;
+ }
+ ecode += 1 + IMM2_SIZE;
+ break;
+
+
+ /* End of the pattern, either real or forced. */
+
+ case OP_END:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+
+ /* If we have matched an empty string, fail if not in an assertion and not
+ in a recursion if either PCRE_NOTEMPTY is set, or if PCRE_NOTEMPTY_ATSTART
+ is set and we have matched at the start of the subject. In both cases,
+ backtracking will then try other alternatives, if any. */
+
+ if (eptr == mstart && op != OP_ASSERT_ACCEPT &&
+ md->recursive == NULL &&
+ (md->notempty ||
+ (md->notempty_atstart &&
+ mstart == md->start_subject + md->start_offset)))
+ RRETURN(MATCH_NOMATCH);
+
+ /* Otherwise, we have a match. */
+
+ md->end_match_ptr = eptr; /* Record where we ended */
+ md->end_offset_top = offset_top; /* and how many extracts were taken */
+ md->start_match_ptr = mstart; /* and the start (\K can modify) */
+
+ /* For some reason, the macros don't work properly if an expression is
+ given as the argument to RRETURN when the heap is in use. */
+
+ rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
+ RRETURN(rrc);
+
+ /* Assertion brackets. Check the alternative branches in turn - the
+ matching won't pass the KET for an assertion. If any one branch matches,
+ the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
+ start of each branch to move the current point backwards, so the code at
+ this level is identical to the lookahead case. When the assertion is part
+ of a condition, we want to return immediately afterwards. The caller of
+ this incarnation of the match() function will have set MATCH_CONDASSERT in
+ md->match_function type, and one of these opcodes will be the first opcode
+ that is processed. We use a local variable that is preserved over calls to
+ match() to remember this case. */
+
+ case OP_ASSERT:
+ case OP_ASSERTBACK:
+ save_mark = md->mark;
+ if (md->match_function_type == MATCH_CONDASSERT)
+ {
+ condassert = TRUE;
+ md->match_function_type = 0;
+ }
+ else condassert = FALSE;
+
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
+ {
+ mstart = md->start_match_ptr; /* In case \K reset it */
+ break;
+ }
+
+ /* PCRE does not allow THEN to escape beyond an assertion; it is treated
+ as NOMATCH. */
+
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ ecode += GET(ecode, 1);
+ md->mark = save_mark;
+ }
+ while (*ecode == OP_ALT);
+
+ if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
+
+ /* If checking an assertion for a condition, return MATCH_MATCH. */
+
+ if (condassert) RRETURN(MATCH_MATCH);
+
+ /* Continue from after the assertion, updating the offsets high water
+ mark, since extracts may have been taken during the assertion. */
+
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ ecode += 1 + LINK_SIZE;
+ offset_top = md->end_offset_top;
+ continue;
+
+ /* Negative assertion: all branches must fail to match. Encountering SKIP,
+ PRUNE, or COMMIT means we must assume failure without checking subsequent
+ branches. */
+
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK_NOT:
+ save_mark = md->mark;
+ if (md->match_function_type == MATCH_CONDASSERT)
+ {
+ condassert = TRUE;
+ md->match_function_type = 0;
+ }
+ else condassert = FALSE;
+
+ do
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
+ md->mark = save_mark;
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
+ if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
+ {
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ break;
+ }
+
+ /* PCRE does not allow THEN to escape beyond an assertion; it is treated
+ as NOMATCH. */
+
+ if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ ecode += GET(ecode,1);
+ }
+ while (*ecode == OP_ALT);
+
+ if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+
+ ecode += 1 + LINK_SIZE;
+ continue;
+
+ /* Move the subject pointer back. This occurs only at the start of
+ each branch of a lookbehind assertion. If we are too close to the start to
+ move back, this match function fails. When working with UTF-8 we move
+ back a number of characters, not bytes. */
+
+ case OP_REVERSE:
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ i = GET(ecode, 1);
+ while (i-- > 0)
+ {
+ eptr--;
+ if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+
+ /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
+
+ {
+ eptr -= GET(ecode, 1);
+ if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
+ }
+
+ /* Save the earliest consulted character, then skip to next op code */
+
+ if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
+ ecode += 1 + LINK_SIZE;
+ break;
+
+ /* The callout item calls an external function, if one is provided, passing
+ details of the match so far. This is mainly for debugging, though the
+ function is able to force a failure. */
+
+ case OP_CALLOUT:
+ if (PUBL(callout) != NULL)
+ {
+ PUBL(callout_block) cb;
+ cb.version = 2; /* Version 1 of the callout block */
+ cb.callout_number = ecode[1];
+ cb.offset_vector = md->offset_vector;
+#ifdef COMPILE_PCRE8
+ cb.subject = (PCRE_SPTR)md->start_subject;
+#else
+ cb.subject = (PCRE_SPTR16)md->start_subject;
+#endif
+ cb.subject_length = (int)(md->end_subject - md->start_subject);
+ cb.start_match = (int)(mstart - md->start_subject);
+ cb.current_position = (int)(eptr - md->start_subject);
+ cb.pattern_position = GET(ecode, 2);
+ cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
+ cb.capture_top = offset_top/2;
+ cb.capture_last = md->capture_last;
+ cb.callout_data = md->callout_data;
+ cb.mark = md->nomatch_mark;
+ if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
+ if (rrc < 0) RRETURN(rrc);
+ }
+ ecode += 2 + 2*LINK_SIZE;
+ break;
+
+ /* Recursion either matches the current regex, or some subexpression. The
+ offset data is the offset to the starting bracket from the start of the
+ whole pattern. (This is so that it works from duplicated subpatterns.)
+
+ The state of the capturing groups is preserved over recursion, and
+ re-instated afterwards. We don't know how many are started and not yet
+ finished (offset_top records the completed total) so we just have to save
+ all the potential data. There may be up to 65535 such values, which is too
+ large to put on the stack, but using malloc for small numbers seems
+ expensive. As a compromise, the stack is used when there are no more than
+ REC_STACK_SAVE_MAX values to store; otherwise malloc is used.
+
+ There are also other values that have to be saved. We use a chained
+ sequence of blocks that actually live on the stack. Thanks to Robin Houston
+ for the original version of this logic. It has, however, been hacked around
+ a lot, so he is not to blame for the current way it works. */
+
+ case OP_RECURSE:
+ {
+ recursion_info *ri;
+ int recno;
+
+ callpat = md->start_code + GET(ecode, 1);
+ recno = (callpat == md->start_code)? 0 :
+ GET2(callpat, 1 + LINK_SIZE);
+
+ /* Check for repeating a recursion without advancing the subject pointer.
+ This should catch convoluted mutual recursions. (Some simple cases are
+ caught at compile time.) */
+
+ for (ri = md->recursive; ri != NULL; ri = ri->prevrec)
+ if (recno == ri->group_num && eptr == ri->subject_position)
+ RRETURN(PCRE_ERROR_RECURSELOOP);
+
+ /* Add to "recursing stack" */
+
+ new_recursive.group_num = recno;
+ new_recursive.subject_position = eptr;
+ new_recursive.prevrec = md->recursive;
+ md->recursive = &new_recursive;
+
+ /* Where to continue from afterwards */
+
+ ecode += 1 + LINK_SIZE;
+
+ /* Now save the offset data */
+
+ new_recursive.saved_max = md->offset_end;
+ if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
+ new_recursive.offset_save = stacksave;
+ else
+ {
+ new_recursive.offset_save =
+ (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
+ if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
+ }
+ memcpy(new_recursive.offset_save, md->offset_vector,
+ new_recursive.saved_max * sizeof(int));
+
+ /* OK, now we can do the recursion. After processing each alternative,
+ restore the offset data. If there were nested recursions, md->recursive
+ might be changed, so reset it before looping. */
+
+ DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
+ cbegroup = (*callpat >= OP_SBRA);
+ do
+ {
+ if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
+ md, eptrb, RM6);
+ memcpy(md->offset_vector, new_recursive.offset_save,
+ new_recursive.saved_max * sizeof(int));
+ md->recursive = new_recursive.prevrec;
+ if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
+ {
+ DPRINTF(("Recursion matched\n"));
+ if (new_recursive.offset_save != stacksave)
+ (PUBL(free))(new_recursive.offset_save);
+
+ /* Set where we got to in the subject, and reset the start in case
+ it was changed by \K. This *is* propagated back out of a recursion,
+ for Perl compatibility. */
+
+ eptr = md->end_match_ptr;
+ mstart = md->start_match_ptr;
+ goto RECURSION_MATCHED; /* Exit loop; end processing */
+ }
+
+ /* PCRE does not allow THEN to escape beyond a recursion; it is treated
+ as NOMATCH. */
+
+ else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+ {
+ DPRINTF(("Recursion gave error %d\n", rrc));
+ if (new_recursive.offset_save != stacksave)
+ (PUBL(free))(new_recursive.offset_save);
+ RRETURN(rrc);
+ }
+
+ md->recursive = &new_recursive;
+ callpat += GET(callpat, 1);
+ }
+ while (*callpat == OP_ALT);
+
+ DPRINTF(("Recursion didn't match\n"));
+ md->recursive = new_recursive.prevrec;
+ if (new_recursive.offset_save != stacksave)
+ (PUBL(free))(new_recursive.offset_save);
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ RECURSION_MATCHED:
+ break;
+
+ /* An alternation is the end of a branch; scan along to find the end of the
+ bracketed group and go to there. */
+
+ case OP_ALT:
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ break;
+
+ /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
+ indicating that it may occur zero times. It may repeat infinitely, or not
+ at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
+ with fixed upper repeat limits are compiled as a number of copies, with the
+ optional ones preceded by BRAZERO or BRAMINZERO. */
+
+ case OP_BRAZERO:
+ next = ecode + 1;
+ RMATCH(eptr, next, offset_top, md, eptrb, RM10);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ do next += GET(next, 1); while (*next == OP_ALT);
+ ecode = next + 1 + LINK_SIZE;
+ break;
+
+ case OP_BRAMINZERO:
+ next = ecode + 1;
+ do next += GET(next, 1); while (*next == OP_ALT);
+ RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, eptrb, RM11);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ ecode++;
+ break;
+
+ case OP_SKIPZERO:
+ next = ecode+1;
+ do next += GET(next,1); while (*next == OP_ALT);
+ ecode = next + 1 + LINK_SIZE;
+ break;
+
+ /* BRAPOSZERO occurs before a possessive bracket group. Don't do anything
+ here; just jump to the group, with allow_zero set TRUE. */
+
+ case OP_BRAPOSZERO:
+ op = *(++ecode);
+ allow_zero = TRUE;
+ if (op == OP_CBRAPOS || op == OP_SCBRAPOS) goto POSSESSIVE_CAPTURE;
+ goto POSSESSIVE_NON_CAPTURE;
+
+ /* End of a group, repeated or non-repeating. */
+
+ case OP_KET:
+ case OP_KETRMIN:
+ case OP_KETRMAX:
+ case OP_KETRPOS:
+ prev = ecode - GET(ecode, 1);
+
+ /* If this was a group that remembered the subject start, in order to break
+ infinite repeats of empty string matches, retrieve the subject start from
+ the chain. Otherwise, set it NULL. */
+
+ if (*prev >= OP_SBRA || *prev == OP_ONCE)
+ {
+ saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
+ eptrb = eptrb->epb_prev; /* Backup to previous group */
+ }
+ else saved_eptr = NULL;
+
+ /* If we are at the end of an assertion group or a non-capturing atomic
+ group, stop matching and return MATCH_MATCH, but record the current high
+ water mark for use by positive assertions. We also need to record the match
+ start in case it was changed by \K. */
+
+ if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
+ *prev == OP_ONCE_NC)
+ {
+ md->end_match_ptr = eptr; /* For ONCE_NC */
+ md->end_offset_top = offset_top;
+ md->start_match_ptr = mstart;
+ RRETURN(MATCH_MATCH); /* Sets md->mark */
+ }
+
+ /* For capturing groups we have to check the group number back at the start
+ and if necessary complete handling an extraction by setting the offsets and
+ bumping the high water mark. Whole-pattern recursion is coded as a recurse
+ into group 0, so it won't be picked up here. Instead, we catch it when the
+ OP_END is reached. Other recursion is handled here. We just have to record
+ the current subject position and start match pointer and give a MATCH
+ return. */
+
+ if (*prev == OP_CBRA || *prev == OP_SCBRA ||
+ *prev == OP_CBRAPOS || *prev == OP_SCBRAPOS)
+ {
+ number = GET2(prev, 1+LINK_SIZE);
+ offset = number << 1;
+
+#ifdef PCRE_DEBUG
+ printf("end bracket %d", number);
+ printf("\n");
+#endif
+
+ /* Handle a recursively called group. */
+
+ if (md->recursive != NULL && md->recursive->group_num == number)
+ {
+ md->end_match_ptr = eptr;
+ md->start_match_ptr = mstart;
+ RRETURN(MATCH_MATCH);
+ }
+
+ /* Deal with capturing */
+
+ md->capture_last = number;
+ if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ {
+ /* If offset is greater than offset_top, it means that we are
+ "skipping" a capturing group, and that group's offsets must be marked
+ unset. In earlier versions of PCRE, all the offsets were unset at the
+ start of matching, but this doesn't work because atomic groups and
+ assertions can cause a value to be set that should later be unset.
+ Example: matching /(?>(a))b|(a)c/ against "ac". This sets group 1 as
+ part of the atomic group, but this is not on the final matching path,
+ so must be unset when 2 is set. (If there is no group 2, there is no
+ problem, because offset_top will then be 2, indicating no capture.) */
+
+ if (offset > offset_top)
+ {
+ register int *iptr = md->offset_vector + offset_top;
+ register int *iend = md->offset_vector + offset;
+ while (iptr < iend) *iptr++ = -1;
+ }
+
+ /* Now make the extraction */
+
+ md->offset_vector[offset] =
+ md->offset_vector[md->offset_end - number];
+ md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
+ if (offset_top <= offset) offset_top = offset + 2;
+ }
+ }
+
+ /* For an ordinary non-repeating ket, just continue at this level. This
+ also happens for a repeating ket if no characters were matched in the
+ group. This is the forcible breaking of infinite loops as implemented in
+ Perl 5.005. For a non-repeating atomic group that includes captures,
+ establish a backup point by processing the rest of the pattern at a lower
+ level. If this results in a NOMATCH return, pass MATCH_ONCE back to the
+ original OP_ONCE level, thereby bypassing intermediate backup points, but
+ resetting any captures that happened along the way. */
+
+ if (*ecode == OP_KET || eptr == saved_eptr)
+ {
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM12);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ ecode += 1 + LINK_SIZE; /* Carry on at this level */
+ break;
+ }
+
+ /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
+ and return the MATCH_KETRPOS. This makes it possible to do the repeats one
+ at a time from the outer level, thus saving stack. */
+
+ if (*ecode == OP_KETRPOS)
+ {
+ md->end_match_ptr = eptr;
+ md->end_offset_top = offset_top;
+ RRETURN(MATCH_KETRPOS);
+ }
+
+ /* The normal repeating kets try the rest of the pattern or restart from
+ the preceding bracket, in the appropriate order. In the second case, we can
+ use tail recursion to avoid using another stack frame, unless we have an
+ an atomic group or an unlimited repeat of a group that can match an empty
+ string. */
+
+ if (*ecode == OP_KETRMIN)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM7);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM8);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev; /* Level at which to change to MATCH_NOMATCH */
+ RRETURN(MATCH_ONCE);
+ }
+ if (*prev >= OP_SBRA) /* Could match an empty string */
+ {
+ md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
+ RRETURN(rrc);
+ }
+ ecode = prev;
+ goto TAIL_RECURSE;
+ }
+ else /* OP_KETRMAX */
+ {
+ if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
+ RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
+ if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (*prev == OP_ONCE)
+ {
+ RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM9);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ md->once_target = prev;
+ RRETURN(MATCH_ONCE);
+ }
+ ecode += 1 + LINK_SIZE;
+ goto TAIL_RECURSE;
+ }
+ /* Control never gets here */
+
+ /* Not multiline mode: start of subject assertion, unless notbol. */
+
+ case OP_CIRC:
+ if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
+
+ /* Start of subject assertion */
+
+ case OP_SOD:
+ if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Multiline mode: start of subject unless notbol, or after any newline. */
+
+ case OP_CIRCM:
+ if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
+ if (eptr != md->start_subject &&
+ (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Start of match assertion */
+
+ case OP_SOM:
+ if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ /* Reset the start of match point */
+
+ case OP_SET_SOM:
+ mstart = eptr;
+ ecode++;
+ break;
+
+ /* Multiline mode: assert before any newline, or before end of subject
+ unless noteol is set. */
+
+ case OP_DOLLM:
+ if (eptr < md->end_subject)
+ { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
+ else
+ {
+ if (md->noteol) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ }
+ ecode++;
+ break;
+
+ /* Not multiline mode: assert before a terminating newline or before end of
+ subject unless noteol is set. */
+
+ case OP_DOLL:
+ if (md->noteol) RRETURN(MATCH_NOMATCH);
+ if (!md->endonly) goto ASSERT_NL_OR_EOS;
+
+ /* ... else fall through for endonly */
+
+ /* End of subject assertion (\z) */
+
+ case OP_EOD:
+ if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
+ SCHECK_PARTIAL();
+ ecode++;
+ break;
+
+ /* End of subject or ending \n assertion (\Z) */
+
+ case OP_EODN:
+ ASSERT_NL_OR_EOS:
+ if (eptr < md->end_subject &&
+ (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
+ RRETURN(MATCH_NOMATCH);
+
+ /* Either at end of string or \n before end. */
+
+ SCHECK_PARTIAL();
+ ecode++;
+ break;
+
+ /* Word boundary assertions */
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ {
+
+ /* Find out if the previous and current characters are "word" characters.
+ It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
+ be "non-word" characters. Remember the earliest consulted character for
+ partial matching. */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ /* Get status of previous character */
+
+ if (eptr == md->start_subject) prev_is_word = FALSE; else
+ {
+ PCRE_PUCHAR lastptr = eptr - 1;
+ BACKCHAR(lastptr);
+ if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
+ GETCHAR(c, lastptr);
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ if (c == '_') prev_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ prev_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
+ }
+
+ /* Get status of next character */
+
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ cur_is_word = FALSE;
+ }
+ else
+ {
+ GETCHAR(c, eptr);
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ if (c == '_') cur_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ cur_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
+ }
+ }
+ else
+#endif
+
+ /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
+ consistency with the behaviour of \w we do use it in this case. */
+
+ {
+ /* Get status of previous character */
+
+ if (eptr == md->start_subject) prev_is_word = FALSE; else
+ {
+ if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ c = eptr[-1];
+ if (c == '_') prev_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ prev_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ prev_is_word = MAX_255(eptr[-1])
+ && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
+ }
+
+ /* Get status of next character */
+
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ cur_is_word = FALSE;
+ }
+ else
+#ifdef SUPPORT_UCP
+ if (md->use_ucp)
+ {
+ c = *eptr;
+ if (c == '_') cur_is_word = TRUE; else
+ {
+ int cat = UCD_CATEGORY(c);
+ cur_is_word = (cat == ucp_L || cat == ucp_N);
+ }
+ }
+ else
+#endif
+ cur_is_word = MAX_255(*eptr)
+ && ((md->ctypes[*eptr] & ctype_word) != 0);
+ }
+
+ /* Now see if the situation is what we want */
+
+ if ((*ecode++ == OP_WORD_BOUNDARY)?
+ cur_is_word == prev_is_word : cur_is_word != prev_is_word)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* Match a single character type; inline for speed */
+
+ case OP_ANY:
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ /* Fall through */
+
+ case OP_ALLANY:
+ if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+#ifdef SUPPORT_UTF
+ if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+#endif
+ ecode++;
+ break;
+
+ /* Match a single byte, even in UTF-8 mode. This opcode really does match
+ any byte, even newline, independent of the setting of PCRE_DOTALL. */
+
+ case OP_ANYBYTE:
+ if (eptr >= md->end_subject) /* DO NOT merge the eptr++ here; it must */
+ { /* not be updated before SCHECK_PARTIAL. */
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+ ecode++;
+ break;
+
+ case OP_NOT_DIGIT:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c < 256 &&
+#endif
+ (md->ctypes[c] & ctype_digit) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_DIGIT:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
+#endif
+ (md->ctypes[c] & ctype_digit) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c < 256 &&
+#endif
+ (md->ctypes[c] & ctype_space) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_WHITESPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
+#endif
+ (md->ctypes[c] & ctype_space) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c < 256 &&
+#endif
+ (md->ctypes[c] & ctype_word) != 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_WORDCHAR:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (
+#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
+ c > 255 ||
+#endif
+ (md->ctypes[c] & ctype_word) == 0
+ )
+ RRETURN(MATCH_NOMATCH);
+ ecode++;
+ break;
+
+ case OP_ANYNL:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ ecode++;
+ break;
+
+ case OP_NOT_HSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ break;
+
+ case OP_HSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+ }
+ ecode++;
+ break;
+
+ case OP_NOT_VSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ break;
+
+ case OP_VSPACE:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ break;
+ }
+ ecode++;
+ break;
+
+#ifdef SUPPORT_UCP
+ /* Check the next character by Unicode property. We will get here only
+ if the support is in the binary; otherwise a compile-time error occurs. */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ {
+ const ucd_record *prop = GET_UCD(c);
+
+ switch(ecode[1])
+ {
+ case PT_ANY:
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_LAMP:
+ if ((prop->chartype == ucp_Lu ||
+ prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_GC:
+ if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_PC:
+ if ((ecode[2] != prop->chartype) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_SC:
+ if ((ecode[2] != prop->script) == (op == OP_PROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* These are specials */
+
+ case PT_ALNUM:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_SPACE: /* Perl space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
+ == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR)
+ == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case PT_WORD:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ /* This should never occur */
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ ecode += 3;
+ }
+ break;
+
+ /* Match an extended Unicode sequence. We will get here only if the support
+ is in the binary; otherwise a compile-time error occurs. */
+
+ case OP_EXTUNI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ ecode++;
+ break;
+#endif
+
+
+ /* Match a back reference, possibly repeatedly. Look past the end of the
+ item to see if there is repeat information following. The code is similar
+ to that for character classes, but repeated for efficiency. Then obey
+ similar code to character type repeats - written out again for speed.
+ However, if the referenced string is the empty string, always treat
+ it as matched, any number of times (otherwise there could be infinite
+ loops). */
+
+ case OP_REF:
+ case OP_REFI:
+ caseless = op == OP_REFI;
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ ecode += 1 + IMM2_SIZE;
+
+ /* If the reference is unset, there are two possibilities:
+
+ (a) In the default, Perl-compatible state, set the length negative;
+ this ensures that every attempt at a match fails. We can't just fail
+ here, because of the possibility of quantifiers with zero minima.
+
+ (b) If the JavaScript compatibility flag is set, set the length to zero
+ so that the back reference matches an empty string.
+
+ Otherwise, set the length to the length of what was matched by the
+ referenced subpattern. */
+
+ if (offset >= offset_top || md->offset_vector[offset] < 0)
+ length = (md->jscript_compat)? 0 : -1;
+ else
+ length = md->offset_vector[offset+1] - md->offset_vector[offset];
+
+ /* Set up for repetition, or handle the non-repeated case */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += length;
+ continue; /* With the main loop */
+ }
+
+ /* Handle repeated back references. If the length of the reference is
+ zero, just continue with the main loop. If the length is negative, it
+ means the reference is unset in non-Java-compatible mode. If the minimum is
+ zero, we can continue at the same level without recursion. For any other
+ minimum, carrying on will result in NOMATCH. */
+
+ if (length == 0) continue;
+ if (length < 0 && min == 0) continue;
+
+ /* First, ensure the minimum number of matches are present. We get back
+ the length of the reference string explicitly rather than passing the
+ address of eptr, so that eptr can be a register variable. */
+
+ for (i = 1; i <= min; i++)
+ {
+ int slength;
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += slength;
+ }
+
+ /* If min = max, continue at the same level without recursion.
+ They are not both allowed to be zero. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep trying and advancing the pointer */
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ int slength;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += slength;
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest string and work backwards */
+
+ else
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ int slength;
+ if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
+ {
+ CHECK_PARTIAL();
+ break;
+ }
+ eptr += slength;
+ }
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr -= length;
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* Match a bit-mapped character class, possibly repeatedly. This op code is
+ used when all the characters in the class have values in the range 0-255,
+ and either the matching is caseful, or the characters are in the range
+ 0-127 when UTF-8 processing is enabled. The only difference between
+ OP_CLASS and OP_NCLASS occurs when a data character outside the range is
+ encountered.
+
+ First, look past the end of the item to see if there is repeat information
+ following. Then obey similar code to character type repeats - written out
+ again for speed. */
+
+ case OP_NCLASS:
+ case OP_CLASS:
+ {
+ /* The data variable is saved across frames, so the byte map needs to
+ be stored there. */
+#define BYTE_MAP ((pcre_uint8 *)data)
+ data = ecode + 1; /* Save for matching */
+ ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ min = max = 1;
+ break;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ c = *eptr++;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ /* If max == min we can continue with the main loop without the
+ need to recurse. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep testing the rest of the expression and advancing
+ the pointer while it matches the class. */
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ c = *eptr++;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest possible run, then work backwards. */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
+ eptr += len;
+ }
+ for (;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+#ifndef COMPILE_PCRE8
+ if (c > 255)
+ {
+ if (op == OP_CLASS) break;
+ }
+ else
+#endif
+ if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
+ eptr++;
+ }
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+#undef BYTE_MAP
+ }
+ /* Control never gets here */
+
+
+ /* Match an extended character class. This opcode is encountered only
+ when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
+ mode, because Unicode properties are supported in non-UTF-8 mode. */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ {
+ data = ecode + 1 + LINK_SIZE; /* Save for matching */
+ ecode += GET(ecode, 1); /* Advance past the item */
+
+ switch (*ecode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ c = *ecode++ - OP_CRSTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ minimize = (*ecode == OP_CRMINRANGE);
+ min = GET2(ecode, 1);
+ max = GET2(ecode, 1 + IMM2_SIZE);
+ if (max == 0) max = INT_MAX;
+ ecode += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default: /* No repeat follows */
+ min = max = 1;
+ break;
+ }
+
+ /* First, ensure the minimum number of matches are present. */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
+ }
+
+ /* If max == min we can continue with the main loop without the
+ need to recurse. */
+
+ if (min == max) continue;
+
+ /* If minimizing, keep testing the rest of the expression and advancing
+ the pointer while it matches the class. */
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, find the longest possible run, then work backwards. */
+
+ else
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+#ifdef SUPPORT_UTF
+ GETCHARLENTEST(c, eptr, len);
+#else
+ c = *eptr;
+#endif
+ if (!PRIV(xclass)(c, data, utf)) break;
+ eptr += len;
+ }
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+#ifdef SUPPORT_UTF
+ if (utf) BACKCHAR(eptr);
+#endif
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+
+ /* Control never gets here */
+ }
+#endif /* End of XCLASS */
+
+ /* Match a single character, casefully */
+
+ case OP_CHAR:
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ length = 1;
+ ecode++;
+ GETCHARLEN(fc, ecode, length);
+ if (length > md->end_subject - eptr)
+ {
+ CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
+ RRETURN(MATCH_NOMATCH);
+ }
+ while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ if (md->end_subject - eptr < 1)
+ {
+ SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
+ ecode += 2;
+ }
+ break;
+
+ /* Match a single character, caselessly. If we are at the end of the
+ subject, give up immediately. */
+
+ case OP_CHARI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ length = 1;
+ ecode++;
+ GETCHARLEN(fc, ecode, length);
+
+ /* If the pattern character's value is < 128, we have only one byte, and
+ we know that its other case must also be one byte long, so we can use the
+ fast lookup table. We know that there is at least one byte left in the
+ subject. */
+
+ if (fc < 128)
+ {
+ if (md->lcc[fc]
+ != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ ecode++;
+ eptr++;
+ }
+
+ /* Otherwise we must pick up the subject character. Note that we cannot
+ use the value of "length" to check for sufficient bytes left, because the
+ other case of the character may have more or fewer bytes. */
+
+ else
+ {
+ unsigned int dc;
+ GETCHARINC(dc, eptr);
+ ecode += length;
+
+ /* If we have Unicode property support, we can use it to test the other
+ case of the character, if there is one. */
+
+ if (fc != dc)
+ {
+#ifdef SUPPORT_UCP
+ if (dc != UCD_OTHERCASE(fc))
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+
+ /* Not UTF mode */
+ {
+ if (TABLE_GET(ecode[1], md->lcc, ecode[1])
+ != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ecode += 2;
+ }
+ break;
+
+ /* Match a single character repeatedly. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ min = max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATCHAR;
+
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ possessive = TRUE;
+ /* Fall through */
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATCHAR;
+
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATCHAR;
+
+ case OP_STAR:
+ case OP_STARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ c = *ecode++ - ((op < OP_STARI)? OP_STAR : OP_STARI);
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single-character matches. */
+
+ REPEATCHAR:
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ length = 1;
+ charptr = ecode;
+ GETCHARLEN(fc, ecode, length);
+ ecode += length;
+
+ /* Handle multibyte character matching specially here. There is
+ support for caseless matching if UCP support is present. */
+
+ if (length > 1)
+ {
+#ifdef SUPPORT_UCP
+ unsigned int othercase;
+ if (op >= OP_STARI && /* Caseless */
+ (othercase = UCD_OTHERCASE(fc)) != fc)
+ oclength = PRIV(ord2utf)(othercase, occhars);
+ else oclength = 0;
+#endif /* SUPPORT_UCP */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr <= md->end_subject - length &&
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+ else if (oclength > 0 &&
+ eptr <= md->end_subject - oclength &&
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
+#endif /* SUPPORT_UCP */
+ else
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr <= md->end_subject - length &&
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+ else if (oclength > 0 &&
+ eptr <= md->end_subject - oclength &&
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
+#endif /* SUPPORT_UCP */
+ else
+ {
+ CHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr <= md->end_subject - length &&
+ memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+ else if (oclength > 0 &&
+ eptr <= md->end_subject - oclength &&
+ memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
+#endif /* SUPPORT_UCP */
+ else
+ {
+ CHECK_PARTIAL();
+ break;
+ }
+ }
+
+ if (possessive) continue;
+
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
+#ifdef SUPPORT_UCP
+ eptr--;
+ BACKCHAR(eptr);
+#else /* without SUPPORT_UCP */
+ eptr -= length;
+#endif /* SUPPORT_UCP */
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If the length of a UTF-8 character is 1, we fall through here, and
+ obey the code as for non-UTF-8 characters below, though in this case the
+ value of fc will always be < 128. */
+ }
+ else
+#endif /* SUPPORT_UTF */
+ /* When not in UTF-8 mode, load a single-byte character. */
+ fc = *ecode++;
+
+ /* The value of fc at this point is always one character, though we may
+ or may not be in UTF mode. The code is duplicated for the caseless and
+ caseful cases, for speed, since matching characters is likely to be quite
+ common. First, ensure the minimum number of matches are present. If min =
+ max, continue at the same level without recursing. Otherwise, if
+ minimizing, keep trying the rest of the expression and advancing one
+ matching character if failing, up to the maximum. Alternatively, if
+ maximizing, find the maximum number of characters and work backwards. */
+
+ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
+ max, eptr));
+
+ if (op >= OP_STARI) /* Caseless */
+ {
+#ifdef COMPILE_PCRE8
+ /* fc must be < 128 if UTF is enabled. */
+ foc = md->fcc[fc];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+#else
+ if (utf && fc > 127)
+ foc = fc;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ foc = TABLE_GET(fc, md->fcc, fc);
+#endif /* COMPILE_PCRE8 */
+
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ if (min == max) continue;
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ /* Control never gets here */
+ }
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc != *eptr && foc != *eptr) break;
+ eptr++;
+ }
+
+ if (possessive) continue;
+
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
+ eptr--;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* Caseful comparisons (includes all multi-byte characters) */
+
+ else
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+ else /* Maximize */
+ {
+ pp = eptr;
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc != *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue;
+
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
+ eptr--;
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ }
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+
+ /* Match a negated single one-byte character. The character we are
+ checking can be multibyte. */
+
+ case OP_NOT:
+ case OP_NOTI:
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ ecode++;
+ GETCHARINCTEST(c, eptr);
+ if (op == OP_NOTI) /* The caseless case */
+ {
+ register unsigned int ch, och;
+ ch = *ecode++;
+#ifdef COMPILE_PCRE8
+ /* ch must be < 128 if UTF is enabled. */
+ och = md->fcc[ch];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && ch > 127)
+ och = UCD_OTHERCASE(ch);
+#else
+ if (utf && ch > 127)
+ och = ch;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ och = TABLE_GET(ch, md->fcc, ch);
+#endif /* COMPILE_PCRE8 */
+ if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
+ }
+ else /* Caseful */
+ {
+ if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* Match a negated single one-byte character repeatedly. This is almost a
+ repeat of the code for a repeated single character, but I haven't found a
+ nice way of commoning these up that doesn't require a test of the
+ positive/negative option for each character match. Maybe that wouldn't add
+ very much to the time taken, but character matching *is* what this is all
+ about... */
+
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ min = max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ possessive = TRUE;
+ min = 0;
+ max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATNOTCHAR;
+
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ c = *ecode++ - ((op >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single-byte matches. */
+
+ REPEATNOTCHAR:
+ fc = *ecode++;
+
+ /* The code is duplicated for the caseless and caseful cases, for speed,
+ since matching characters is likely to be quite common. First, ensure the
+ minimum number of matches are present. If min = max, continue at the same
+ level without recursing. Otherwise, if minimizing, keep trying the rest of
+ the expression and advancing one matching character if failing, up to the
+ maximum. Alternatively, if maximizing, find the maximum number of
+ characters and work backwards. */
+
+ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
+ max, eptr));
+
+ if (op >= OP_NOTSTARI) /* Caseless */
+ {
+#ifdef COMPILE_PCRE8
+ /* fc must be < 128 if UTF is enabled. */
+ foc = md->fcc[fc];
+#else
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ if (utf && fc > 127)
+ foc = UCD_OTHERCASE(fc);
+#else
+ if (utf && fc > 127)
+ foc = fc;
+#endif /* SUPPORT_UCP */
+ else
+#endif /* SUPPORT_UTF */
+ foc = TABLE_GET(fc, md->fcc, fc);
+#endif /* COMPILE_PCRE8 */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* Maximize case */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(d, eptr, len);
+ if (fc == d || (unsigned int)foc == d) break;
+ eptr += len;
+ }
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc == *eptr || foc == *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue;
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+ }
+
+ /* Caseful comparisons */
+
+ else
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ }
+
+ if (min == max) continue;
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(d, eptr);
+ if (fc == d) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* Maximize case */
+
+ else
+ {
+ pp = eptr;
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ register unsigned int d;
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(d, eptr, len);
+ if (fc == d) break;
+ eptr += len;
+ }
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (fc == *eptr) break;
+ eptr++;
+ }
+ if (possessive) continue;
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ }
+ }
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ /* Control never gets here */
+
+ /* Match a single character type repeatedly; several different opcodes
+ share code. This is very similar to the code for single characters, but we
+ repeat it in the interests of efficiency. */
+
+ case OP_TYPEEXACT:
+ min = max = GET2(ecode, 1);
+ minimize = TRUE;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ min = 0;
+ max = GET2(ecode, 1);
+ minimize = *ecode == OP_TYPEMINUPTO;
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSSTAR:
+ possessive = TRUE;
+ min = 0;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSPLUS:
+ possessive = TRUE;
+ min = 1;
+ max = INT_MAX;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSQUERY:
+ possessive = TRUE;
+ min = 0;
+ max = 1;
+ ecode++;
+ goto REPEATTYPE;
+
+ case OP_TYPEPOSUPTO:
+ possessive = TRUE;
+ min = 0;
+ max = GET2(ecode, 1);
+ ecode += 1 + IMM2_SIZE;
+ goto REPEATTYPE;
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ c = *ecode++ - OP_TYPESTAR;
+ minimize = (c & 1) != 0;
+ min = rep_min[c]; /* Pick up values from tables; */
+ max = rep_max[c]; /* zero for max => infinity */
+ if (max == 0) max = INT_MAX;
+
+ /* Common code for all repeated single character type matches. Note that
+ in UTF-8 mode, '.' matches a character of any length, but for the other
+ character types, the valid characters are all one-byte long. */
+
+ REPEATTYPE:
+ ctype = *ecode++; /* Code for the character type */
+
+#ifdef SUPPORT_UCP
+ if (ctype == OP_PROP || ctype == OP_NOTPROP)
+ {
+ prop_fail_result = ctype == OP_NOTPROP;
+ prop_type = *ecode++;
+ prop_value = *ecode++;
+ }
+ else prop_type = -1;
+#endif
+
+ /* First, ensure the minimum number of matches are present. Use inline
+ code for maximizing the speed, and do the type test once at the start
+ (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
+ is tidier. Also separate the UCP code, which can be the same for both UTF-8
+ and single-bytes. */
+
+ if (min > 0)
+ {
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ }
+ break;
+
+ case PT_LAMP:
+ for (i = 1; i <= min; i++)
+ {
+ int chartype;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_GC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_PC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_SC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_ALNUM:
+ for (i = 1; i <= min; i++)
+ {
+ int category;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_SPACE: /* Perl space */
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case PT_WORD:
+ for (i = 1; i <= min; i++)
+ {
+ int category;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ /* This should not occur */
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UCP */
+
+/* Handle all other cases when the coding is UTF-8 */
+
+#ifdef SUPPORT_UTF
+ if (utf) switch(ctype)
+ {
+ case OP_ANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ALLANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_ANYBYTE:
+ if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
+ eptr += min;
+ break;
+
+ case OP_ANYNL:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINC(c, eptr);
+ if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ /* No need to skip more bytes - we know it's a 1-byte character */
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ } /* End switch(ctype) */
+
+ else
+#endif /* SUPPORT_UTF */
+
+ /* Code for the non-UTF-8 case for minimum matching of operators other
+ than OP_PROP and OP_NOTPROP. */
+
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_ALLANY:
+ if (eptr > md->end_subject - min)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += min;
+ break;
+
+ case OP_ANYBYTE:
+ if (eptr > md->end_subject - min)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ eptr += min;
+ break;
+
+ case OP_ANYNL:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+#ifdef COMPILE_PCRE16
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ switch(*eptr++)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ break;
+ }
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ eptr++;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+
+ /* If min = max, continue at the same level without recursing */
+
+ if (min == max) continue;
+
+ /* If minimizing, we have to test the rest of the pattern before each
+ subsequent match. Again, separate the UTF-8 case for speed, and also
+ separate the UCP cases. */
+
+ if (minimize)
+ {
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_LAMP:
+ for (fi = min;; fi++)
+ {
+ int chartype;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_GC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_PC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_SC:
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_ALNUM:
+ for (fi = min;; fi++)
+ {
+ int category;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_SPACE: /* Perl space */
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_PXSPACE: /* POSIX space */
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ case PT_WORD:
+ for (fi = min;; fi++)
+ {
+ int category;
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L ||
+ category == ucp_N ||
+ c == CHAR_UNDERSCORE)
+ == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* This should never occur */
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM41);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);
+ while (eptr < md->end_subject)
+ {
+ int len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ }
+ }
+ else
+#endif /* SUPPORT_UCP */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM42);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ctype == OP_ANY && IS_NEWLINE(eptr))
+ RRETURN(MATCH_NOMATCH);
+ GETCHARINC(c, eptr);
+ switch(ctype)
+ {
+ case OP_ANY: /* This is the non-NL case */
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ break;
+
+ case OP_ANYNL:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+ case 0x2028:
+ case 0x2029:
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_HSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_VSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ break;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_DIGIT:
+ if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WHITESPACE:
+ if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WORDCHAR:
+ if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
+ RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+ }
+ else
+#endif
+ /* Not UTF mode */
+ {
+ for (fi = min;; fi++)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM43);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (fi >= max) RRETURN(MATCH_NOMATCH);
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ if (ctype == OP_ANY && IS_NEWLINE(eptr))
+ RRETURN(MATCH_NOMATCH);
+ c = *eptr++;
+ switch(ctype)
+ {
+ case OP_ANY: /* This is the non-NL case */
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ break;
+
+ case OP_ANYNL:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x000d:
+ if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+ break;
+
+ case 0x000a:
+ break;
+
+ case 0x000b:
+ case 0x000c:
+ case 0x0085:
+#ifdef COMPILE_PCRE16
+ case 0x2028:
+ case 0x2029:
+#endif
+ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+ break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_HSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+#ifdef COMPILE_PCRE16
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+#endif
+ break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(c)
+ {
+ default: break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
+ case OP_VSPACE:
+ switch(c)
+ {
+ default: RRETURN(MATCH_NOMATCH);
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+#ifdef COMPILE_PCRE16
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+#endif
+ break;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_DIGIT:
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WHITESPACE:
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ case OP_WORDCHAR:
+ if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+ }
+ }
+ /* Control never gets here */
+ }
+
+ /* If maximizing, it is worth using inline code for speed, doing the type
+ test once at the start (i.e. keep it out of the loop). Again, keep the
+ UTF-8 and UCP stuff separate. */
+
+ else
+ {
+ pp = eptr; /* Remember where we started */
+
+#ifdef SUPPORT_UCP
+ if (prop_type >= 0)
+ {
+ switch(prop_type)
+ {
+ case PT_ANY:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if (prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_LAMP:
+ for (i = min; i < max; i++)
+ {
+ int chartype;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ chartype = UCD_CHARTYPE(c);
+ if ((chartype == ucp_Lu ||
+ chartype == ucp_Ll ||
+ chartype == ucp_Lt) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_GC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_PC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_SC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result) break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_ALNUM:
+ for (i = min; i < max; i++)
+ {
+ int category;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_SPACE: /* Perl space */
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
+ c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
+ == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ case PT_WORD:
+ for (i = min; i < max; i++)
+ {
+ int category;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ category = UCD_CATEGORY(c);
+ if ((category == ucp_L || category == ucp_N ||
+ c == CHAR_UNDERSCORE) == prop_fail_result)
+ break;
+ eptr+= len;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run */
+
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ if (utf) BACKCHAR(eptr);
+ }
+ }
+
+ /* Match extended Unicode sequences. We will get here only if the
+ support is in the binary; otherwise a compile-time error occurs. */
+
+ else if (ctype == OP_EXTUNI)
+ {
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) == ucp_M) break;
+ eptr += len;
+ while (eptr < md->end_subject)
+ {
+ len = 1;
+ if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr += len;
+ }
+ }
+
+ /* eptr is now past the end of the maximum run */
+
+ if (possessive) continue;
+
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ for (;;) /* Move back over one extended */
+ {
+ if (!utf) c = *eptr; else
+ {
+ BACKCHAR(eptr);
+ GETCHAR(c, eptr);
+ }
+ if (UCD_CATEGORY(c) != ucp_M) break;
+ eptr--;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UCP */
+
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ switch(ctype)
+ {
+ case OP_ANY:
+ if (max < INT_MAX)
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ }
+
+ /* Handle unlimited UTF-8 repeat */
+
+ else
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ }
+ break;
+
+ case OP_ALLANY:
+ if (max < INT_MAX)
+ {
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ eptr++;
+ ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
+ }
+ }
+ else
+ {
+ eptr = md->end_subject; /* Unlimited UTF-8 repeat */
+ SCHECK_PARTIAL();
+ }
+ break;
+
+ /* The byte case is the same as non-UTF8 */
+
+ case OP_ANYBYTE:
+ c = max - min;
+ if (c > (unsigned int)(md->end_subject - eptr))
+ {
+ eptr = md->end_subject;
+ SCHECK_PARTIAL();
+ }
+ else eptr += c;
+ break;
+
+ case OP_ANYNL:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c == 0x000d)
+ {
+ if (++eptr >= md->end_subject) break;
+ if (*eptr == 0x000a) eptr++;
+ }
+ else
+ {
+ if (c != 0x000a &&
+ (md->bsr_anycrlf ||
+ (c != 0x000b && c != 0x000c &&
+ c != 0x0085 && c != 0x2028 && c != 0x2029)))
+ break;
+ eptr += len;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ BOOL gotspace;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ switch(c)
+ {
+ default: gotspace = FALSE; break;
+ case 0x09: /* HT */
+ case 0x20: /* SPACE */
+ case 0xa0: /* NBSP */
+ case 0x1680: /* OGHAM SPACE MARK */
+ case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
+ case 0x2000: /* EN QUAD */
+ case 0x2001: /* EM QUAD */
+ case 0x2002: /* EN SPACE */
+ case 0x2003: /* EM SPACE */
+ case 0x2004: /* THREE-PER-EM SPACE */
+ case 0x2005: /* FOUR-PER-EM SPACE */
+ case 0x2006: /* SIX-PER-EM SPACE */
+ case 0x2007: /* FIGURE SPACE */
+ case 0x2008: /* PUNCTUATION SPACE */
+ case 0x2009: /* THIN SPACE */
+ case 0x200A: /* HAIR SPACE */
+ case 0x202f: /* NARROW NO-BREAK SPACE */
+ case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
+ case 0x3000: /* IDEOGRAPHIC SPACE */
+ gotspace = TRUE;
+ break;
+ }
+ if (gotspace == (ctype == OP_NOT_HSPACE)) break;
+ eptr += len;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ BOOL gotspace;
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ switch(c)
+ {
+ default: gotspace = FALSE; break;
+ case 0x0a: /* LF */
+ case 0x0b: /* VT */
+ case 0x0c: /* FF */
+ case 0x0d: /* CR */
+ case 0x85: /* NEL */
+ case 0x2028: /* LINE SEPARATOR */
+ case 0x2029: /* PARAGRAPH SEPARATOR */
+ gotspace = TRUE;
+ break;
+ }
+ if (gotspace == (ctype == OP_NOT_VSPACE)) break;
+ eptr += len;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
+ eptr+= len;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLEN(c, eptr, len);
+ if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
+ eptr+= len;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run. If possessive, we are
+ done (no backing up). Otherwise, match at this position; anything other
+ than no match is immediately returned. For nomatch, back up one
+ character, unless we are matching \R and the last thing matched was
+ \r\n, in which case, back up two bytes. */
+
+ if (possessive) continue;
+ for(;;)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ if (eptr-- == pp) break; /* Stop if tried at original pos */
+ BACKCHAR(eptr);
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
+ eptr[-1] == '\r') eptr--;
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ /* Not UTF mode */
+ {
+ switch(ctype)
+ {
+ case OP_ANY:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (IS_NEWLINE(eptr)) break;
+ eptr++;
+ }
+ break;
+
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ c = max - min;
+ if (c > (unsigned int)(md->end_subject - eptr))
+ {
+ eptr = md->end_subject;
+ SCHECK_PARTIAL();
+ }
+ else eptr += c;
+ break;
+
+ case OP_ANYNL:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == 0x000d)
+ {
+ if (++eptr >= md->end_subject) break;
+ if (*eptr == 0x000a) eptr++;
+ }
+ else
+ {
+ if (c != 0x000a && (md->bsr_anycrlf ||
+ (c != 0x000b && c != 0x000c && c != 0x0085
+#ifdef COMPILE_PCRE16
+ && c != 0x2028 && c != 0x2029
+#endif
+ ))) break;
+ eptr++;
+ }
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == 0x09 || c == 0x20 || c == 0xa0
+#ifdef COMPILE_PCRE16
+ || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
+ || c == 0x202f || c == 0x205f || c == 0x3000
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_HSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c != 0x09 && c != 0x20 && c != 0xa0
+#ifdef COMPILE_PCRE16
+ && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
+ && c != 0x202f && c != 0x205f && c != 0x3000
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
+#ifdef COMPILE_PCRE16
+ || c == 0x2028 || c == 0x2029
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_VSPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ c = *eptr;
+ if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
+#ifdef COMPILE_PCRE16
+ && c != 0x2028 && c != 0x2029
+#endif
+ ) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_DIGIT:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_WHITESPACE:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_NOT_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
+ eptr++;
+ }
+ break;
+
+ case OP_WORDCHAR:
+ for (i = min; i < max; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
+ eptr++;
+ }
+ break;
+
+ default:
+ RRETURN(PCRE_ERROR_INTERNAL);
+ }
+
+ /* eptr is now past the end of the maximum run. If possessive, we are
+ done (no backing up). Otherwise, match at this position; anything other
+ than no match is immediately returned. For nomatch, back up one
+ character (byte), unless we are matching \R and the last thing matched
+ was \r\n, in which case, back up two bytes. */
+
+ if (possessive) continue;
+ while (eptr >= pp)
+ {
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+ eptr--;
+ if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' &&
+ eptr[-1] == '\r') eptr--;
+ }
+ }
+
+ /* Get here if we can't make it match with any permitted repetitions */
+
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
+ /* There's been some horrible disaster. Arrival here can only mean there is
+ something seriously wrong in the code above or the OP_xxx definitions. */
+
+ default:
+ DPRINTF(("Unknown opcode %d\n", *ecode));
+ RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
+ }
+
+ /* Do not stick any code in here without much thought; it is assumed
+ that "continue" in the code above comes out to here to repeat the main
+ loop. */
+
+ } /* End of main loop */
+/* Control never reaches here */
+
+
+/* When compiling to use the heap rather than the stack for recursive calls to
+match(), the RRETURN() macro jumps here. The number that is saved in
+frame->Xwhere indicates which label we actually want to return to. */
+
+#ifdef NO_RECURSE
+#define LBL(val) case val: goto L_RM##val;
+HEAP_RETURN:
+switch (frame->Xwhere)
+ {
+ LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
+ LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
+ LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
+ LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
+ LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
+ LBL(65) LBL(66)
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ LBL(21)
+#endif
+#ifdef SUPPORT_UTF
+ LBL(16) LBL(18) LBL(20)
+ LBL(22) LBL(23) LBL(28) LBL(30)
+ LBL(32) LBL(34) LBL(42) LBL(46)
+#ifdef SUPPORT_UCP
+ LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
+ LBL(59) LBL(60) LBL(61) LBL(62)
+#endif /* SUPPORT_UCP */
+#endif /* SUPPORT_UTF */
+ default:
+ DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
+
+printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
+
+ return PCRE_ERROR_INTERNAL;
+ }
+#undef LBL
+#endif /* NO_RECURSE */
+}
+
+
+/***************************************************************************
+****************************************************************************
+ RECURSION IN THE match() FUNCTION
+
+Undefine all the macros that were defined above to handle this. */
+
+#ifdef NO_RECURSE
+#undef eptr
+#undef ecode
+#undef mstart
+#undef offset_top
+#undef eptrb
+#undef flags
+
+#undef callpat
+#undef charptr
+#undef data
+#undef next
+#undef pp
+#undef prev
+#undef saved_eptr
+
+#undef new_recursive
+
+#undef cur_is_word
+#undef condition
+#undef prev_is_word
+
+#undef ctype
+#undef length
+#undef max
+#undef min
+#undef number
+#undef offset
+#undef op
+#undef save_capture_last
+#undef save_offset1
+#undef save_offset2
+#undef save_offset3
+#undef stacksave
+
+#undef newptrb
+
+#endif
+
+/* These two are defined as macros in both cases */
+
+#undef fc
+#undef fi
+
+/***************************************************************************
+***************************************************************************/
+
+
+
+/*************************************************
+* Execute a Regular Expression *
+*************************************************/
+
+/* This function applies a compiled re to a subject string and picks out
+portions of the string if it matches. Two elements in the vector are set for
+each substring: the offsets to the start and end of the substring.
+
+Arguments:
+ argument_re points to the compiled expression
+ extra_data points to extra data or is NULL
+ subject points to the subject string
+ length length of subject string (may contain binary zeros)
+ start_offset where to start in the subject string
+ options option bits
+ offsets points to a vector of ints to be filled in with offsets
+ offsetcount the number of elements in the vector
+
+Returns: > 0 => success; value is the number of elements filled in
+ = 0 => success, but offsets is not big enough
+ -1 => failed to match
+ < -1 => some kind of unexpected problem
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
+ PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
+ int offsetcount)
+#endif
+{
+int rc, ocount, arg_offset_max;
+int newline;
+BOOL using_temporary_offsets = FALSE;
+BOOL anchored;
+BOOL startline;
+BOOL firstline;
+BOOL utf;
+BOOL has_first_char = FALSE;
+BOOL has_req_char = FALSE;
+pcre_uchar first_char = 0;
+pcre_uchar first_char2 = 0;
+pcre_uchar req_char = 0;
+pcre_uchar req_char2 = 0;
+match_data match_block;
+match_data *md = &match_block;
+const pcre_uint8 *tables;
+const pcre_uint8 *start_bits = NULL;
+PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
+PCRE_PUCHAR end_subject;
+PCRE_PUCHAR start_partial = NULL;
+PCRE_PUCHAR req_char_ptr = start_match - 1;
+
+const pcre_study_data *study;
+const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
+
+/* Check for the special magic call that measures the size of the stack used
+per recursive call of match(). */
+
+if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
+ start_offset == -999)
+#ifdef NO_RECURSE
+ return -sizeof(heapframe);
+#else
+ return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
+#endif
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
+if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
+ return PCRE_ERROR_NULL;
+if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
+if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+/* These two settings are used in the code for checking a UTF-8 string that
+follows immediately afterwards. Other values in the md block are used only
+during "normal" pcre_exec() processing, not when the JIT support is in use,
+so they are set up later. */
+
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+utf = md->utf = (re->options & PCRE_UTF8) != 0;
+md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
+ ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
+
+/* Check a UTF-8 string if required. Pass back the character offset and error
+code for an invalid string if a results vector is available. */
+
+#ifdef SUPPORT_UTF
+if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
+ {
+ int erroroffset;
+ int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
+ if (errorcode != 0)
+ {
+ if (offsetcount >= 2)
+ {
+ offsets[0] = erroroffset;
+ offsets[1] = errorcode;
+ }
+#ifdef COMPILE_PCRE16
+ return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
+ PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
+#else
+ return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
+ PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
+#endif
+ }
+
+ /* Check that a start_offset points to the start of a UTF character. */
+ if (start_offset > 0 && start_offset < length &&
+ NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
+ return PCRE_ERROR_BADUTF8_OFFSET;
+ }
+#endif
+
+/* If the pattern was successfully studied with JIT support, run the JIT
+executable instead of the rest of this function. Most options must be set at
+compile time for the JIT code to be usable. Fallback to the normal code path if
+an unsupported flag is set. In particular, JIT does not support partial
+matching. */
+
+#ifdef SUPPORT_JIT
+if (extra_data != NULL
+ && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0
+ && extra_data->executable_jit != NULL
+ && (extra_data->flags & PCRE_EXTRA_TABLES) == 0
+ && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
+ PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)
+ return PRIV(jit_exec)(re, extra_data->executable_jit,
+ (const pcre_uchar *)subject, length, start_offset, options,
+ ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
+ ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);
+#endif
+
+/* Carry on with non-JIT matching. This information is for finding all the
+numbers associated with a given name, for condition testing. */
+
+md->name_table = (pcre_uchar *)re + re->name_table_offset;
+md->name_count = re->name_count;
+md->name_entry_size = re->name_entry_size;
+
+/* Fish out the optional data from the extra_data structure, first setting
+the default values. */
+
+study = NULL;
+md->match_limit = MATCH_LIMIT;
+md->match_limit_recursion = MATCH_LIMIT_RECURSION;
+md->callout_data = NULL;
+
+/* The table pointer is always in native byte order. */
+
+tables = re->tables;
+
+if (extra_data != NULL)
+ {
+ register unsigned int flags = extra_data->flags;
+ if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ study = (const pcre_study_data *)extra_data->study_data;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
+ md->match_limit = extra_data->match_limit;
+ if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
+ md->match_limit_recursion = extra_data->match_limit_recursion;
+ if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
+ md->callout_data = extra_data->callout_data;
+ if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
+ }
+
+/* If the exec call supplied NULL for tables, use the inbuilt ones. This
+is a feature that makes it possible to save compiled regex and re-use them
+in other programs later. */
+
+if (tables == NULL) tables = PRIV(default_tables);
+
+/* Set up other data */
+
+anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
+startline = (re->flags & PCRE_STARTLINE) != 0;
+firstline = (re->options & PCRE_FIRSTLINE) != 0;
+
+/* The code starts after the real_pcre block and the capture name table. */
+
+md->start_code = (const pcre_uchar *)re + re->name_table_offset +
+ re->name_count * re->name_entry_size;
+
+md->start_subject = (PCRE_PUCHAR)subject;
+md->start_offset = start_offset;
+md->end_subject = md->start_subject + length;
+end_subject = md->end_subject;
+
+md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+md->use_ucp = (re->options & PCRE_UCP) != 0;
+md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+md->ignore_skip_arg = FALSE;
+
+/* Some options are unpacked into BOOL variables in the hope that testing
+them will be faster than individual option bits. */
+
+md->notbol = (options & PCRE_NOTBOL) != 0;
+md->noteol = (options & PCRE_NOTEOL) != 0;
+md->notempty = (options & PCRE_NOTEMPTY) != 0;
+md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
+
+md->hitend = FALSE;
+md->mark = md->nomatch_mark = NULL; /* In case never set */
+
+md->recursive = NULL; /* No recursion at top level */
+md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
+
+md->lcc = tables + lcc_offset;
+md->fcc = tables + fcc_offset;
+md->ctypes = tables + ctypes_offset;
+
+/* Handle different \R options. */
+
+switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+ {
+ case 0:
+ if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
+ md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
+ else
+#ifdef BSR_ANYCRLF
+ md->bsr_anycrlf = TRUE;
+#else
+ md->bsr_anycrlf = FALSE;
+#endif
+ break;
+
+ case PCRE_BSR_ANYCRLF:
+ md->bsr_anycrlf = TRUE;
+ break;
+
+ case PCRE_BSR_UNICODE:
+ md->bsr_anycrlf = FALSE;
+ break;
+
+ default: return PCRE_ERROR_BADNEWLINE;
+ }
+
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
+
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
+ (pcre_uint32)options) & PCRE_NEWLINE_BITS)
+ {
+ case 0: newline = NEWLINE; break; /* Compile-time default */
+ case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: newline = -1; break;
+ case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+ default: return PCRE_ERROR_BADNEWLINE;
+ }
+
+if (newline == -2)
+ {
+ md->nltype = NLTYPE_ANYCRLF;
+ }
+else if (newline < 0)
+ {
+ md->nltype = NLTYPE_ANY;
+ }
+else
+ {
+ md->nltype = NLTYPE_FIXED;
+ if (newline > 255)
+ {
+ md->nllen = 2;
+ md->nl[0] = (newline >> 8) & 255;
+ md->nl[1] = newline & 255;
+ }
+ else
+ {
+ md->nllen = 1;
+ md->nl[0] = newline;
+ }
+ }
+
+/* Partial matching was originally supported only for a restricted set of
+regexes; from release 8.00 there are no restrictions, but the bits are still
+defined (though never set). So there's no harm in leaving this code. */
+
+if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
+ return PCRE_ERROR_BADPARTIAL;
+
+/* If the expression has got more back references than the offsets supplied can
+hold, we get a temporary chunk of working store to use during the matching.
+Otherwise, we can use the vector supplied, rounding down its size to a multiple
+of 3. */
+
+ocount = offsetcount - (offsetcount % 3);
+arg_offset_max = (2*ocount)/3;
+
+if (re->top_backref > 0 && re->top_backref >= ocount/3)
+ {
+ ocount = re->top_backref * 3 + 3;
+ md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
+ if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
+ using_temporary_offsets = TRUE;
+ DPRINTF(("Got memory to hold back references\n"));
+ }
+else md->offset_vector = offsets;
+
+md->offset_end = ocount;
+md->offset_max = (2*ocount)/3;
+md->offset_overflow = FALSE;
+md->capture_last = -1;
+
+/* Reset the working variable associated with each extraction. These should
+never be used unless previously set, but they get saved and restored, and so we
+initialize them to avoid reading uninitialized locations. Also, unset the
+offsets for the matched string. This is really just for tidiness with callouts,
+in case they inspect these fields. */
+
+if (md->offset_vector != NULL)
+ {
+ register int *iptr = md->offset_vector + ocount;
+ register int *iend = iptr - re->top_bracket;
+ if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
+ while (--iptr >= iend) *iptr = -1;
+ md->offset_vector[0] = md->offset_vector[1] = -1;
+ }
+
+/* Set up the first character to match, if available. The first_char value is
+never set for an anchored regular expression, but the anchoring may be forced
+at run time, so we have to test for anchoring. The first char may be unset for
+an unanchored pattern, of course. If there's no first char and the pattern was
+studied, there may be a bitmap of possible first characters. */
+
+if (!anchored)
+ {
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ {
+ has_first_char = TRUE;
+ first_char = first_char2 = (pcre_uchar)(re->first_char);
+ if ((re->flags & PCRE_FCH_CASELESS) != 0)
+ {
+ first_char2 = TABLE_GET(first_char, md->fcc, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && first_char > 127)
+ first_char2 = UCD_OTHERCASE(first_char);
+#endif
+ }
+ }
+ else
+ if (!startline && study != NULL &&
+ (study->flags & PCRE_STUDY_MAPPED) != 0)
+ start_bits = study->start_bits;
+ }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+ {
+ has_req_char = TRUE;
+ req_char = req_char2 = (pcre_uchar)(re->req_char);
+ if ((re->flags & PCRE_RCH_CASELESS) != 0)
+ {
+ req_char2 = TABLE_GET(req_char, md->fcc, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (utf && req_char > 127)
+ req_char2 = UCD_OTHERCASE(req_char);
+#endif
+ }
+ }
+
+
+/* ==========================================================================*/
+
+/* Loop for handling unanchored repeated matching attempts; for anchored regexs
+the loop runs just once. */
+
+for(;;)
+ {
+ PCRE_PUCHAR save_end_subject = end_subject;
+ PCRE_PUCHAR new_start_match;
+
+ /* If firstline is TRUE, the start of the match is constrained to the first
+ line of a multiline string. That is, the match must be before or at the first
+ newline. Implement this by temporarily adjusting end_subject so that we stop
+ scanning at a newline. If the match fails at the newline, later code breaks
+ this loop. */
+
+ if (firstline)
+ {
+ PCRE_PUCHAR t = start_match;
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (t < md->end_subject && !IS_NEWLINE(t))
+ {
+ t++;
+ ACROSSCHAR(t < end_subject, *t, t++);
+ }
+ }
+ else
+#endif
+ while (t < md->end_subject && !IS_NEWLINE(t)) t++;
+ end_subject = t;
+ }
+
+ /* There are some optimizations that avoid running the match if a known
+ starting point is not found, or if a known later character is not present.
+ However, there is an option that disables these, for testing and for ensuring
+ that all callouts do actually occur. The option can be set in the regex by
+ (*NO_START_OPT) or passed in match-time options. */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ /* Advance to a unique first char if there is one. */
+
+ if (has_first_char)
+ {
+ if (first_char != first_char2)
+ while (start_match < end_subject &&
+ *start_match != first_char && *start_match != first_char2)
+ start_match++;
+ else
+ while (start_match < end_subject && *start_match != first_char)
+ start_match++;
+ }
+
+ /* Or to just after a linebreak for a multiline match */
+
+ else if (startline)
+ {
+ if (start_match > md->start_subject + start_offset)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ {
+ start_match++;
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+ }
+ }
+ else
+#endif
+ while (start_match < end_subject && !WAS_NEWLINE(start_match))
+ start_match++;
+
+ /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
+ and we are now at a LF, advance the match position by one more character.
+ */
+
+ if (start_match[-1] == CHAR_CR &&
+ (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+ start_match < end_subject &&
+ *start_match == CHAR_NL)
+ start_match++;
+ }
+ }
+
+ /* Or to a non-unique first byte after study */
+
+ else if (start_bits != NULL)
+ {
+ while (start_match < end_subject)
+ {
+ register unsigned int c = *start_match;
+#ifndef COMPILE_PCRE8
+ if (c > 255) c = 255;
+#endif
+ if ((start_bits[c/8] & (1 << (c&7))) == 0)
+ {
+ start_match++;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ /* In non 8-bit mode, the iteration will stop for
+ characters > 255 at the beginning or not stop at all. */
+ if (utf)
+ ACROSSCHAR(start_match < end_subject, *start_match,
+ start_match++);
+#endif
+ }
+ else break;
+ }
+ }
+ } /* Starting optimizations */
+
+ /* Restore fudged end_subject */
+
+ end_subject = save_end_subject;
+
+ /* The following two optimizations are disabled for partial matching or if
+ disabling is explicitly requested. */
+
+ if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
+ {
+ /* If the pattern was studied, a minimum subject length may be set. This is
+ a lower bound; no actual string of that length may actually match the
+ pattern. Although the value is, strictly, in characters, we treat it as
+ bytes to avoid spending too much time in this optimization. */
+
+ if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
+ (pcre_uint32)(end_subject - start_match) < study->minlength)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* If req_char is set, we know that that character must appear in the
+ subject for the match to succeed. If the first character is set, req_char
+ must be later in the subject; otherwise the test starts at the match point.
+ This optimization can save a huge amount of backtracking in patterns with
+ nested unlimited repeats that aren't going to match. Writing separate code
+ for cased/caseless versions makes it go faster, as does using an
+ autoincrement and backing off on a match.
+
+ HOWEVER: when the subject string is very, very long, searching to its end
+ can take a long time, and give bad performance on quite ordinary patterns.
+ This showed up when somebody was matching something like /^\d+C/ on a
+ 32-megabyte string... so we don't do this when the string is sufficiently
+ long. */
+
+ if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
+ {
+ register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
+
+ /* We don't need to repeat the search if we haven't yet reached the
+ place we found it at last time. */
+
+ if (p > req_char_ptr)
+ {
+ if (req_char != req_char2)
+ {
+ while (p < end_subject)
+ {
+ register int pp = *p++;
+ if (pp == req_char || pp == req_char2) { p--; break; }
+ }
+ }
+ else
+ {
+ while (p < end_subject)
+ {
+ if (*p++ == req_char) { p--; break; }
+ }
+ }
+
+ /* If we can't find the required character, break the matching loop,
+ forcing a match failure. */
+
+ if (p >= end_subject)
+ {
+ rc = MATCH_NOMATCH;
+ break;
+ }
+
+ /* If we have found the required character, save the point where we
+ found it, so that we don't search again next time round the loop if
+ the start hasn't passed this character yet. */
+
+ req_char_ptr = p;
+ }
+ }
+ }
+
+#ifdef PCRE_DEBUG /* Sigh. Some compilers never learn. */
+ printf(">>>> Match against: ");
+ pchars(start_match, end_subject - start_match, TRUE, md);
+ printf("\n");
+#endif
+
+ /* OK, we can now run the match. If "hitend" is set afterwards, remember the
+ first starting point for which a partial match was found. */
+
+ md->start_match_ptr = start_match;
+ md->start_used_ptr = start_match;
+ md->match_call_count = 0;
+ md->match_function_type = 0;
+ md->end_offset_top = 0;
+ rc = match(start_match, md->start_code, start_match, 2, md, NULL, 0);
+ if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
+
+ switch(rc)
+ {
+ /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
+ the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
+ entirely. The only way we can do that is to re-do the match at the same
+ point, with a flag to force SKIP with an argument to be ignored. Just
+ treating this case as NOMATCH does not work because it does not check other
+ alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
+
+ case MATCH_SKIP_ARG:
+ new_start_match = start_match;
+ md->ignore_skip_arg = TRUE;
+ break;
+
+ /* SKIP passes back the next starting point explicitly, but if it is the
+ same as the match we have just done, treat it as NOMATCH. */
+
+ case MATCH_SKIP:
+ if (md->start_match_ptr != start_match)
+ {
+ new_start_match = md->start_match_ptr;
+ break;
+ }
+ /* Fall through */
+
+ /* NOMATCH and PRUNE advance by one character. THEN at this level acts
+ exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */
+
+ case MATCH_NOMATCH:
+ case MATCH_PRUNE:
+ case MATCH_THEN:
+ md->ignore_skip_arg = FALSE;
+ new_start_match = start_match + 1;
+#ifdef SUPPORT_UTF
+ if (utf)
+ ACROSSCHAR(new_start_match < end_subject, *new_start_match,
+ new_start_match++);
+#endif
+ break;
+
+ /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
+
+ case MATCH_COMMIT:
+ rc = MATCH_NOMATCH;
+ goto ENDLOOP;
+
+ /* Any other return is either a match, or some kind of error. */
+
+ default:
+ goto ENDLOOP;
+ }
+
+ /* Control reaches here for the various types of "no match at this point"
+ result. Reset the code to MATCH_NOMATCH for subsequent checking. */
+
+ rc = MATCH_NOMATCH;
+
+ /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
+ newline in the subject (though it may continue over the newline). Therefore,
+ if we have just failed to match, starting at a newline, do not continue. */
+
+ if (firstline && IS_NEWLINE(start_match)) break;
+
+ /* Advance to new matching position */
+
+ start_match = new_start_match;
+
+ /* Break the loop if the pattern is anchored or if we have passed the end of
+ the subject. */
+
+ if (anchored || start_match > end_subject) break;
+
+ /* If we have just passed a CR and we are now at a LF, and the pattern does
+ not contain any explicit matches for \r or \n, and the newline option is CRLF
+ or ANY or ANYCRLF, advance the match position by one more character. In
+ normal matching start_match will aways be greater than the first position at
+ this stage, but a failed *SKIP can cause a return at the same point, which is
+ why the first test exists. */
+
+ if (start_match > (PCRE_PUCHAR)subject + start_offset &&
+ start_match[-1] == CHAR_CR &&
+ start_match < end_subject &&
+ *start_match == CHAR_NL &&
+ (re->flags & PCRE_HASCRORLF) == 0 &&
+ (md->nltype == NLTYPE_ANY ||
+ md->nltype == NLTYPE_ANYCRLF ||
+ md->nllen == 2))
+ start_match++;
+
+ md->mark = NULL; /* Reset for start of next match attempt */
+ } /* End of for(;;) "bumpalong" loop */
+
+/* ==========================================================================*/
+
+/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
+conditions is true:
+
+(1) The pattern is anchored or the match was failed by (*COMMIT);
+
+(2) We are past the end of the subject;
+
+(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
+ this option requests that a match occur at or before the first newline in
+ the subject.
+
+When we have a match and the offset vector is big enough to deal with any
+backreferences, captured substring offsets will already be set up. In the case
+where we had to get some local store to hold offsets for backreference
+processing, copy those that we can. In this case there need not be overflow if
+certain parts of the pattern were not used, even though there are more
+capturing parentheses than vector slots. */
+
+ENDLOOP:
+
+if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
+ {
+ if (using_temporary_offsets)
+ {
+ if (arg_offset_max >= 4)
+ {
+ memcpy(offsets + 2, md->offset_vector + 2,
+ (arg_offset_max - 2) * sizeof(int));
+ DPRINTF(("Copied offsets from temporary memory\n"));
+ }
+ if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
+ DPRINTF(("Freeing temporary memory\n"));
+ (PUBL(free))(md->offset_vector);
+ }
+
+ /* Set the return code to the number of captured strings, or 0 if there were
+ too many to fit into the vector. */
+
+ rc = (md->offset_overflow && md->end_offset_top >= arg_offset_max)?
+ 0 : md->end_offset_top/2;
+
+ /* If there is space in the offset vector, set any unused pairs at the end of
+ the pattern to -1 for backwards compatibility. It is documented that this
+ happens. In earlier versions, the whole set of potential capturing offsets
+ was set to -1 each time round the loop, but this is handled differently now.
+ "Gaps" are set to -1 dynamically instead (this fixes a bug). Thus, it is only
+ those at the end that need unsetting here. We can't just unset them all at
+ the start of the whole thing because they may get set in one branch that is
+ not the final matching branch. */
+
+ if (md->end_offset_top/2 <= re->top_bracket && offsets != NULL)
+ {
+ register int *iptr, *iend;
+ int resetcount = 2 + re->top_bracket * 2;
+ if (resetcount > offsetcount) resetcount = ocount;
+ iptr = offsets + md->end_offset_top;
+ iend = offsets + resetcount;
+ while (iptr < iend) *iptr++ = -1;
+ }
+
+ /* If there is space, set up the whole thing as substring 0. The value of
+ md->start_match_ptr might be modified if \K was encountered on the success
+ matching path. */
+
+ if (offsetcount < 2) rc = 0; else
+ {
+ offsets[0] = (int)(md->start_match_ptr - md->start_subject);
+ offsets[1] = (int)(md->end_match_ptr - md->start_subject);
+ }
+
+ /* Return MARK data if requested */
+
+ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = (pcre_uchar *)md->mark;
+ DPRINTF((">>>> returning %d\n", rc));
+ return rc;
+ }
+
+/* Control gets here if there has been an error, or if the overall match
+attempt has failed at all permitted starting positions. */
+
+if (using_temporary_offsets)
+ {
+ DPRINTF(("Freeing temporary memory\n"));
+ (PUBL(free))(md->offset_vector);
+ }
+
+/* For anything other than nomatch or partial match, just return the code. */
+
+if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
+ {
+ DPRINTF((">>>> error: returning %d\n", rc));
+ return rc;
+ }
+
+/* Handle partial matches - disable any mark data */
+
+if (start_partial != NULL)
+ {
+ DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
+ md->mark = NULL;
+ if (offsetcount > 1)
+ {
+ offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
+ offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
+ }
+ rc = PCRE_ERROR_PARTIAL;
+ }
+
+/* This is the classic nomatch case */
+
+else
+ {
+ DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
+ rc = PCRE_ERROR_NOMATCH;
+ }
+
+/* Return the MARK data if it has been requested. */
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
+ *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
+return rc;
+}
+
+/* End of pcre_exec.c */
diff --git a/src/3rdparty/pcre/pcre_fullinfo.c b/src/3rdparty/pcre/pcre_fullinfo.c
new file mode 100644
index 00000000000..e5e68f3f290
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_fullinfo.c
@@ -0,0 +1,202 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_fullinfo(), which returns
+information about a compiled pattern. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return info about compiled pattern *
+*************************************************/
+
+/* This is a newer "info" function which has an extensible interface so
+that additional items can be added compatibly.
+
+Arguments:
+ argument_re points to compiled code
+ extra_data points extra data, or NULL
+ what what information is required
+ where where to put the information
+
+Returns: 0 if data returned, negative on error
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
+ int what, void *where)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
+ int what, void *where)
+#endif
+{
+const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
+const pcre_study_data *study = NULL;
+
+if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
+ study = (const pcre_study_data *)extra_data->study_data;
+
+/* Check that the first field in the block is the magic number. If it is not,
+return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
+REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
+means that the pattern is likely compiled with different endianness. */
+
+if (re->magic_number != MAGIC_NUMBER)
+ return re->magic_number == REVERSED_MAGIC_NUMBER?
+ PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
+
+/* Check that this pattern was compiled in the correct bit mode */
+
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+
+switch (what)
+ {
+ case PCRE_INFO_OPTIONS:
+ *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS;
+ break;
+
+ case PCRE_INFO_SIZE:
+ *((size_t *)where) = re->size;
+ break;
+
+ case PCRE_INFO_STUDYSIZE:
+ *((size_t *)where) = (study == NULL)? 0 : study->size;
+ break;
+
+ case PCRE_INFO_JITSIZE:
+#ifdef SUPPORT_JIT
+ *((size_t *)where) =
+ (extra_data != NULL &&
+ (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra_data->executable_jit != NULL)?
+ PRIV(jit_get_size)(extra_data->executable_jit) : 0;
+#else
+ *((size_t *)where) = 0;
+#endif
+ break;
+
+ case PCRE_INFO_CAPTURECOUNT:
+ *((int *)where) = re->top_bracket;
+ break;
+
+ case PCRE_INFO_BACKREFMAX:
+ *((int *)where) = re->top_backref;
+ break;
+
+ case PCRE_INFO_FIRSTBYTE:
+ *((int *)where) =
+ ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char :
+ ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
+ break;
+
+ /* Make sure we pass back the pointer to the bit vector in the external
+ block, not the internal copy (with flipped integer fields). */
+
+ case PCRE_INFO_FIRSTTABLE:
+ *((const pcre_uint8 **)where) =
+ (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
+ ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
+ break;
+
+ case PCRE_INFO_MINLENGTH:
+ *((int *)where) =
+ (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
+ (int)(study->minlength) : -1;
+ break;
+
+ case PCRE_INFO_JIT:
+ *((int *)where) = extra_data != NULL &&
+ (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra_data->executable_jit != NULL;
+ break;
+
+ case PCRE_INFO_LASTLITERAL:
+ *((int *)where) =
+ ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1;
+ break;
+
+ case PCRE_INFO_NAMEENTRYSIZE:
+ *((int *)where) = re->name_entry_size;
+ break;
+
+ case PCRE_INFO_NAMECOUNT:
+ *((int *)where) = re->name_count;
+ break;
+
+ case PCRE_INFO_NAMETABLE:
+ *((const pcre_uchar **)where) = (const pcre_uchar *)re + re->name_table_offset;
+ break;
+
+ case PCRE_INFO_DEFAULT_TABLES:
+ *((const pcre_uint8 **)where) = (const pcre_uint8 *)(PRIV(default_tables));
+ break;
+
+ /* From release 8.00 this will always return TRUE because NOPARTIAL is
+ no longer ever set (the restrictions have been removed). */
+
+ case PCRE_INFO_OKPARTIAL:
+ *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
+ break;
+
+ case PCRE_INFO_JCHANGED:
+ *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
+ break;
+
+ case PCRE_INFO_HASCRORLF:
+ *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
+ break;
+
+ default: return PCRE_ERROR_BADOPTION;
+ }
+
+return 0;
+}
+
+/* End of pcre_fullinfo.c */
diff --git a/src/3rdparty/pcre/pcre_get.c b/src/3rdparty/pcre/pcre_get.c
new file mode 100644
index 00000000000..daecb695fe4
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_get.c
@@ -0,0 +1,587 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains some convenience functions for extracting substrings
+from the subject string after a regex match has succeeded. The original idea
+for these functions came from Scott Wimer. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Find number for named string *
+*************************************************/
+
+/* This function is used by the get_first_set() function below, as well
+as being generally available. It assumes that names are unique.
+
+Arguments:
+ code the compiled regex
+ stringname the name whose number is required
+
+Returns: the number of the named parentheses, or a negative number
+ (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_stringnumber(const pcre *code, const char *stringname)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
+#endif
+{
+int rc;
+int entrysize;
+int top, bot;
+pcre_uchar *nametable;
+
+#ifdef COMPILE_PCRE8
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+#ifdef COMPILE_PCRE16
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+
+bot = 0;
+while (top > bot)
+ {
+ int mid = (top + bot) / 2;
+ pcre_uchar *entry = nametable + entrysize*mid;
+ int c = STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(entry + IMM2_SIZE));
+ if (c == 0) return GET2(entry, 0);
+ if (c > 0) bot = mid + 1; else top = mid;
+ }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+
+/*************************************************
+* Find (multiple) entries for named string *
+*************************************************/
+
+/* This is used by the get_first_set() function below, as well as being
+generally available. It is used when duplicated names are permitted.
+
+Arguments:
+ code the compiled regex
+ stringname the name whose entries required
+ firstptr where to put the pointer to the first entry
+ lastptr where to put the pointer to the last entry
+
+Returns: the length of each entry, or a negative number
+ (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_stringtable_entries(const pcre *code, const char *stringname,
+ char **firstptr, char **lastptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
+#endif
+{
+int rc;
+int entrysize;
+int top, bot;
+pcre_uchar *nametable, *lastentry;
+
+#ifdef COMPILE_PCRE8
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+#ifdef COMPILE_PCRE16
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+ return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+ return rc;
+if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+ return rc;
+#endif
+
+lastentry = nametable + entrysize * (top - 1);
+bot = 0;
+while (top > bot)
+ {
+ int mid = (top + bot) / 2;
+ pcre_uchar *entry = nametable + entrysize*mid;
+ int c = STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(entry + IMM2_SIZE));
+ if (c == 0)
+ {
+ pcre_uchar *first = entry;
+ pcre_uchar *last = entry;
+ while (first > nametable)
+ {
+ if (STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(first - entrysize + IMM2_SIZE)) != 0) break;
+ first -= entrysize;
+ }
+ while (last < lastentry)
+ {
+ if (STRCMP_UC_UC((pcre_uchar *)stringname,
+ (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
+ last += entrysize;
+ }
+#ifdef COMPILE_PCRE8
+ *firstptr = (char *)first;
+ *lastptr = (char *)last;
+#else
+ *firstptr = (PCRE_UCHAR16 *)first;
+ *lastptr = (PCRE_UCHAR16 *)last;
+#endif
+ return entrysize;
+ }
+ if (c > 0) bot = mid + 1; else top = mid;
+ }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+
+/*************************************************
+* Find first set of multiple named strings *
+*************************************************/
+
+/* This function allows for duplicate names in the table of named substrings.
+It returns the number of the first one that was set in a pattern match.
+
+Arguments:
+ code the compiled regex
+ stringname the name of the capturing substring
+ ovector the vector of matched substrings
+
+Returns: the number of the first that is set,
+ or the number of the last one if none are set,
+ or a negative number on error
+*/
+
+#ifdef COMPILE_PCRE8
+static int
+get_first_set(const pcre *code, const char *stringname, int *ovector)
+#else
+static int
+get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector)
+#endif
+{
+const REAL_PCRE *re = (const REAL_PCRE *)code;
+int entrysize;
+pcre_uchar *entry;
+#ifdef COMPILE_PCRE8
+char *first, *last;
+#else
+PCRE_UCHAR16 *first, *last;
+#endif
+
+#ifdef COMPILE_PCRE8
+if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
+ return pcre_get_stringnumber(code, stringname);
+entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
+#else
+if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
+ return pcre16_get_stringnumber(code, stringname);
+entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
+#endif
+if (entrysize <= 0) return entrysize;
+for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
+ {
+ int n = GET2(entry, 0);
+ if (ovector[n*2] >= 0) return n;
+ }
+return GET2(entry, 0);
+}
+
+
+
+
+/*************************************************
+* Copy captured string to given buffer *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer.
+Note that we use memcpy() rather than strncpy() in case there are binary zeros
+in the string.
+
+Arguments:
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringnumber the number of the required substring
+ buffer where to put the substring
+ size the size of the buffer
+
+Returns: if successful:
+ the length of the copied string, not including the zero
+ that is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) buffer too small
+ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_substring(const char *subject, int *ovector, int stringcount,
+ int stringnumber, char *buffer, int size)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ int stringnumber, PCRE_UCHAR16 *buffer, int size)
+#endif
+{
+int yield;
+if (stringnumber < 0 || stringnumber >= stringcount)
+ return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
+memcpy(buffer, subject + ovector[stringnumber], IN_UCHARS(yield));
+buffer[yield] = 0;
+return yield;
+}
+
+
+
+/*************************************************
+* Copy named captured string to given buffer *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer,
+identifying it by name. If the regex permits duplicate names, the first
+substring that is set is chosen.
+
+Arguments:
+ code the compiled regex
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringname the name of the required substring
+ buffer where to put the substring
+ size the size of the buffer
+
+Returns: if successful:
+ the length of the copied string, not including the zero
+ that is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) buffer too small
+ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_named_substring(const pcre *code, const char *subject,
+ int *ovector, int stringcount, const char *stringname,
+ char *buffer, int size)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 stringname,
+ PCRE_UCHAR16 *buffer, int size)
+#endif
+{
+int n = get_first_set(code, stringname, ovector);
+if (n <= 0) return n;
+#ifdef COMPILE_PCRE8
+return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
+#else
+return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
+#endif
+}
+
+
+
+/*************************************************
+* Copy all captured strings to new store *
+*************************************************/
+
+/* This function gets one chunk of store and builds a list of pointers and all
+of the captured substrings in it. A NULL pointer is put on the end of the list.
+
+Arguments:
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ listptr set to point to the list of pointers
+
+Returns: if successful: 0
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) failed to get store
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
+ const char ***listptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ PCRE_SPTR16 **listptr)
+#endif
+{
+int i;
+int size = sizeof(pcre_uchar *);
+int double_count = stringcount * 2;
+pcre_uchar **stringlist;
+pcre_uchar *p;
+
+for (i = 0; i < double_count; i += 2)
+ size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1);
+
+stringlist = (pcre_uchar **)(PUBL(malloc))(size);
+if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
+
+#ifdef COMPILE_PCRE8
+*listptr = (const char **)stringlist;
+#else
+*listptr = (PCRE_SPTR16 *)stringlist;
+#endif
+p = (pcre_uchar *)(stringlist + stringcount + 1);
+
+for (i = 0; i < double_count; i += 2)
+ {
+ int len = ovector[i+1] - ovector[i];
+ memcpy(p, subject + ovector[i], IN_UCHARS(len));
+ *stringlist++ = p;
+ p += len;
+ *p++ = 0;
+ }
+
+*stringlist = NULL;
+return 0;
+}
+
+
+
+/*************************************************
+* Free store obtained by get_substring_list *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (PUBL(free))()
+directly.
+
+Argument: the result of a previous pcre_get_substring_list()
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre_free_substring_list(const char **pointer)
+#else
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre16_free_substring_list(PCRE_SPTR16 *pointer)
+#endif
+{
+(PUBL(free))((void *)pointer);
+}
+
+
+
+/*************************************************
+* Copy captured string to new store *
+*************************************************/
+
+/* This function copies a single captured substring into a piece of new
+store
+
+Arguments:
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringnumber the number of the required substring
+ stringptr where to put a pointer to the substring
+
+Returns: if successful:
+ the length of the string, not including the zero that
+ is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) failed to get store
+ PCRE_ERROR_NOSUBSTRING (-7) substring not present
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_substring(const char *subject, int *ovector, int stringcount,
+ int stringnumber, const char **stringptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
+ int stringnumber, PCRE_SPTR16 *stringptr)
+#endif
+{
+int yield;
+pcre_uchar *substring;
+if (stringnumber < 0 || stringnumber >= stringcount)
+ return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
+if (substring == NULL) return PCRE_ERROR_NOMEMORY;
+memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
+substring[yield] = 0;
+#ifdef COMPILE_PCRE8
+*stringptr = (const char *)substring;
+#else
+*stringptr = (PCRE_SPTR16)substring;
+#endif
+return yield;
+}
+
+
+
+/*************************************************
+* Copy named captured string to new store *
+*************************************************/
+
+/* This function copies a single captured substring, identified by name, into
+new store. If the regex permits duplicate names, the first substring that is
+set is chosen.
+
+Arguments:
+ code the compiled regex
+ subject the subject string that was matched
+ ovector pointer to the offsets table
+ stringcount the number of substrings that were captured
+ (i.e. the yield of the pcre_exec call, unless
+ that was zero, in which case it should be 1/3
+ of the offset table size)
+ stringname the name of the required substring
+ stringptr where to put the pointer
+
+Returns: if successful:
+ the length of the copied string, not including the zero
+ that is put on the end; can be zero
+ if not successful:
+ PCRE_ERROR_NOMEMORY (-6) couldn't get memory
+ PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_named_substring(const pcre *code, const char *subject,
+ int *ovector, int stringcount, const char *stringname,
+ const char **stringptr)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
+ int *ovector, int stringcount, PCRE_SPTR16 stringname,
+ PCRE_SPTR16 *stringptr)
+#endif
+{
+int n = get_first_set(code, stringname, ovector);
+if (n <= 0) return n;
+#ifdef COMPILE_PCRE8
+return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
+#else
+return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
+#endif
+}
+
+
+
+
+/*************************************************
+* Free store obtained by get_substring *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (PUBL(free))()
+directly.
+
+Argument: the result of a previous pcre_get_substring()
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre_free_substring(const char *pointer)
+#else
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre16_free_substring(PCRE_SPTR16 pointer)
+#endif
+{
+(PUBL(free))((void *)pointer);
+}
+
+/* End of pcre_get.c */
diff --git a/src/3rdparty/pcre/pcre_globals.c b/src/3rdparty/pcre/pcre_globals.c
new file mode 100644
index 00000000000..d5b6286fc23
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_globals.c
@@ -0,0 +1,84 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains global variables that are exported by the PCRE library.
+PCRE is thread-clean and doesn't use any global variables in the normal sense.
+However, it calls memory allocation and freeing functions via the four
+indirections below, and it can optionally do callouts, using the fifth
+indirection. These values can be changed by the caller, but are shared between
+all threads.
+
+For MS Visual Studio and Symbian OS, there are problems in initializing these
+variables to non-local functions. In these cases, therefore, an indirection via
+a local function is used.
+
+Also, when compiling for Virtual Pascal, things are done differently, and
+global variables are not used. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#if defined _MSC_VER || defined __SYMBIAN32__
+static void* LocalPcreMalloc(size_t aSize)
+ {
+ return malloc(aSize);
+ }
+static void LocalPcreFree(void* aPtr)
+ {
+ free(aPtr);
+ }
+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = LocalPcreMalloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = LocalPcreFree;
+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = LocalPcreMalloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = LocalPcreFree;
+PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
+
+#elif !defined VPCOMPAT
+PCRE_EXP_DATA_DEFN void *(*PUBL(malloc))(size_t) = malloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(free))(void *) = free;
+PCRE_EXP_DATA_DEFN void *(*PUBL(stack_malloc))(size_t) = malloc;
+PCRE_EXP_DATA_DEFN void (*PUBL(stack_free))(void *) = free;
+PCRE_EXP_DATA_DEFN int (*PUBL(callout))(PUBL(callout_block) *) = NULL;
+#endif
+
+/* End of pcre_globals.c */
diff --git a/src/3rdparty/pcre/pcre_internal.h b/src/3rdparty/pcre/pcre_internal.h
new file mode 100644
index 00000000000..e5a4b6a526d
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_internal.h
@@ -0,0 +1,2332 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+/* This header contains definitions that are shared between the different
+modules, but which are not relevant to the exported API. This includes some
+functions whose names all begin with "_pcre_" or "_pcre16_" depending on
+the PRIV macro. */
+
+#ifndef PCRE_INTERNAL_H
+#define PCRE_INTERNAL_H
+
+/* Define PCRE_DEBUG to get debugging output on stdout. */
+
+#if 0
+#define PCRE_DEBUG
+#endif
+
+/* PCRE is compiled as an 8 bit library if it is not requested otherwise. */
+#ifndef COMPILE_PCRE16
+#define COMPILE_PCRE8
+#endif
+
+/* If SUPPORT_UCP is defined, SUPPORT_UTF must also be defined. The
+"configure" script ensures this, but not everybody uses "configure". */
+
+#if defined SUPPORT_UCP && !(defined SUPPORT_UTF)
+#define SUPPORT_UTF 1
+#endif
+
+/* We define SUPPORT_UTF if SUPPORT_UTF8 is enabled for compatibility
+reasons with existing code. */
+
+#if defined SUPPORT_UTF8 && !(defined SUPPORT_UTF)
+#define SUPPORT_UTF 1
+#endif
+
+/* Fixme: SUPPORT_UTF8 should be eventually disappear from the code.
+Until then we define it if SUPPORT_UTF is defined. */
+
+#if defined SUPPORT_UTF && !(defined SUPPORT_UTF8)
+#define SUPPORT_UTF8 1
+#endif
+
+/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure"
+script prevents both being selected, but not everybody uses "configure". */
+
+#if defined EBCDIC && defined SUPPORT_UTF
+#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported.
+#endif
+
+/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
+inline, and there are *still* stupid compilers about that don't like indented
+pre-processor statements, or at least there were when I first wrote this. After
+all, it had only been about 10 years then...
+
+It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
+be absolutely sure we get our version. */
+
+#undef DPRINTF
+#ifdef PCRE_DEBUG
+#define DPRINTF(p) printf p
+#else
+#define DPRINTF(p) /* Nothing */
+#endif
+
+
+/* Standard C headers plus the external interface definition. The only time
+setjmp and stdarg are used is when NO_RECURSE is set. */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* When compiling a DLL for Windows, the exported symbols have to be declared
+using some MS magic. I found some useful information on this web page:
+http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
+information there, using __declspec(dllexport) without "extern" we have a
+definition; with "extern" we have a declaration. The settings here override the
+setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
+which is all that is needed for applications (they just import the symbols). We
+use:
+
+ PCRE_EXP_DECL for declarations
+ PCRE_EXP_DEFN for definitions of exported functions
+ PCRE_EXP_DATA_DEFN for definitions of exported variables
+
+The reason for the two DEFN macros is that in non-Windows environments, one
+does not want to have "extern" before variable definitions because it leads to
+compiler warnings. So we distinguish between functions and variables. In
+Windows, the two should always be the same.
+
+The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
+which is an application, but needs to import this file in order to "peek" at
+internals, can #include pcre.h first to get an application's-eye view.
+
+In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
+special-purpose environments) might want to stick other stuff in front of
+exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
+PCRE_EXP_DATA_DEFN only if they are not already set. */
+
+#ifndef PCRE_EXP_DECL
+# ifdef _WIN32
+# ifndef PCRE_STATIC
+# define PCRE_EXP_DECL extern __declspec(dllexport)
+# define PCRE_EXP_DEFN __declspec(dllexport)
+# define PCRE_EXP_DATA_DEFN __declspec(dllexport)
+# else
+# define PCRE_EXP_DECL extern
+# define PCRE_EXP_DEFN
+# define PCRE_EXP_DATA_DEFN
+# endif
+# else
+# ifdef __cplusplus
+# define PCRE_EXP_DECL extern "C"
+# else
+# define PCRE_EXP_DECL extern
+# endif
+# ifndef PCRE_EXP_DEFN
+# define PCRE_EXP_DEFN PCRE_EXP_DECL
+# endif
+# ifndef PCRE_EXP_DATA_DEFN
+# define PCRE_EXP_DATA_DEFN
+# endif
+# endif
+#endif
+
+/* When compiling with the MSVC compiler, it is sometimes necessary to include
+a "calling convention" before exported function names. (This is secondhand
+information; I know nothing about MSVC myself). For example, something like
+
+ void __cdecl function(....)
+
+might be needed. In order so make this easy, all the exported functions have
+PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not
+set, we ensure here that it has no effect. */
+
+#ifndef PCRE_CALL_CONVENTION
+#define PCRE_CALL_CONVENTION
+#endif
+
+/* We need to have types that specify unsigned 8, 16 and 32-bit integers. We
+cannot determine these outside the compilation (e.g. by running a program as
+part of "configure") because PCRE is often cross-compiled for use on other
+systems. Instead we make use of the maximum sizes that are available at
+preprocessor time in standard C environments. */
+
+typedef unsigned char pcre_uint8;
+
+#if USHRT_MAX == 65535
+ typedef unsigned short pcre_uint16;
+ typedef short pcre_int16;
+#elif UINT_MAX == 65535
+ typedef unsigned int pcre_uint16;
+ typedef int pcre_int16;
+#else
+ #error Cannot determine a type for 16-bit unsigned integers
+#endif
+
+#if UINT_MAX == 4294967295
+ typedef unsigned int pcre_uint32;
+ typedef int pcre_int32;
+#elif ULONG_MAX == 4294967295
+ typedef unsigned long int pcre_uint32;
+ typedef long int pcre_int32;
+#else
+ #error Cannot determine a type for 32-bit unsigned integers
+#endif
+
+/* When checking for integer overflow in pcre_compile(), we need to handle
+large integers. If a 64-bit integer type is available, we can use that.
+Otherwise we have to cast to double, which of course requires floating point
+arithmetic. Handle this by defining a macro for the appropriate type. If
+stdint.h is available, include it; it may define INT64_MAX. Systems that do not
+have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
+by "configure". */
+
+#if HAVE_STDINT_H
+#include
+#elif HAVE_INTTYPES_H
+#include
+#endif
+
+#if defined INT64_MAX || defined int64_t
+#define INT64_OR_DOUBLE int64_t
+#else
+#define INT64_OR_DOUBLE double
+#endif
+
+/* All character handling must be done as unsigned characters. Otherwise there
+are problems with top-bit-set characters and functions such as isspace().
+However, we leave the interface to the outside world as char * or short *,
+because that should make things easier for callers. This character type is
+called pcre_uchar.
+
+The IN_UCHARS macro multiply its argument with the byte size of the current
+pcre_uchar type. Useful for memcpy and such operations, whose require the
+byte size of their input/output buffers.
+
+The MAX_255 macro checks whether its pcre_uchar input is less than 256.
+
+The TABLE_GET macro is designed for accessing elements of tables whose contain
+exactly 256 items. When the character is able to contain more than 256
+items, some check is needed before accessing these tables.
+*/
+
+#ifdef COMPILE_PCRE8
+
+typedef unsigned char pcre_uchar;
+#define IN_UCHARS(x) (x)
+#define MAX_255(c) 1
+#define TABLE_GET(c, table, default) ((table)[c])
+
+#else
+
+#ifdef COMPILE_PCRE16
+#if USHRT_MAX != 65535
+/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
+pcre.h(.in) and disable (comment out) this message. */
+#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
+#endif
+
+typedef pcre_uint16 pcre_uchar;
+#define IN_UCHARS(x) ((x) << 1)
+#define MAX_255(c) ((c) <= 255u)
+#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default))
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+/* This is an unsigned int value that no character can ever have. UTF-8
+characters only go up to 0x7fffffff (though Unicode doesn't go beyond
+0x0010ffff). */
+
+#define NOTACHAR 0xffffffff
+
+/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
+"any" and "anycrlf" at present). The following macros are used to package up
+testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
+modules to indicate in which datablock the parameters exist, and what the
+start/end of string field names are. */
+
+#define NLTYPE_FIXED 0 /* Newline is a fixed length string */
+#define NLTYPE_ANY 1 /* Newline is any Unicode line ending */
+#define NLTYPE_ANYCRLF 2 /* Newline is CR, LF, or CRLF */
+
+/* This macro checks for a newline at the given position */
+
+#define IS_NEWLINE(p) \
+ ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+ ((p) < NLBLOCK->PSEND && \
+ PRIV(is_newline)((p), NLBLOCK->nltype, NLBLOCK->PSEND, \
+ &(NLBLOCK->nllen), utf)) \
+ : \
+ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
+ (p)[0] == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \
+ ) \
+ )
+
+/* This macro checks for a newline immediately preceding the given position */
+
+#define WAS_NEWLINE(p) \
+ ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+ ((p) > NLBLOCK->PSSTART && \
+ PRIV(was_newline)((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
+ &(NLBLOCK->nllen), utf)) \
+ : \
+ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
+ (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \
+ (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \
+ ) \
+ )
+
+/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
+with a custom type. This makes it possible, for example, to allow pcre_exec()
+to process subject strings that are discontinuous by using a smart pointer
+class. It must always be possible to inspect all of the subject string in
+pcre_exec() because of the way it backtracks. Two macros are required in the
+normal case, for sign-unspecified and unsigned char pointers. The former is
+used for the external interface and appears in pcre.h, which is why its name
+must begin with PCRE_. */
+
+#ifdef CUSTOM_SUBJECT_PTR
+#define PCRE_PUCHAR CUSTOM_SUBJECT_PTR
+#else
+#define PCRE_PUCHAR const pcre_uchar *
+#endif
+
+/* Include the public PCRE header and the definitions of UCP character property
+values. */
+
+#include "pcre.h"
+#include "ucp.h"
+
+/* When compiling for use with the Virtual Pascal compiler, these functions
+need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
+option on the command line. */
+
+#ifdef VPCOMPAT
+#define strlen(s) _strlen(s)
+#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
+#define memcmp(s,c,n) _memcmp(s,c,n)
+#define memcpy(d,s,n) _memcpy(d,s,n)
+#define memmove(d,s,n) _memmove(d,s,n)
+#define memset(s,c,n) _memset(s,c,n)
+#else /* VPCOMPAT */
+
+/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
+define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
+is set. Otherwise, include an emulating function for those systems that have
+neither (there some non-Unix environments where this is the case). */
+
+#ifndef HAVE_MEMMOVE
+#undef memmove /* some systems may have a macro */
+#ifdef HAVE_BCOPY
+#define memmove(a, b, c) bcopy(b, a, c)
+#else /* HAVE_BCOPY */
+static void *
+pcre_memmove(void *d, const void *s, size_t n)
+{
+size_t i;
+unsigned char *dest = (unsigned char *)d;
+const unsigned char *src = (const unsigned char *)s;
+if (dest > src)
+ {
+ dest += n;
+ src += n;
+ for (i = 0; i < n; ++i) *(--dest) = *(--src);
+ return (void *)dest;
+ }
+else
+ {
+ for (i = 0; i < n; ++i) *dest++ = *src++;
+ return (void *)(dest - n);
+ }
+}
+#define memmove(a, b, c) pcre_memmove(a, b, c)
+#endif /* not HAVE_BCOPY */
+#endif /* not HAVE_MEMMOVE */
+#endif /* not VPCOMPAT */
+
+
+/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
+in big-endian order) by default. These are used, for example, to link from the
+start of a subpattern to its alternatives and its end. The use of 2 bytes per
+offset limits the size of the compiled regex to around 64K, which is big enough
+for almost everybody. However, I received a request for an even bigger limit.
+For this reason, and also to make the code easier to maintain, the storing and
+loading of offsets from the byte string is now handled by the macros that are
+defined here.
+
+The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
+the config.h file, but can be overridden by using -D on the command line. This
+is automated on Unix systems via the "configure" command. */
+
+#ifdef COMPILE_PCRE8
+
+#if LINK_SIZE == 2
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 8), \
+ (a[(n)+1] = (d) & 255)
+
+#define GET(a,n) \
+ (((a)[n] << 8) | (a)[(n)+1])
+
+#define MAX_PATTERN_SIZE (1 << 16)
+
+
+#elif LINK_SIZE == 3
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 16), \
+ (a[(n)+1] = (d) >> 8), \
+ (a[(n)+2] = (d) & 255)
+
+#define GET(a,n) \
+ (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
+
+#define MAX_PATTERN_SIZE (1 << 24)
+
+
+#elif LINK_SIZE == 4
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 24), \
+ (a[(n)+1] = (d) >> 16), \
+ (a[(n)+2] = (d) >> 8), \
+ (a[(n)+3] = (d) & 255)
+
+#define GET(a,n) \
+ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
+
+/* Keep it positive */
+#define MAX_PATTERN_SIZE (1 << 30)
+
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+#if LINK_SIZE == 2
+
+#undef LINK_SIZE
+#define LINK_SIZE 1
+
+#define PUT(a,n,d) \
+ (a[n] = (d))
+
+#define GET(a,n) \
+ (a[n])
+
+#define MAX_PATTERN_SIZE (1 << 16)
+
+#elif LINK_SIZE == 3 || LINK_SIZE == 4
+
+#undef LINK_SIZE
+#define LINK_SIZE 2
+
+#define PUT(a,n,d) \
+ (a[n] = (d) >> 16), \
+ (a[(n)+1] = (d) & 65535)
+
+#define GET(a,n) \
+ (((a)[n] << 16) | (a)[(n)+1])
+
+/* Keep it positive */
+#define MAX_PATTERN_SIZE (1 << 30)
+
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+/* Convenience macro defined in terms of the others */
+
+#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
+
+
+/* PCRE uses some other 2-byte quantities that do not change when the size of
+offsets changes. There are used for repeat counts and for other things such as
+capturing parenthesis numbers in back references. */
+
+#ifdef COMPILE_PCRE8
+
+#define IMM2_SIZE 2
+
+#define PUT2(a,n,d) \
+ a[n] = (d) >> 8; \
+ a[(n)+1] = (d) & 255
+
+#define GET2(a,n) \
+ (((a)[n] << 8) | (a)[(n)+1])
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+#define IMM2_SIZE 1
+
+#define PUT2(a,n,d) \
+ a[n] = d
+
+#define GET2(a,n) \
+ a[n]
+
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
+
+/* When UTF encoding is being used, a character is no longer just a single
+character. The macros for character handling generate simple sequences when
+used in character-mode, and more complicated ones for UTF characters.
+GETCHARLENTEST and other macros are not used when UTF is not supported,
+so they are not defined. To make sure they can never even appear when
+UTF support is omitted, we don't even define them. */
+
+#ifndef SUPPORT_UTF
+
+/* #define MAX_VALUE_FOR_SINGLE_CHAR */
+/* #define HAS_EXTRALEN(c) */
+/* #define GET_EXTRALEN(c) */
+/* #define NOT_FIRSTCHAR(c) */
+#define GETCHAR(c, eptr) c = *eptr;
+#define GETCHARTEST(c, eptr) c = *eptr;
+#define GETCHARINC(c, eptr) c = *eptr++;
+#define GETCHARINCTEST(c, eptr) c = *eptr++;
+#define GETCHARLEN(c, eptr, len) c = *eptr;
+/* #define GETCHARLENTEST(c, eptr, len) */
+/* #define BACKCHAR(eptr) */
+/* #define FORWARDCHAR(eptr) */
+/* #define ACROSSCHAR(condition, eptr, action) */
+
+#else /* SUPPORT_UTF */
+
+#ifdef COMPILE_PCRE8
+
+/* These macros were originally written in the form of loops that used data
+from the tables whose names start with PRIV(utf8_table). They were rewritten by
+a user so as not to use loops, because in some environments this gives a
+significant performance advantage, and it seems never to do any harm. */
+
+/* Tells the biggest code point which can be encoded as a single character. */
+
+#define MAX_VALUE_FOR_SINGLE_CHAR 127
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) ((c) >= 0xc0)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f])
+
+/* Returns TRUE, if the given character is not the first character
+of a UTF sequence. */
+
+#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80)
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, not
+advancing the pointer. */
+
+#define GETUTF8(c, eptr) \
+ { \
+ if ((c & 0x20) == 0) \
+ c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
+ else if ((c & 0x10) == 0) \
+ c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
+ else if ((c & 0x08) == 0) \
+ c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
+ ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
+ else if ((c & 0x04) == 0) \
+ c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
+ ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
+ (eptr[4] & 0x3f); \
+ else \
+ c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
+ ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
+ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
+ }
+
+/* Get the next UTF-8 character, not advancing the pointer. This is called when
+we know we are in UTF-8 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if (c >= 0xc0) GETUTF8(c, eptr);
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && c >= 0xc0) GETUTF8(c, eptr);
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, advancing
+the pointer. */
+
+#define GETUTF8INC(c, eptr) \
+ { \
+ if ((c & 0x20) == 0) \
+ c = ((c & 0x1f) << 6) | (*eptr++ & 0x3f); \
+ else if ((c & 0x10) == 0) \
+ { \
+ c = ((c & 0x0f) << 12) | ((*eptr & 0x3f) << 6) | (eptr[1] & 0x3f); \
+ eptr += 2; \
+ } \
+ else if ((c & 0x08) == 0) \
+ { \
+ c = ((c & 0x07) << 18) | ((*eptr & 0x3f) << 12) | \
+ ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
+ eptr += 3; \
+ } \
+ else if ((c & 0x04) == 0) \
+ { \
+ c = ((c & 0x03) << 24) | ((*eptr & 0x3f) << 18) | \
+ ((eptr[1] & 0x3f) << 12) | ((eptr[2] & 0x3f) << 6) | \
+ (eptr[3] & 0x3f); \
+ eptr += 4; \
+ } \
+ else \
+ { \
+ c = ((c & 0x01) << 30) | ((*eptr & 0x3f) << 24) | \
+ ((eptr[1] & 0x3f) << 18) | ((eptr[2] & 0x3f) << 12) | \
+ ((eptr[3] & 0x3f) << 6) | (eptr[4] & 0x3f); \
+ eptr += 5; \
+ } \
+ }
+
+/* Get the next UTF-8 character, advancing the pointer. This is called when we
+know we are in UTF-8 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if (c >= 0xc0) GETUTF8INC(c, eptr);
+
+/* Get the next character, testing for UTF-8 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-8 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && c >= 0xc0) GETUTF8INC(c, eptr);
+
+/* Base macro to pick up the remaining bytes of a UTF-8 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF8LEN(c, eptr, len) \
+ { \
+ if ((c & 0x20) == 0) \
+ { \
+ c = ((c & 0x1f) << 6) | (eptr[1] & 0x3f); \
+ len++; \
+ } \
+ else if ((c & 0x10) == 0) \
+ { \
+ c = ((c & 0x0f) << 12) | ((eptr[1] & 0x3f) << 6) | (eptr[2] & 0x3f); \
+ len += 2; \
+ } \
+ else if ((c & 0x08) == 0) \
+ {\
+ c = ((c & 0x07) << 18) | ((eptr[1] & 0x3f) << 12) | \
+ ((eptr[2] & 0x3f) << 6) | (eptr[3] & 0x3f); \
+ len += 3; \
+ } \
+ else if ((c & 0x04) == 0) \
+ { \
+ c = ((c & 0x03) << 24) | ((eptr[1] & 0x3f) << 18) | \
+ ((eptr[2] & 0x3f) << 12) | ((eptr[3] & 0x3f) << 6) | \
+ (eptr[4] & 0x3f); \
+ len += 4; \
+ } \
+ else \
+ {\
+ c = ((c & 0x01) << 30) | ((eptr[1] & 0x3f) << 24) | \
+ ((eptr[2] & 0x3f) << 18) | ((eptr[3] & 0x3f) << 12) | \
+ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \
+ len += 5; \
+ } \
+ }
+
+/* Get the next UTF-8 character, not advancing the pointer, incrementing length
+if there are extra bytes. This is called when we know we are in UTF-8 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if (c >= 0xc0) GETUTF8LEN(c, eptr, len);
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
+pointer, incrementing length if there are extra bytes. This is called when we
+do not know if we are in UTF-8 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-8 mode - we don't put a test within the macro
+because almost all calls are already within a block of UTF-8 only code. */
+
+#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ while((condition) && ((eptr) & 0xc0) == 0x80) action
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+
+/* Tells the biggest code point which can be encoded as a single character. */
+
+#define MAX_VALUE_FOR_SINGLE_CHAR 65535
+
+/* Tests whether the code point needs extra characters to decode. */
+
+#define HAS_EXTRALEN(c) (((c) & 0xfc00) == 0xd800)
+
+/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+Otherwise it has an undefined behaviour. */
+
+#define GET_EXTRALEN(c) 1
+
+/* Returns TRUE, if the given character is not the first character
+of a UTF sequence. */
+
+#define NOT_FIRSTCHAR(c) (((c) & 0xfc00) == 0xdc00)
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer. */
+
+#define GETUTF16(c, eptr) \
+ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; }
+
+/* Get the next UTF-16 character, not advancing the pointer. This is called when
+we know we are in UTF-16 mode. */
+
+#define GETCHAR(c, eptr) \
+ c = *eptr; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
+
+/* Get the next UTF-16 character, testing for UTF-16 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, advancing
+the pointer. */
+
+#define GETUTF16INC(c, eptr) \
+ { c = (((c & 0x3ff) << 10) | (*eptr++ & 0x3ff)) + 0x10000; }
+
+/* Get the next UTF-16 character, advancing the pointer. This is called when we
+know we are in UTF-16 mode. */
+
+#define GETCHARINC(c, eptr) \
+ c = *eptr++; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
+
+/* Get the next character, testing for UTF-16 mode, and advancing the pointer.
+This is called when we don't know if we are in UTF-16 mode. */
+
+#define GETCHARINCTEST(c, eptr) \
+ c = *eptr++; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16INC(c, eptr);
+
+/* Base macro to pick up the low surrogate of a UTF-16 character, not
+advancing the pointer, incrementing the length. */
+
+#define GETUTF16LEN(c, eptr, len) \
+ { c = (((c & 0x3ff) << 10) | (eptr[1] & 0x3ff)) + 0x10000; len++; }
+
+/* Get the next UTF-16 character, not advancing the pointer, incrementing
+length if there is a low surrogate. This is called when we know we are in
+UTF-16 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+ c = *eptr; \
+ if ((c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
+
+/* Get the next UTF-816character, testing for UTF-16 mode, not advancing the
+pointer, incrementing length if there is a low surrogate. This is called when
+we do not know if we are in UTF-16 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+ c = *eptr; \
+ if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len);
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-16 mode - we don't put a test within the
+macro because almost all calls are already within a block of UTF-16 only
+code. */
+
+#define BACKCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr--
+
+/* Same as above, just in the other direction. */
+#define FORWARDCHAR(eptr) if ((*eptr & 0xfc00) == 0xdc00) eptr++
+
+/* Same as above, but it allows a fully customizable form. */
+#define ACROSSCHAR(condition, eptr, action) \
+ if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action
+
+#endif
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
+
+
+/* In case there is no definition of offsetof() provided - though any proper
+Standard C system should have one. */
+
+#ifndef offsetof
+#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
+#endif
+
+
+/* Private flags containing information about the compiled regex. They used to
+live at the top end of the options word, but that got almost full, so now they
+are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as
+the restrictions on partial matching have been lifted. It remains for backwards
+compatibility. */
+
+#ifdef COMPILE_PCRE8
+#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */
+#endif
+#ifdef COMPILE_PCRE16
+#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */
+#endif
+#define PCRE_FIRSTSET 0x0010 /* first_char is set */
+#define PCRE_FCH_CASELESS 0x0020 /* caseless first char */
+#define PCRE_REQCHSET 0x0040 /* req_byte is set */
+#define PCRE_RCH_CASELESS 0x0080 /* caseless requested char */
+#define PCRE_STARTLINE 0x0100 /* start after \n for multiline */
+#define PCRE_NOPARTIAL 0x0200 /* can't use partial with this regex */
+#define PCRE_JCHANGED 0x0400 /* j option used in regex */
+#define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */
+#define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */
+
+/* Flags for the "extra" block produced by pcre_study(). */
+
+#define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */
+#define PCRE_STUDY_MINLEN 0x0002 /* a minimum length field exists */
+
+/* Masks for identifying the public options that are permitted at compile
+time, run time, or study time, respectively. */
+
+#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
+ PCRE_NEWLINE_ANYCRLF)
+
+#define PUBLIC_COMPILE_OPTIONS \
+ (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
+ PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
+ PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
+ PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
+ PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_EXEC_OPTIONS \
+ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
+ PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \
+ PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_DFA_EXEC_OPTIONS \
+ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
+ PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \
+ PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
+ PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_STUDY_OPTIONS \
+ PCRE_STUDY_JIT_COMPILE
+
+/* Magic number to provide a small check against being handed junk. */
+
+#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
+
+/* This variable is used to detect a loaded regular expression
+in different endianness. */
+
+#define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */
+
+/* Negative values for the firstchar and reqchar variables */
+
+#define REQ_UNSET (-2)
+#define REQ_NONE (-1)
+
+/* The maximum remaining length of subject we are prepared to search for a
+req_byte match. */
+
+#define REQ_BYTE_MAX 1000
+
+/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
+environments where these macros are defined elsewhere. Unfortunately, there
+is no way to do the same for the typedef. */
+
+typedef int BOOL;
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal
+character constants like '*' because the compiler would emit their EBCDIC code,
+which is different from their ASCII/UTF-8 code. Instead we define macros for
+the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
+is enabled. When UTF-8 support is not enabled, the definitions use character
+literals. Both character and string versions of each character are needed, and
+there are some longer strings as well.
+
+This means that, on EBCDIC platforms, the PCRE library can handle either
+EBCDIC, or UTF-8, but not both. To support both in the same compiled library
+would need different lookups depending on whether PCRE_UTF8 was set or not.
+This would make it impossible to use characters in switch/case statements,
+which would reduce performance. For a theoretical use (which nobody has asked
+for) in a minority area (EBCDIC platforms), this is not sensible. Any
+application that did need both could compile two versions of the library, using
+macros to give the functions distinct names. */
+
+#ifndef SUPPORT_UTF
+
+/* UTF-8 support is not enabled; use the platform-dependent character literals
+so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */
+
+#define CHAR_HT '\t'
+#define CHAR_VT '\v'
+#define CHAR_FF '\f'
+#define CHAR_CR '\r'
+#define CHAR_NL '\n'
+#define CHAR_BS '\b'
+#define CHAR_BEL '\a'
+#ifdef EBCDIC
+#define CHAR_ESC '\047'
+#define CHAR_DEL '\007'
+#else
+#define CHAR_ESC '\033'
+#define CHAR_DEL '\177'
+#endif
+
+#define CHAR_SPACE ' '
+#define CHAR_EXCLAMATION_MARK '!'
+#define CHAR_QUOTATION_MARK '"'
+#define CHAR_NUMBER_SIGN '#'
+#define CHAR_DOLLAR_SIGN '$'
+#define CHAR_PERCENT_SIGN '%'
+#define CHAR_AMPERSAND '&'
+#define CHAR_APOSTROPHE '\''
+#define CHAR_LEFT_PARENTHESIS '('
+#define CHAR_RIGHT_PARENTHESIS ')'
+#define CHAR_ASTERISK '*'
+#define CHAR_PLUS '+'
+#define CHAR_COMMA ','
+#define CHAR_MINUS '-'
+#define CHAR_DOT '.'
+#define CHAR_SLASH '/'
+#define CHAR_0 '0'
+#define CHAR_1 '1'
+#define CHAR_2 '2'
+#define CHAR_3 '3'
+#define CHAR_4 '4'
+#define CHAR_5 '5'
+#define CHAR_6 '6'
+#define CHAR_7 '7'
+#define CHAR_8 '8'
+#define CHAR_9 '9'
+#define CHAR_COLON ':'
+#define CHAR_SEMICOLON ';'
+#define CHAR_LESS_THAN_SIGN '<'
+#define CHAR_EQUALS_SIGN '='
+#define CHAR_GREATER_THAN_SIGN '>'
+#define CHAR_QUESTION_MARK '?'
+#define CHAR_COMMERCIAL_AT '@'
+#define CHAR_A 'A'
+#define CHAR_B 'B'
+#define CHAR_C 'C'
+#define CHAR_D 'D'
+#define CHAR_E 'E'
+#define CHAR_F 'F'
+#define CHAR_G 'G'
+#define CHAR_H 'H'
+#define CHAR_I 'I'
+#define CHAR_J 'J'
+#define CHAR_K 'K'
+#define CHAR_L 'L'
+#define CHAR_M 'M'
+#define CHAR_N 'N'
+#define CHAR_O 'O'
+#define CHAR_P 'P'
+#define CHAR_Q 'Q'
+#define CHAR_R 'R'
+#define CHAR_S 'S'
+#define CHAR_T 'T'
+#define CHAR_U 'U'
+#define CHAR_V 'V'
+#define CHAR_W 'W'
+#define CHAR_X 'X'
+#define CHAR_Y 'Y'
+#define CHAR_Z 'Z'
+#define CHAR_LEFT_SQUARE_BRACKET '['
+#define CHAR_BACKSLASH '\\'
+#define CHAR_RIGHT_SQUARE_BRACKET ']'
+#define CHAR_CIRCUMFLEX_ACCENT '^'
+#define CHAR_UNDERSCORE '_'
+#define CHAR_GRAVE_ACCENT '`'
+#define CHAR_a 'a'
+#define CHAR_b 'b'
+#define CHAR_c 'c'
+#define CHAR_d 'd'
+#define CHAR_e 'e'
+#define CHAR_f 'f'
+#define CHAR_g 'g'
+#define CHAR_h 'h'
+#define CHAR_i 'i'
+#define CHAR_j 'j'
+#define CHAR_k 'k'
+#define CHAR_l 'l'
+#define CHAR_m 'm'
+#define CHAR_n 'n'
+#define CHAR_o 'o'
+#define CHAR_p 'p'
+#define CHAR_q 'q'
+#define CHAR_r 'r'
+#define CHAR_s 's'
+#define CHAR_t 't'
+#define CHAR_u 'u'
+#define CHAR_v 'v'
+#define CHAR_w 'w'
+#define CHAR_x 'x'
+#define CHAR_y 'y'
+#define CHAR_z 'z'
+#define CHAR_LEFT_CURLY_BRACKET '{'
+#define CHAR_VERTICAL_LINE '|'
+#define CHAR_RIGHT_CURLY_BRACKET '}'
+#define CHAR_TILDE '~'
+
+#define STR_HT "\t"
+#define STR_VT "\v"
+#define STR_FF "\f"
+#define STR_CR "\r"
+#define STR_NL "\n"
+#define STR_BS "\b"
+#define STR_BEL "\a"
+#ifdef EBCDIC
+#define STR_ESC "\047"
+#define STR_DEL "\007"
+#else
+#define STR_ESC "\033"
+#define STR_DEL "\177"
+#endif
+
+#define STR_SPACE " "
+#define STR_EXCLAMATION_MARK "!"
+#define STR_QUOTATION_MARK "\""
+#define STR_NUMBER_SIGN "#"
+#define STR_DOLLAR_SIGN "$"
+#define STR_PERCENT_SIGN "%"
+#define STR_AMPERSAND "&"
+#define STR_APOSTROPHE "'"
+#define STR_LEFT_PARENTHESIS "("
+#define STR_RIGHT_PARENTHESIS ")"
+#define STR_ASTERISK "*"
+#define STR_PLUS "+"
+#define STR_COMMA ","
+#define STR_MINUS "-"
+#define STR_DOT "."
+#define STR_SLASH "/"
+#define STR_0 "0"
+#define STR_1 "1"
+#define STR_2 "2"
+#define STR_3 "3"
+#define STR_4 "4"
+#define STR_5 "5"
+#define STR_6 "6"
+#define STR_7 "7"
+#define STR_8 "8"
+#define STR_9 "9"
+#define STR_COLON ":"
+#define STR_SEMICOLON ";"
+#define STR_LESS_THAN_SIGN "<"
+#define STR_EQUALS_SIGN "="
+#define STR_GREATER_THAN_SIGN ">"
+#define STR_QUESTION_MARK "?"
+#define STR_COMMERCIAL_AT "@"
+#define STR_A "A"
+#define STR_B "B"
+#define STR_C "C"
+#define STR_D "D"
+#define STR_E "E"
+#define STR_F "F"
+#define STR_G "G"
+#define STR_H "H"
+#define STR_I "I"
+#define STR_J "J"
+#define STR_K "K"
+#define STR_L "L"
+#define STR_M "M"
+#define STR_N "N"
+#define STR_O "O"
+#define STR_P "P"
+#define STR_Q "Q"
+#define STR_R "R"
+#define STR_S "S"
+#define STR_T "T"
+#define STR_U "U"
+#define STR_V "V"
+#define STR_W "W"
+#define STR_X "X"
+#define STR_Y "Y"
+#define STR_Z "Z"
+#define STR_LEFT_SQUARE_BRACKET "["
+#define STR_BACKSLASH "\\"
+#define STR_RIGHT_SQUARE_BRACKET "]"
+#define STR_CIRCUMFLEX_ACCENT "^"
+#define STR_UNDERSCORE "_"
+#define STR_GRAVE_ACCENT "`"
+#define STR_a "a"
+#define STR_b "b"
+#define STR_c "c"
+#define STR_d "d"
+#define STR_e "e"
+#define STR_f "f"
+#define STR_g "g"
+#define STR_h "h"
+#define STR_i "i"
+#define STR_j "j"
+#define STR_k "k"
+#define STR_l "l"
+#define STR_m "m"
+#define STR_n "n"
+#define STR_o "o"
+#define STR_p "p"
+#define STR_q "q"
+#define STR_r "r"
+#define STR_s "s"
+#define STR_t "t"
+#define STR_u "u"
+#define STR_v "v"
+#define STR_w "w"
+#define STR_x "x"
+#define STR_y "y"
+#define STR_z "z"
+#define STR_LEFT_CURLY_BRACKET "{"
+#define STR_VERTICAL_LINE "|"
+#define STR_RIGHT_CURLY_BRACKET "}"
+#define STR_TILDE "~"
+
+#define STRING_ACCEPT0 "ACCEPT\0"
+#define STRING_COMMIT0 "COMMIT\0"
+#define STRING_F0 "F\0"
+#define STRING_FAIL0 "FAIL\0"
+#define STRING_MARK0 "MARK\0"
+#define STRING_PRUNE0 "PRUNE\0"
+#define STRING_SKIP0 "SKIP\0"
+#define STRING_THEN "THEN"
+
+#define STRING_alpha0 "alpha\0"
+#define STRING_lower0 "lower\0"
+#define STRING_upper0 "upper\0"
+#define STRING_alnum0 "alnum\0"
+#define STRING_ascii0 "ascii\0"
+#define STRING_blank0 "blank\0"
+#define STRING_cntrl0 "cntrl\0"
+#define STRING_digit0 "digit\0"
+#define STRING_graph0 "graph\0"
+#define STRING_print0 "print\0"
+#define STRING_punct0 "punct\0"
+#define STRING_space0 "space\0"
+#define STRING_word0 "word\0"
+#define STRING_xdigit "xdigit"
+
+#define STRING_DEFINE "DEFINE"
+
+#define STRING_CR_RIGHTPAR "CR)"
+#define STRING_LF_RIGHTPAR "LF)"
+#define STRING_CRLF_RIGHTPAR "CRLF)"
+#define STRING_ANY_RIGHTPAR "ANY)"
+#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
+#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
+#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
+#ifdef COMPILE_PCRE8
+#define STRING_UTF_RIGHTPAR "UTF8)"
+#endif
+#ifdef COMPILE_PCRE16
+#define STRING_UTF_RIGHTPAR "UTF16)"
+#endif
+#define STRING_UCP_RIGHTPAR "UCP)"
+#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+
+#else /* SUPPORT_UTF */
+
+/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
+works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
+only. */
+
+#define CHAR_HT '\011'
+#define CHAR_VT '\013'
+#define CHAR_FF '\014'
+#define CHAR_CR '\015'
+#define CHAR_NL '\012'
+#define CHAR_BS '\010'
+#define CHAR_BEL '\007'
+#define CHAR_ESC '\033'
+#define CHAR_DEL '\177'
+
+#define CHAR_SPACE '\040'
+#define CHAR_EXCLAMATION_MARK '\041'
+#define CHAR_QUOTATION_MARK '\042'
+#define CHAR_NUMBER_SIGN '\043'
+#define CHAR_DOLLAR_SIGN '\044'
+#define CHAR_PERCENT_SIGN '\045'
+#define CHAR_AMPERSAND '\046'
+#define CHAR_APOSTROPHE '\047'
+#define CHAR_LEFT_PARENTHESIS '\050'
+#define CHAR_RIGHT_PARENTHESIS '\051'
+#define CHAR_ASTERISK '\052'
+#define CHAR_PLUS '\053'
+#define CHAR_COMMA '\054'
+#define CHAR_MINUS '\055'
+#define CHAR_DOT '\056'
+#define CHAR_SLASH '\057'
+#define CHAR_0 '\060'
+#define CHAR_1 '\061'
+#define CHAR_2 '\062'
+#define CHAR_3 '\063'
+#define CHAR_4 '\064'
+#define CHAR_5 '\065'
+#define CHAR_6 '\066'
+#define CHAR_7 '\067'
+#define CHAR_8 '\070'
+#define CHAR_9 '\071'
+#define CHAR_COLON '\072'
+#define CHAR_SEMICOLON '\073'
+#define CHAR_LESS_THAN_SIGN '\074'
+#define CHAR_EQUALS_SIGN '\075'
+#define CHAR_GREATER_THAN_SIGN '\076'
+#define CHAR_QUESTION_MARK '\077'
+#define CHAR_COMMERCIAL_AT '\100'
+#define CHAR_A '\101'
+#define CHAR_B '\102'
+#define CHAR_C '\103'
+#define CHAR_D '\104'
+#define CHAR_E '\105'
+#define CHAR_F '\106'
+#define CHAR_G '\107'
+#define CHAR_H '\110'
+#define CHAR_I '\111'
+#define CHAR_J '\112'
+#define CHAR_K '\113'
+#define CHAR_L '\114'
+#define CHAR_M '\115'
+#define CHAR_N '\116'
+#define CHAR_O '\117'
+#define CHAR_P '\120'
+#define CHAR_Q '\121'
+#define CHAR_R '\122'
+#define CHAR_S '\123'
+#define CHAR_T '\124'
+#define CHAR_U '\125'
+#define CHAR_V '\126'
+#define CHAR_W '\127'
+#define CHAR_X '\130'
+#define CHAR_Y '\131'
+#define CHAR_Z '\132'
+#define CHAR_LEFT_SQUARE_BRACKET '\133'
+#define CHAR_BACKSLASH '\134'
+#define CHAR_RIGHT_SQUARE_BRACKET '\135'
+#define CHAR_CIRCUMFLEX_ACCENT '\136'
+#define CHAR_UNDERSCORE '\137'
+#define CHAR_GRAVE_ACCENT '\140'
+#define CHAR_a '\141'
+#define CHAR_b '\142'
+#define CHAR_c '\143'
+#define CHAR_d '\144'
+#define CHAR_e '\145'
+#define CHAR_f '\146'
+#define CHAR_g '\147'
+#define CHAR_h '\150'
+#define CHAR_i '\151'
+#define CHAR_j '\152'
+#define CHAR_k '\153'
+#define CHAR_l '\154'
+#define CHAR_m '\155'
+#define CHAR_n '\156'
+#define CHAR_o '\157'
+#define CHAR_p '\160'
+#define CHAR_q '\161'
+#define CHAR_r '\162'
+#define CHAR_s '\163'
+#define CHAR_t '\164'
+#define CHAR_u '\165'
+#define CHAR_v '\166'
+#define CHAR_w '\167'
+#define CHAR_x '\170'
+#define CHAR_y '\171'
+#define CHAR_z '\172'
+#define CHAR_LEFT_CURLY_BRACKET '\173'
+#define CHAR_VERTICAL_LINE '\174'
+#define CHAR_RIGHT_CURLY_BRACKET '\175'
+#define CHAR_TILDE '\176'
+
+#define STR_HT "\011"
+#define STR_VT "\013"
+#define STR_FF "\014"
+#define STR_CR "\015"
+#define STR_NL "\012"
+#define STR_BS "\010"
+#define STR_BEL "\007"
+#define STR_ESC "\033"
+#define STR_DEL "\177"
+
+#define STR_SPACE "\040"
+#define STR_EXCLAMATION_MARK "\041"
+#define STR_QUOTATION_MARK "\042"
+#define STR_NUMBER_SIGN "\043"
+#define STR_DOLLAR_SIGN "\044"
+#define STR_PERCENT_SIGN "\045"
+#define STR_AMPERSAND "\046"
+#define STR_APOSTROPHE "\047"
+#define STR_LEFT_PARENTHESIS "\050"
+#define STR_RIGHT_PARENTHESIS "\051"
+#define STR_ASTERISK "\052"
+#define STR_PLUS "\053"
+#define STR_COMMA "\054"
+#define STR_MINUS "\055"
+#define STR_DOT "\056"
+#define STR_SLASH "\057"
+#define STR_0 "\060"
+#define STR_1 "\061"
+#define STR_2 "\062"
+#define STR_3 "\063"
+#define STR_4 "\064"
+#define STR_5 "\065"
+#define STR_6 "\066"
+#define STR_7 "\067"
+#define STR_8 "\070"
+#define STR_9 "\071"
+#define STR_COLON "\072"
+#define STR_SEMICOLON "\073"
+#define STR_LESS_THAN_SIGN "\074"
+#define STR_EQUALS_SIGN "\075"
+#define STR_GREATER_THAN_SIGN "\076"
+#define STR_QUESTION_MARK "\077"
+#define STR_COMMERCIAL_AT "\100"
+#define STR_A "\101"
+#define STR_B "\102"
+#define STR_C "\103"
+#define STR_D "\104"
+#define STR_E "\105"
+#define STR_F "\106"
+#define STR_G "\107"
+#define STR_H "\110"
+#define STR_I "\111"
+#define STR_J "\112"
+#define STR_K "\113"
+#define STR_L "\114"
+#define STR_M "\115"
+#define STR_N "\116"
+#define STR_O "\117"
+#define STR_P "\120"
+#define STR_Q "\121"
+#define STR_R "\122"
+#define STR_S "\123"
+#define STR_T "\124"
+#define STR_U "\125"
+#define STR_V "\126"
+#define STR_W "\127"
+#define STR_X "\130"
+#define STR_Y "\131"
+#define STR_Z "\132"
+#define STR_LEFT_SQUARE_BRACKET "\133"
+#define STR_BACKSLASH "\134"
+#define STR_RIGHT_SQUARE_BRACKET "\135"
+#define STR_CIRCUMFLEX_ACCENT "\136"
+#define STR_UNDERSCORE "\137"
+#define STR_GRAVE_ACCENT "\140"
+#define STR_a "\141"
+#define STR_b "\142"
+#define STR_c "\143"
+#define STR_d "\144"
+#define STR_e "\145"
+#define STR_f "\146"
+#define STR_g "\147"
+#define STR_h "\150"
+#define STR_i "\151"
+#define STR_j "\152"
+#define STR_k "\153"
+#define STR_l "\154"
+#define STR_m "\155"
+#define STR_n "\156"
+#define STR_o "\157"
+#define STR_p "\160"
+#define STR_q "\161"
+#define STR_r "\162"
+#define STR_s "\163"
+#define STR_t "\164"
+#define STR_u "\165"
+#define STR_v "\166"
+#define STR_w "\167"
+#define STR_x "\170"
+#define STR_y "\171"
+#define STR_z "\172"
+#define STR_LEFT_CURLY_BRACKET "\173"
+#define STR_VERTICAL_LINE "\174"
+#define STR_RIGHT_CURLY_BRACKET "\175"
+#define STR_TILDE "\176"
+
+#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
+#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
+#define STRING_F0 STR_F "\0"
+#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0"
+#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0"
+#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0"
+#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0"
+#define STRING_THEN STR_T STR_H STR_E STR_N
+
+#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0"
+#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0"
+#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0"
+#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0"
+#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0"
+#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0"
+#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0"
+#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0"
+#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0"
+#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0"
+#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0"
+#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0"
+#define STRING_word0 STR_w STR_o STR_r STR_d "\0"
+#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t
+
+#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E
+
+#define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS
+#define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_CRLF_RIGHTPAR STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_ANY_RIGHTPAR STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
+#define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
+#ifdef COMPILE_PCRE8
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+#endif
+#ifdef COMPILE_PCRE16
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
+#endif
+#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
+#define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS
+
+#endif /* SUPPORT_UTF */
+
+/* Escape items that are just an encoding of a particular data value. */
+
+#ifndef ESC_e
+#define ESC_e CHAR_ESC
+#endif
+
+#ifndef ESC_f
+#define ESC_f CHAR_FF
+#endif
+
+#ifndef ESC_n
+#define ESC_n CHAR_NL
+#endif
+
+#ifndef ESC_r
+#define ESC_r CHAR_CR
+#endif
+
+/* We can't officially use ESC_t because it is a POSIX reserved identifier
+(presumably because of all the others like size_t). */
+
+#ifndef ESC_tee
+#define ESC_tee CHAR_HT
+#endif
+
+/* Codes for different types of Unicode property */
+
+#define PT_ANY 0 /* Any property - matches all chars */
+#define PT_LAMP 1 /* L& - the union of Lu, Ll, Lt */
+#define PT_GC 2 /* Specified general characteristic (e.g. L) */
+#define PT_PC 3 /* Specified particular characteristic (e.g. Lu) */
+#define PT_SC 4 /* Script (e.g. Han) */
+#define PT_ALNUM 5 /* Alphanumeric - the union of L and N */
+#define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */
+#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
+#define PT_WORD 8 /* Word - L plus N plus underscore */
+
+/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
+contain characters with values greater than 255. */
+
+#define XCL_NOT 0x01 /* Flag: this is a negative class */
+#define XCL_MAP 0x02 /* Flag: a 32-byte map is present */
+
+#define XCL_END 0 /* Marks end of individual items */
+#define XCL_SINGLE 1 /* Single item (one multibyte char) follows */
+#define XCL_RANGE 2 /* A range (two multibyte chars) follows */
+#define XCL_PROP 3 /* Unicode property (2-byte property code follows) */
+#define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */
+
+/* These are escaped items that aren't just an encoding of a particular data
+value such as \n. They must have non-zero values, as check_escape() returns
+their negation. Also, they must appear in the same order as in the opcode
+definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it
+corresponds to "." in DOTALL mode rather than an escape sequence. It is also
+used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In
+non-DOTALL mode, "." behaves like \N.
+
+The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc.
+when PCRE_UCP is set, when replacement of \d etc by \p sequences is required.
+They must be contiguous, and remain in order so that the replacements can be
+looked up from a table.
+
+The final escape must be ESC_REF as subsequent values are used for
+backreferences (\1, \2, \3, etc). There are two tests in the code for an escape
+greater than ESC_b and less than ESC_Z to detect the types that may be
+repeated. These are the types that consume characters. If any new escapes are
+put in between that don't consume a character, that code will have to change.
+*/
+
+enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
+ ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
+ ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
+ ESC_E, ESC_Q, ESC_g, ESC_k,
+ ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu,
+ ESC_REF };
+
+/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
+OP_EOD must correspond in order to the list of escapes immediately above.
+
+*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
+that follow must also be updated to match. There are also tables called
+"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+
+enum {
+ OP_END, /* 0 End of pattern */
+
+ /* Values corresponding to backslashed metacharacters */
+
+ OP_SOD, /* 1 Start of data: \A */
+ OP_SOM, /* 2 Start of match (subject + offset): \G */
+ OP_SET_SOM, /* 3 Set start of match (\K) */
+ OP_NOT_WORD_BOUNDARY, /* 4 \B */
+ OP_WORD_BOUNDARY, /* 5 \b */
+ OP_NOT_DIGIT, /* 6 \D */
+ OP_DIGIT, /* 7 \d */
+ OP_NOT_WHITESPACE, /* 8 \S */
+ OP_WHITESPACE, /* 9 \s */
+ OP_NOT_WORDCHAR, /* 10 \W */
+ OP_WORDCHAR, /* 11 \w */
+
+ OP_ANY, /* 12 Match any character except newline */
+ OP_ALLANY, /* 13 Match any character */
+ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
+ OP_NOTPROP, /* 15 \P (not Unicode property) */
+ OP_PROP, /* 16 \p (Unicode property) */
+ OP_ANYNL, /* 17 \R (any newline sequence) */
+ OP_NOT_HSPACE, /* 18 \H (not horizontal whitespace) */
+ OP_HSPACE, /* 19 \h (horizontal whitespace) */
+ OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */
+ OP_VSPACE, /* 21 \v (vertical whitespace) */
+ OP_EXTUNI, /* 22 \X (extended Unicode sequence */
+ OP_EODN, /* 23 End of data or \n at end of data: \Z. */
+ OP_EOD, /* 24 End of data: \z */
+
+ OP_CIRC, /* 25 Start of line - not multiline */
+ OP_CIRCM, /* 26 Start of line - multiline */
+ OP_DOLL, /* 27 End of line - not multiline */
+ OP_DOLLM, /* 28 End of line - multiline */
+ OP_CHAR, /* 29 Match one character, casefully */
+ OP_CHARI, /* 30 Match one character, caselessly */
+ OP_NOT, /* 31 Match one character, not the given one, casefully */
+ OP_NOTI, /* 32 Match one character, not the given one, caselessly */
+
+ /* The following sets of 13 opcodes must always be kept in step because
+ the offset from the first one is used to generate the others. */
+
+ /**** Single characters, caseful, must precede the caseless ones ****/
+
+ OP_STAR, /* 33 The maximizing and minimizing versions of */
+ OP_MINSTAR, /* 34 these six opcodes must come in pairs, with */
+ OP_PLUS, /* 35 the minimizing one second. */
+ OP_MINPLUS, /* 36 */
+ OP_QUERY, /* 37 */
+ OP_MINQUERY, /* 38 */
+
+ OP_UPTO, /* 39 From 0 to n matches of one character, caseful*/
+ OP_MINUPTO, /* 40 */
+ OP_EXACT, /* 41 Exactly n matches */
+
+ OP_POSSTAR, /* 42 Possessified star, caseful */
+ OP_POSPLUS, /* 43 Possessified plus, caseful */
+ OP_POSQUERY, /* 44 Posesssified query, caseful */
+ OP_POSUPTO, /* 45 Possessified upto, caseful */
+
+ /**** Single characters, caseless, must follow the caseful ones */
+
+ OP_STARI, /* 46 */
+ OP_MINSTARI, /* 47 */
+ OP_PLUSI, /* 48 */
+ OP_MINPLUSI, /* 49 */
+ OP_QUERYI, /* 50 */
+ OP_MINQUERYI, /* 51 */
+
+ OP_UPTOI, /* 52 From 0 to n matches of one character, caseless */
+ OP_MINUPTOI, /* 53 */
+ OP_EXACTI, /* 54 */
+
+ OP_POSSTARI, /* 55 Possessified star, caseless */
+ OP_POSPLUSI, /* 56 Possessified plus, caseless */
+ OP_POSQUERYI, /* 57 Posesssified query, caseless */
+ OP_POSUPTOI, /* 58 Possessified upto, caseless */
+
+ /**** The negated ones must follow the non-negated ones, and match them ****/
+ /**** Negated single character, caseful; must precede the caseless ones ****/
+
+ OP_NOTSTAR, /* 59 The maximizing and minimizing versions of */
+ OP_NOTMINSTAR, /* 60 these six opcodes must come in pairs, with */
+ OP_NOTPLUS, /* 61 the minimizing one second. They must be in */
+ OP_NOTMINPLUS, /* 62 exactly the same order as those above. */
+ OP_NOTQUERY, /* 63 */
+ OP_NOTMINQUERY, /* 64 */
+
+ OP_NOTUPTO, /* 65 From 0 to n matches, caseful */
+ OP_NOTMINUPTO, /* 66 */
+ OP_NOTEXACT, /* 67 Exactly n matches */
+
+ OP_NOTPOSSTAR, /* 68 Possessified versions, caseful */
+ OP_NOTPOSPLUS, /* 69 */
+ OP_NOTPOSQUERY, /* 70 */
+ OP_NOTPOSUPTO, /* 71 */
+
+ /**** Negated single character, caseless; must follow the caseful ones ****/
+
+ OP_NOTSTARI, /* 72 */
+ OP_NOTMINSTARI, /* 73 */
+ OP_NOTPLUSI, /* 74 */
+ OP_NOTMINPLUSI, /* 75 */
+ OP_NOTQUERYI, /* 76 */
+ OP_NOTMINQUERYI, /* 77 */
+
+ OP_NOTUPTOI, /* 78 From 0 to n matches, caseless */
+ OP_NOTMINUPTOI, /* 79 */
+ OP_NOTEXACTI, /* 80 Exactly n matches */
+
+ OP_NOTPOSSTARI, /* 81 Possessified versions, caseless */
+ OP_NOTPOSPLUSI, /* 82 */
+ OP_NOTPOSQUERYI, /* 83 */
+ OP_NOTPOSUPTOI, /* 84 */
+
+ /**** Character types ****/
+
+ OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
+ OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
+ OP_TYPEPLUS, /* 87 the minimizing one second. These codes must */
+ OP_TYPEMINPLUS, /* 88 be in exactly the same order as those above. */
+ OP_TYPEQUERY, /* 89 */
+ OP_TYPEMINQUERY, /* 90 */
+
+ OP_TYPEUPTO, /* 91 From 0 to n matches */
+ OP_TYPEMINUPTO, /* 92 */
+ OP_TYPEEXACT, /* 93 Exactly n matches */
+
+ OP_TYPEPOSSTAR, /* 94 Possessified versions */
+ OP_TYPEPOSPLUS, /* 95 */
+ OP_TYPEPOSQUERY, /* 96 */
+ OP_TYPEPOSUPTO, /* 97 */
+
+ /* These are used for character classes and back references; only the
+ first six are the same as the sets above. */
+
+ OP_CRSTAR, /* 98 The maximizing and minimizing versions of */
+ OP_CRMINSTAR, /* 99 all these opcodes must come in pairs, with */
+ OP_CRPLUS, /* 100 the minimizing one second. These codes must */
+ OP_CRMINPLUS, /* 101 be in exactly the same order as those above. */
+ OP_CRQUERY, /* 102 */
+ OP_CRMINQUERY, /* 103 */
+
+ OP_CRRANGE, /* 104 These are different to the three sets above. */
+ OP_CRMINRANGE, /* 105 */
+
+ /* End of quantifier opcodes */
+
+ OP_CLASS, /* 106 Match a character class, chars < 256 only */
+ OP_NCLASS, /* 107 Same, but the bitmap was created from a negative
+ class - the difference is relevant only when a
+ character > 255 is encountered. */
+ OP_XCLASS, /* 108 Extended class for handling > 255 chars within the
+ class. This does both positive and negative. */
+ OP_REF, /* 109 Match a back reference, casefully */
+ OP_REFI, /* 110 Match a back reference, caselessly */
+ OP_RECURSE, /* 111 Match a numbered subpattern (possibly recursive) */
+ OP_CALLOUT, /* 112 Call out to external function if provided */
+
+ OP_ALT, /* 113 Start of alternation */
+ OP_KET, /* 114 End of group that doesn't have an unbounded repeat */
+ OP_KETRMAX, /* 115 These two must remain together and in this */
+ OP_KETRMIN, /* 116 order. They are for groups the repeat for ever. */
+ OP_KETRPOS, /* 117 Possessive unlimited repeat. */
+
+ /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
+ asserts must remain in order. */
+
+ OP_REVERSE, /* 118 Move pointer back - used in lookbehind assertions */
+ OP_ASSERT, /* 119 Positive lookahead */
+ OP_ASSERT_NOT, /* 120 Negative lookahead */
+ OP_ASSERTBACK, /* 121 Positive lookbehind */
+ OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */
+
+ /* ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately
+ after the assertions, with ONCE first, as there's a test for >= ONCE for a
+ subpattern that isn't an assertion. The POS versions must immediately follow
+ the non-POS versions in each case. */
+
+ OP_ONCE, /* 123 Atomic group, contains captures */
+ OP_ONCE_NC, /* 124 Atomic group containing no captures */
+ OP_BRA, /* 125 Start of non-capturing bracket */
+ OP_BRAPOS, /* 126 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 127 Start of capturing bracket */
+ OP_CBRAPOS, /* 128 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 129 Conditional group */
+
+ /* These five must follow the previous five, in the same order. There's a
+ check for >= SBRA to distinguish the two sets. */
+
+ OP_SBRA, /* 130 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 131 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 132 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 134 Conditional group, check empty */
+
+ /* The next two pairs must (respectively) be kept together. */
+
+ OP_CREF, /* 135 Used to hold a capture number as condition */
+ OP_NCREF, /* 136 Same, but generated by a name reference*/
+ OP_RREF, /* 137 Used to hold a recursion number as condition */
+ OP_NRREF, /* 138 Same, but generated by a name reference*/
+ OP_DEF, /* 139 The DEFINE condition */
+
+ OP_BRAZERO, /* 140 These two must remain together and in this */
+ OP_BRAMINZERO, /* 141 order. */
+ OP_BRAPOSZERO, /* 142 */
+
+ /* These are backtracking control verbs */
+
+ OP_MARK, /* 143 always has an argument */
+ OP_PRUNE, /* 144 */
+ OP_PRUNE_ARG, /* 145 same, but with argument */
+ OP_SKIP, /* 146 */
+ OP_SKIP_ARG, /* 147 same, but with argument */
+ OP_THEN, /* 148 */
+ OP_THEN_ARG, /* 149 same, but with argument */
+ OP_COMMIT, /* 150 */
+
+ /* These are forced failure and success verbs */
+
+ OP_FAIL, /* 151 */
+ OP_ACCEPT, /* 152 */
+ OP_ASSERT_ACCEPT, /* 153 Used inside assertions */
+ OP_CLOSE, /* 154 Used before OP_ACCEPT to close open captures */
+
+ /* This is used to skip a subpattern with a {0} quantifier */
+
+ OP_SKIPZERO, /* 155 */
+
+ /* This is not an opcode, but is used to check that tables indexed by opcode
+ are the correct length, in order to catch updating errors - there have been
+ some in the past. */
+
+ OP_TABLE_LENGTH
+};
+
+/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
+definitions that follow must also be updated to match. There are also tables
+called "coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+
+
+/* This macro defines textual names for all the opcodes. These are used only
+for debugging, and some of them are only partial names. The macro is referenced
+only in pcre_printint.c, which fills out the full names in many cases (and in
+some cases doesn't actually use these names at all). */
+
+#define OP_NAME_LIST \
+ "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d", \
+ "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
+ "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
+ "extuni", "\\Z", "\\z", \
+ "^", "^", "$", "$", "char", "chari", "not", "noti", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", \
+ "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
+ "*+","++", "?+", "{", \
+ "*", "*?", "+", "+?", "?", "??", "{", "{", \
+ "class", "nclass", "xclass", "Ref", "Refi", \
+ "Recurse", "Callout", \
+ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
+ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
+ "Once", "Once_NC", \
+ "Bra", "BraPos", "CBra", "CBraPos", \
+ "Cond", \
+ "SBra", "SBraPos", "SCBra", "SCBraPos", \
+ "SCond", \
+ "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
+ "Brazero", "Braminzero", "Braposzero", \
+ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
+ "*THEN", "*THEN", "*COMMIT", "*FAIL", \
+ "*ACCEPT", "*ASSERT_ACCEPT", \
+ "Close", "Skip zero"
+
+
+/* This macro defines the length of fixed length operations in the compiled
+regex. The lengths are used when searching for specific things, and also in the
+debugging printing of a compiled regex. We use a macro so that it can be
+defined close to the definitions of the opcodes themselves.
+
+As things have been extended, some of these are no longer fixed lenths, but are
+minima instead. For example, the length of a single-character repeat may vary
+in UTF-8 mode. The code that uses this table must know about such things. */
+
+#define OP_LENGTHS \
+ 1, /* End */ \
+ 1, 1, 1, 1, 1, /* \A, \G, \K, \B, \b */ \
+ 1, 1, 1, 1, 1, 1, /* \D, \d, \S, \s, \W, \w */ \
+ 1, 1, 1, /* Any, AllAny, Anybyte */ \
+ 3, 3, /* \P, \p */ \
+ 1, 1, 1, 1, 1, /* \R, \H, \h, \V, \v */ \
+ 1, /* \X */ \
+ 1, 1, 1, 1, 1, 1, /* \Z, \z, ^, ^M, $, $M */ \
+ 2, /* Char - the minimum length */ \
+ 2, /* Chari - the minimum length */ \
+ 2, /* not */ \
+ 2, /* noti */ \
+ /* Positive single-char repeats ** These are */ \
+ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto, minupto ** mode */ \
+ 2+IMM2_SIZE, /* exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+, ++, ?+, upto+ */ \
+ 2, 2, 2, 2, 2, 2, /* *I, *?I, +I, +?I, ?I, ??I ** UTF-8 */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* upto I, minupto I */ \
+ 2+IMM2_SIZE, /* exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* *+I, ++I, ?+I, upto+I */ \
+ /* Negative single-char repeats - only for chars < 256 */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto, minupto */ \
+ 2+IMM2_SIZE, /* NOT exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *, +, ?, upto */ \
+ 2, 2, 2, 2, 2, 2, /* NOT *I, *?I, +I, +?I, ?I, ??I */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* NOT upto I, minupto I */ \
+ 2+IMM2_SIZE, /* NOT exact I */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive NOT *I, +I, ?I, upto I */ \
+ /* Positive type repeats */ \
+ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \
+ 2+IMM2_SIZE, 2+IMM2_SIZE, /* Type upto, minupto */ \
+ 2+IMM2_SIZE, /* Type exact */ \
+ 2, 2, 2, 2+IMM2_SIZE, /* Possessive *+, ++, ?+, upto+ */ \
+ /* Character class & ref repeats */ \
+ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
+ 1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
+ 1+(32/sizeof(pcre_uchar)), /* CLASS */ \
+ 1+(32/sizeof(pcre_uchar)), /* NCLASS */ \
+ 0, /* XCLASS - variable length */ \
+ 1+IMM2_SIZE, /* REF */ \
+ 1+IMM2_SIZE, /* REFI */ \
+ 1+LINK_SIZE, /* RECURSE */ \
+ 2+2*LINK_SIZE, /* CALLOUT */ \
+ 1+LINK_SIZE, /* Alt */ \
+ 1+LINK_SIZE, /* Ket */ \
+ 1+LINK_SIZE, /* KetRmax */ \
+ 1+LINK_SIZE, /* KetRmin */ \
+ 1+LINK_SIZE, /* KetRpos */ \
+ 1+LINK_SIZE, /* Reverse */ \
+ 1+LINK_SIZE, /* Assert */ \
+ 1+LINK_SIZE, /* Assert not */ \
+ 1+LINK_SIZE, /* Assert behind */ \
+ 1+LINK_SIZE, /* Assert behind not */ \
+ 1+LINK_SIZE, /* ONCE */ \
+ 1+LINK_SIZE, /* ONCE_NC */ \
+ 1+LINK_SIZE, /* BRA */ \
+ 1+LINK_SIZE, /* BRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* CBRAPOS */ \
+ 1+LINK_SIZE, /* COND */ \
+ 1+LINK_SIZE, /* SBRA */ \
+ 1+LINK_SIZE, /* SBRAPOS */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRA */ \
+ 1+LINK_SIZE+IMM2_SIZE, /* SCBRAPOS */ \
+ 1+LINK_SIZE, /* SCOND */ \
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* CREF, NCREF */ \
+ 1+IMM2_SIZE, 1+IMM2_SIZE, /* RREF, NRREF */ \
+ 1, /* DEF */ \
+ 1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
+ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
+ 1, 3, /* SKIP, SKIP_ARG */ \
+ 1, 3, /* THEN, THEN_ARG */ \
+ 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \
+ 1+IMM2_SIZE, 1 /* CLOSE, SKIPZERO */
+
+/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion"
+condition. */
+
+#define RREF_ANY 0xffff
+
+/* Compile time error code numbers. They are given names so that they can more
+easily be tracked. When a new number is added, the table called eint in
+pcreposix.c must be updated. */
+
+enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
+ ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
+ ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
+ ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
+ ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
+ ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
+ ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69,
+ ERR70, ERR71, ERR72, ERR73, ERR74, ERRCOUNT };
+
+/* The real format of the start of the pcre block; the index of names and the
+code vector run on as long as necessary after the end. We store an explicit
+offset to the name table so that if a regex is compiled on one host, saved, and
+then run on another where the size of pointers is different, all might still
+be well. For the case of compiled-on-4 and run-on-8, we include an extra
+pointer that is always NULL. For future-proofing, a few dummy fields were
+originally included - even though you can never get this planning right - but
+there is only one left now.
+
+NOTE NOTE NOTE:
+Because people can now save and re-use compiled patterns, any additions to this
+structure should be made at the end, and something earlier (e.g. a new
+flag in the options or one of the dummy fields) should indicate that the new
+fields are present. Currently PCRE always sets the dummy fields to zero.
+NOTE NOTE NOTE
+*/
+
+#ifdef COMPILE_PCRE8
+#define REAL_PCRE real_pcre
+#else
+#define REAL_PCRE real_pcre16
+#endif
+
+typedef struct REAL_PCRE {
+ pcre_uint32 magic_number;
+ pcre_uint32 size; /* Total that was malloced */
+ pcre_uint32 options; /* Public options */
+ pcre_uint16 flags; /* Private flags */
+ pcre_uint16 dummy1; /* For future use */
+ pcre_uint16 top_bracket;
+ pcre_uint16 top_backref;
+ pcre_uint16 first_char; /* Starting character */
+ pcre_uint16 req_char; /* This character must be seen */
+ pcre_uint16 name_table_offset; /* Offset to name table that follows */
+ pcre_uint16 name_entry_size; /* Size of any name items */
+ pcre_uint16 name_count; /* Number of name items */
+ pcre_uint16 ref_count; /* Reference count */
+
+ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
+ const pcre_uint8 *nullpad; /* NULL padding */
+} REAL_PCRE;
+
+/* The format of the block used to store data from pcre_study(). The same
+remark (see NOTE above) about extending this structure applies. */
+
+typedef struct pcre_study_data {
+ pcre_uint32 size; /* Total that was malloced */
+ pcre_uint32 flags; /* Private flags */
+ pcre_uint8 start_bits[32]; /* Starting char bits */
+ pcre_uint32 minlength; /* Minimum subject length */
+} pcre_study_data;
+
+/* Structure for building a chain of open capturing subpatterns during
+compiling, so that instructions to close them can be compiled when (*ACCEPT) is
+encountered. This is also used to identify subpatterns that contain recursive
+back references to themselves, so that they can be made atomic. */
+
+typedef struct open_capitem {
+ struct open_capitem *next; /* Chain link */
+ pcre_uint16 number; /* Capture number */
+ pcre_uint16 flag; /* Set TRUE if recursive back ref */
+} open_capitem;
+
+/* Structure for passing "static" information around between the functions
+doing the compiling, so that they are thread-safe. */
+
+typedef struct compile_data {
+ const pcre_uint8 *lcc; /* Points to lower casing table */
+ const pcre_uint8 *fcc; /* Points to case-flipping table */
+ const pcre_uint8 *cbits; /* Points to character type table */
+ const pcre_uint8 *ctypes; /* Points to table of type maps */
+ const pcre_uchar *start_workspace;/* The start of working space */
+ const pcre_uchar *start_code; /* The start of the compiled code */
+ const pcre_uchar *start_pattern; /* The start of the pattern */
+ const pcre_uchar *end_pattern; /* The end of the pattern */
+ open_capitem *open_caps; /* Chain of open capture items */
+ pcre_uchar *hwm; /* High watermark of workspace */
+ pcre_uchar *name_table; /* The name/number table */
+ int names_found; /* Number of entries so far */
+ int name_entry_size; /* Size of each entry */
+ int workspace_size; /* Size of workspace */
+ int bracount; /* Count of capturing parens as we compile */
+ int final_bracount; /* Saved value after first pass */
+ int top_backref; /* Maximum back reference */
+ unsigned int backref_map; /* Bitmap of low back refs */
+ int assert_depth; /* Depth of nested assertions */
+ int external_options; /* External (initial) options */
+ int external_flags; /* External flag bits to be set */
+ int req_varyopt; /* "After variable item" flag for reqbyte */
+ BOOL had_accept; /* (*ACCEPT) encountered */
+ BOOL check_lookbehind; /* Lookbehinds need later checking */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ pcre_uchar nl[4]; /* Newline string when fixed length */
+} compile_data;
+
+/* Structure for maintaining a chain of pointers to the currently incomplete
+branches, for testing for left recursion while compiling. */
+
+typedef struct branch_chain {
+ struct branch_chain *outer;
+ pcre_uchar *current_branch;
+} branch_chain;
+
+/* Structure for items in a linked list that represents an explicit recursive
+call within the pattern; used by pcre_exec(). */
+
+typedef struct recursion_info {
+ struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
+ int group_num; /* Number of group that was called */
+ int *offset_save; /* Pointer to start of saved offsets */
+ int saved_max; /* Number of saved offsets */
+ PCRE_PUCHAR subject_position; /* Position at start of recursion */
+} recursion_info;
+
+/* A similar structure for pcre_dfa_exec(). */
+
+typedef struct dfa_recursion_info {
+ struct dfa_recursion_info *prevrec;
+ int group_num;
+ PCRE_PUCHAR subject_position;
+} dfa_recursion_info;
+
+/* Structure for building a chain of data for holding the values of the subject
+pointer at the start of each subpattern, so as to detect when an empty string
+has been matched by a subpattern - to break infinite loops; used by
+pcre_exec(). */
+
+typedef struct eptrblock {
+ struct eptrblock *epb_prev;
+ PCRE_PUCHAR epb_saved_eptr;
+} eptrblock;
+
+
+/* Structure for passing "static" information around between the functions
+doing traditional NFA matching, so that they are thread-safe. */
+
+typedef struct match_data {
+ unsigned long int match_call_count; /* As it says */
+ unsigned long int match_limit; /* As it says */
+ unsigned long int match_limit_recursion; /* As it says */
+ int *offset_vector; /* Offset vector */
+ int offset_end; /* One past the end */
+ int offset_max; /* The maximum usable for return data */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ int name_count; /* Number of names in name table */
+ int name_entry_size; /* Size of entry in names table */
+ pcre_uchar *name_table; /* Table of names */
+ pcre_uchar nl[4]; /* Newline string when fixed */
+ const pcre_uint8 *lcc; /* Points to lower casing table */
+ const pcre_uint8 *fcc; /* Points to case-flipping table */
+ const pcre_uint8 *ctypes; /* Points to table of type maps */
+ BOOL offset_overflow; /* Set if too many extractions */
+ BOOL notbol; /* NOTBOL flag */
+ BOOL noteol; /* NOTEOL flag */
+ BOOL utf; /* UTF-8 / UTF-16 flag */
+ BOOL jscript_compat; /* JAVASCRIPT_COMPAT flag */
+ BOOL use_ucp; /* PCRE_UCP flag */
+ BOOL endonly; /* Dollar not before final \n */
+ BOOL notempty; /* Empty string match not wanted */
+ BOOL notempty_atstart; /* Empty string match at start not wanted */
+ BOOL hitend; /* Hit the end of the subject at some point */
+ BOOL bsr_anycrlf; /* \R is just any CRLF, not full Unicode */
+ BOOL hasthen; /* Pattern contains (*THEN) */
+ BOOL ignore_skip_arg; /* For re-run when SKIP name not found */
+ const pcre_uchar *start_code; /* For use when recursing */
+ PCRE_PUCHAR start_subject; /* Start of the subject string */
+ PCRE_PUCHAR end_subject; /* End of the subject string */
+ PCRE_PUCHAR start_match_ptr; /* Start of matched string */
+ PCRE_PUCHAR end_match_ptr; /* Subject position at end match */
+ PCRE_PUCHAR start_used_ptr; /* Earliest consulted character */
+ int partial; /* PARTIAL options */
+ int end_offset_top; /* Highwater mark at end of match */
+ int capture_last; /* Most recent capture number */
+ int start_offset; /* The start offset value */
+ int match_function_type; /* Set for certain special calls of MATCH() */
+ eptrblock *eptrchain; /* Chain of eptrblocks for tail recursions */
+ int eptrn; /* Next free eptrblock */
+ recursion_info *recursive; /* Linked list of recursion data */
+ void *callout_data; /* To pass back to callouts */
+ const pcre_uchar *mark; /* Mark pointer to pass back on success */
+ const pcre_uchar *nomatch_mark;/* Mark pointer to pass back on failure */
+ const pcre_uchar *once_target; /* Where to back up to for atomic groups */
+} match_data;
+
+/* A similar structure is used for the same purpose by the DFA matching
+functions. */
+
+typedef struct dfa_match_data {
+ const pcre_uchar *start_code; /* Start of the compiled pattern */
+ const pcre_uchar *start_subject ; /* Start of the subject string */
+ const pcre_uchar *end_subject; /* End of subject string */
+ const pcre_uchar *start_used_ptr; /* Earliest consulted character */
+ const pcre_uint8 *tables; /* Character tables */
+ int start_offset; /* The start offset value */
+ int moptions; /* Match options */
+ int poptions; /* Pattern options */
+ int nltype; /* Newline type */
+ int nllen; /* Newline string length */
+ pcre_uchar nl[4]; /* Newline string when fixed */
+ void *callout_data; /* To pass back to callouts */
+ dfa_recursion_info *recursive; /* Linked list of recursion data */
+} dfa_match_data;
+
+/* Bit definitions for entries in the pcre_ctypes table. */
+
+#define ctype_space 0x01
+#define ctype_letter 0x02
+#define ctype_digit 0x04
+#define ctype_xdigit 0x08
+#define ctype_word 0x10 /* alphanumeric or '_' */
+#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
+
+/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
+of bits for a class map. Some classes are built by combining these tables. */
+
+#define cbit_space 0 /* [:space:] or \s */
+#define cbit_xdigit 32 /* [:xdigit:] */
+#define cbit_digit 64 /* [:digit:] or \d */
+#define cbit_upper 96 /* [:upper:] */
+#define cbit_lower 128 /* [:lower:] */
+#define cbit_word 160 /* [:word:] or \w */
+#define cbit_graph 192 /* [:graph:] */
+#define cbit_print 224 /* [:print:] */
+#define cbit_punct 256 /* [:punct:] */
+#define cbit_cntrl 288 /* [:cntrl:] */
+#define cbit_length 320 /* Length of the cbits table */
+
+/* Offsets of the various tables from the base tables pointer, and
+total length. */
+
+#define lcc_offset 0
+#define fcc_offset 256
+#define cbits_offset 512
+#define ctypes_offset (cbits_offset + cbit_length)
+#define tables_length (ctypes_offset + 256)
+
+/* Internal function prefix */
+
+#ifdef COMPILE_PCRE8
+#ifndef PUBL
+#define PUBL(name) pcre_##name
+#endif
+#ifndef PRIV
+#define PRIV(name) _pcre_##name
+#endif
+#else /* COMPILE_PCRE8 */
+#ifdef COMPILE_PCRE16
+#ifndef PUBL
+#define PUBL(name) pcre16_##name
+#endif
+#ifndef PRIV
+#define PRIV(name) _pcre16_##name
+#endif
+#else
+#error Unsupported compiling mode
+#endif /* COMPILE_PCRE16 */
+#endif /* COMPILE_PCRE8 */
+
+/* Layout of the UCP type table that translates property names into types and
+codes. Each entry used to point directly to a name, but to reduce the number of
+relocations in shared libraries, it now has an offset into a single string
+instead. */
+
+typedef struct {
+ pcre_uint16 name_offset;
+ pcre_uint16 type;
+ pcre_uint16 value;
+} ucp_type_table;
+
+
+/* Internal shared data tables. These are tables that are used by more than one
+of the exported public functions. They have to be "external" in the C sense,
+but are not part of the PCRE public API. The data for these tables is in the
+pcre_tables.c module. */
+
+#ifdef COMPILE_PCRE8
+
+extern const int PRIV(utf8_table1)[];
+extern const int PRIV(utf8_table1_size);
+extern const int PRIV(utf8_table2)[];
+extern const int PRIV(utf8_table3)[];
+extern const pcre_uint8 PRIV(utf8_table4)[];
+
+#endif /* COMPILE_PCRE8 */
+
+extern const char PRIV(utt_names)[];
+extern const ucp_type_table PRIV(utt)[];
+extern const int PRIV(utt_size);
+
+extern const pcre_uint8 PRIV(default_tables)[];
+
+extern const pcre_uint8 PRIV(OP_lengths)[];
+
+
+/* Internal shared functions. These are functions that are used by more than
+one of the exported public functions. They have to be "external" in the C
+sense, but are not part of the PCRE public API. */
+
+/* String comparison functions. */
+#ifdef COMPILE_PCRE8
+
+#define STRCMP_UC_UC(str1, str2) \
+ strcmp((char *)(str1), (char *)(str2))
+#define STRCMP_UC_C8(str1, str2) \
+ strcmp((char *)(str1), (str2))
+#define STRNCMP_UC_UC(str1, str2, num) \
+ strncmp((char *)(str1), (char *)(str2), (num))
+#define STRNCMP_UC_C8(str1, str2, num) \
+ strncmp((char *)(str1), (str2), (num))
+#define STRLEN_UC(str) strlen((const char *)str)
+
+#else
+
+extern int PRIV(strcmp_uc_uc)(const pcre_uchar *,
+ const pcre_uchar *);
+extern int PRIV(strcmp_uc_c8)(const pcre_uchar *,
+ const char *);
+extern int PRIV(strncmp_uc_uc)(const pcre_uchar *,
+ const pcre_uchar *, unsigned int num);
+extern int PRIV(strncmp_uc_c8)(const pcre_uchar *,
+ const char *, unsigned int num);
+extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str);
+
+#define STRCMP_UC_UC(str1, str2) \
+ PRIV(strcmp_uc_uc)((str1), (str2))
+#define STRCMP_UC_C8(str1, str2) \
+ PRIV(strcmp_uc_c8)((str1), (str2))
+#define STRNCMP_UC_UC(str1, str2, num) \
+ PRIV(strncmp_uc_uc)((str1), (str2), (num))
+#define STRNCMP_UC_C8(str1, str2, num) \
+ PRIV(strncmp_uc_c8)((str1), (str2), (num))
+#define STRLEN_UC(str) PRIV(strlen_uc)(str)
+
+#endif /* COMPILE_PCRE8 */
+
+extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int);
+extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
+ int *, BOOL);
+extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *);
+extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *);
+extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR,
+ int *, BOOL);
+extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL);
+
+#ifdef SUPPORT_JIT
+extern void PRIV(jit_compile)(const REAL_PCRE *, PUBL(extra) *);
+extern int PRIV(jit_exec)(const REAL_PCRE *, void *,
+ const pcre_uchar *, int, int, int, int, int *, int);
+extern void PRIV(jit_free)(void *);
+extern int PRIV(jit_get_size)(void *);
+extern const char* PRIV(jit_get_target)(void);
+#endif
+
+/* Unicode character database (UCD) */
+
+typedef struct {
+ pcre_uint8 script;
+ pcre_uint8 chartype;
+ pcre_int32 other_case;
+} ucd_record;
+
+extern const ucd_record PRIV(ucd_records)[];
+extern const pcre_uint8 PRIV(ucd_stage1)[];
+extern const pcre_uint16 PRIV(ucd_stage2)[];
+extern const int PRIV(ucp_gentype)[];
+#ifdef SUPPORT_JIT
+extern const int PRIV(ucp_typerange)[];
+#endif
+
+#ifdef SUPPORT_UCP
+/* UCD access macros */
+
+#define UCD_BLOCK_SIZE 128
+#define GET_UCD(ch) (PRIV(ucd_records) + \
+ PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \
+ UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE])
+
+#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype
+#define UCD_SCRIPT(ch) GET_UCD(ch)->script
+#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)]
+#define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case)
+
+#endif /* SUPPORT_UCP */
+
+#endif
+
+/* End of pcre_internal.h */
diff --git a/src/3rdparty/pcre/pcre_jit_compile.c b/src/3rdparty/pcre/pcre_jit_compile.c
new file mode 100644
index 00000000000..f3d240d100a
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_jit_compile.c
@@ -0,0 +1,6915 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+ The machine code generator part (this module) was written by Zoltan Herczeg
+ Copyright (c) 2010-2012
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#ifdef SUPPORT_JIT
+
+/* All-in-one: Since we use the JIT compiler only from here,
+we just include it. This way we don't need to touch the build
+system files. */
+
+#define SLJIT_MALLOC(size) (PUBL(malloc))(size)
+#define SLJIT_FREE(ptr) (PUBL(free))(ptr)
+#define SLJIT_CONFIG_AUTO 1
+#define SLJIT_CONFIG_STATIC 1
+#define SLJIT_VERBOSE 0
+#define SLJIT_DEBUG 0
+
+#include "sljit/sljitLir.c"
+
+#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
+#error Unsupported architecture
+#endif
+
+/* Allocate memory on the stack. Fast, but limited size. */
+#define LOCAL_SPACE_SIZE 32768
+
+#define STACK_GROWTH_RATE 8192
+
+/* Enable to check that the allocation could destroy temporaries. */
+#if defined SLJIT_DEBUG && SLJIT_DEBUG
+#define DESTROY_REGISTERS 1
+#endif
+
+/*
+Short summary about the backtracking mechanism empolyed by the jit code generator:
+
+The code generator follows the recursive nature of the PERL compatible regular
+expressions. The basic blocks of regular expressions are condition checkers
+whose execute different commands depending on the result of the condition check.
+The relationship between the operators can be horizontal (concatenation) and
+vertical (sub-expression) (See struct fallback_common for more details).
+
+ 'ab' - 'a' and 'b' regexps are concatenated
+ 'a+' - 'a' is the sub-expression of the '+' operator
+
+The condition checkers are boolean (true/false) checkers. Machine code is generated
+for the checker itself and for the actions depending on the result of the checker.
+The 'true' case is called as the hot path (expected path), and the other is called as
+the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken
+branches on the hot path.
+
+ Greedy star operator (*) :
+ Hot path: match happens.
+ Fallback path: match failed.
+ Non-greedy star operator (*?) :
+ Hot path: no need to perform a match.
+ Fallback path: match is required.
+
+The following example shows how the code generated for a capturing bracket
+with two alternatives. Let A, B, C, D are arbirary regular expressions, and
+we have the following regular expression:
+
+ A(B|C)D
+
+The generated code will be the following:
+
+ A hot path
+ '(' hot path (pushing arguments to the stack)
+ B hot path
+ ')' hot path (pushing arguments to the stack)
+ D hot path
+ return with successful match
+
+ D fallback path
+ ')' fallback path (If we arrived from "C" jump to the fallback of "C")
+ B fallback path
+ C expected path
+ jump to D hot path
+ C fallback path
+ A fallback path
+
+ Notice, that the order of fallback code paths are the opposite of the fast
+ code paths. In this way the topmost value on the stack is always belong
+ to the current fallback code path. The fallback code path must check
+ whether there is a next alternative. If so, it needs to jump back to
+ the hot path eventually. Otherwise it needs to clear out its own stack
+ frame and continue the execution on the fallback code paths.
+*/
+
+/*
+Saved stack frames:
+
+Atomic blocks and asserts require reloading the values of local variables
+when the fallback mechanism performed. Because of OP_RECURSE, the locals
+are not necessarly known in compile time, thus we need a dynamic restore
+mechanism.
+
+The stack frames are stored in a chain list, and have the following format:
+([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
+
+Thus we can restore the locals to a particular point in the stack.
+*/
+
+typedef struct jit_arguments {
+ /* Pointers first. */
+ struct sljit_stack *stack;
+ const pcre_uchar *str;
+ const pcre_uchar *begin;
+ const pcre_uchar *end;
+ int *offsets;
+ pcre_uchar *ptr;
+ /* Everything else after. */
+ int offsetcount;
+ int calllimit;
+ pcre_uint8 notbol;
+ pcre_uint8 noteol;
+ pcre_uint8 notempty;
+ pcre_uint8 notempty_atstart;
+} jit_arguments;
+
+typedef struct executable_function {
+ void *executable_func;
+ PUBL(jit_callback) callback;
+ void *userdata;
+ sljit_uw executable_size;
+} executable_function;
+
+typedef struct jump_list {
+ struct sljit_jump *jump;
+ struct jump_list *next;
+} jump_list;
+
+enum stub_types { stack_alloc };
+
+typedef struct stub_list {
+ enum stub_types type;
+ int data;
+ struct sljit_jump *start;
+ struct sljit_label *leave;
+ struct stub_list *next;
+} stub_list;
+
+typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
+
+/* The following structure is the key data type for the recursive
+code generator. It is allocated by compile_hotpath, and contains
+the aguments for compile_fallbackpath. Must be the first member
+of its descendants. */
+typedef struct fallback_common {
+ /* Concatenation stack. */
+ struct fallback_common *prev;
+ jump_list *nextfallbacks;
+ /* Internal stack (for component operators). */
+ struct fallback_common *top;
+ jump_list *topfallbacks;
+ /* Opcode pointer. */
+ pcre_uchar *cc;
+} fallback_common;
+
+typedef struct assert_fallback {
+ fallback_common common;
+ jump_list *condfailed;
+ /* Less than 0 (-1) if a frame is not needed. */
+ int framesize;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+ /* For iterators. */
+ struct sljit_label *hotpath;
+} assert_fallback;
+
+typedef struct bracket_fallback {
+ fallback_common common;
+ /* Where to coninue if an alternative is successfully matched. */
+ struct sljit_label *althotpath;
+ /* For rmin and rmax iterators. */
+ struct sljit_label *recursivehotpath;
+ /* For greedy ? operator. */
+ struct sljit_label *zerohotpath;
+ /* Contains the branches of a failed condition. */
+ union {
+ /* Both for OP_COND, OP_SCOND. */
+ jump_list *condfailed;
+ assert_fallback *assert;
+ /* For OP_ONCE. -1 if not needed. */
+ int framesize;
+ } u;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+} bracket_fallback;
+
+typedef struct bracketpos_fallback {
+ fallback_common common;
+ /* Points to our private memory word on the stack. */
+ int localptr;
+ /* Reverting stack is needed. */
+ int framesize;
+ /* Allocated stack size. */
+ int stacksize;
+} bracketpos_fallback;
+
+typedef struct braminzero_fallback {
+ fallback_common common;
+ struct sljit_label *hotpath;
+} braminzero_fallback;
+
+typedef struct iterator_fallback {
+ fallback_common common;
+ /* Next iteration. */
+ struct sljit_label *hotpath;
+} iterator_fallback;
+
+typedef struct recurse_entry {
+ struct recurse_entry *next;
+ /* Contains the function entry. */
+ struct sljit_label *entry;
+ /* Collects the calls until the function is not created. */
+ jump_list *calls;
+ /* Points to the starting opcode. */
+ int start;
+} recurse_entry;
+
+typedef struct recurse_fallback {
+ fallback_common common;
+} recurse_fallback;
+
+typedef struct compiler_common {
+ struct sljit_compiler *compiler;
+ pcre_uchar *start;
+ int localsize;
+ int *localptrs;
+ const pcre_uint8 *fcc;
+ sljit_w lcc;
+ int cbraptr;
+ int nltype;
+ int newline;
+ int bsr_nltype;
+ int endonly;
+ sljit_w ctypes;
+ sljit_uw name_table;
+ sljit_w name_count;
+ sljit_w name_entry_size;
+ struct sljit_label *acceptlabel;
+ stub_list *stubs;
+ recurse_entry *entries;
+ recurse_entry *currententry;
+ jump_list *accept;
+ jump_list *calllimit;
+ jump_list *stackalloc;
+ jump_list *revertframes;
+ jump_list *wordboundary;
+ jump_list *anynewline;
+ jump_list *hspace;
+ jump_list *vspace;
+ jump_list *casefulcmp;
+ jump_list *caselesscmp;
+ BOOL jscript_compat;
+#ifdef SUPPORT_UTF
+ BOOL utf;
+#ifdef SUPPORT_UCP
+ BOOL use_ucp;
+#endif
+ jump_list *utfreadchar;
+#ifdef COMPILE_PCRE8
+ jump_list *utfreadtype8;
+#endif
+#endif /* SUPPORT_UTF */
+#ifdef SUPPORT_UCP
+ jump_list *getucd;
+#endif
+} compiler_common;
+
+/* For byte_sequence_compare. */
+
+typedef struct compare_context {
+ int length;
+ int sourcereg;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ int ucharptr;
+ union {
+ sljit_i asint;
+ sljit_uh asushort;
+#ifdef COMPILE_PCRE8
+ sljit_ub asbyte;
+ sljit_ub asuchars[4];
+#else
+#ifdef COMPILE_PCRE16
+ sljit_uh asuchars[2];
+#endif
+#endif
+ } c;
+ union {
+ sljit_i asint;
+ sljit_uh asushort;
+#ifdef COMPILE_PCRE8
+ sljit_ub asbyte;
+ sljit_ub asuchars[4];
+#else
+#ifdef COMPILE_PCRE16
+ sljit_uh asuchars[2];
+#endif
+#endif
+ } oc;
+#endif
+} compare_context;
+
+enum {
+ frame_end = 0,
+ frame_setstrbegin = -1
+};
+
+/* Undefine sljit macros. */
+#undef CMP
+
+/* Used for accessing the elements of the stack. */
+#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w))
+
+#define TMP1 SLJIT_TEMPORARY_REG1
+#define TMP2 SLJIT_TEMPORARY_REG3
+#define TMP3 SLJIT_TEMPORARY_EREG2
+#define STR_PTR SLJIT_SAVED_REG1
+#define STR_END SLJIT_SAVED_REG2
+#define STACK_TOP SLJIT_TEMPORARY_REG2
+#define STACK_LIMIT SLJIT_SAVED_REG3
+#define ARGUMENTS SLJIT_SAVED_EREG1
+#define CALL_COUNT SLJIT_SAVED_EREG2
+#define RETURN_ADDR SLJIT_TEMPORARY_EREG1
+
+/* Locals layout. */
+/* These two locals can be used by the current opcode. */
+#define LOCALS0 (0 * sizeof(sljit_w))
+#define LOCALS1 (1 * sizeof(sljit_w))
+/* Two local variables for possessive quantifiers (char1 cannot use them). */
+#define POSSESSIVE0 (2 * sizeof(sljit_w))
+#define POSSESSIVE1 (3 * sizeof(sljit_w))
+/* Head of the last recursion. */
+#define RECURSIVE_HEAD (4 * sizeof(sljit_w))
+/* Max limit of recursions. */
+#define CALL_LIMIT (5 * sizeof(sljit_w))
+/* Last known position of the requested byte. */
+#define REQ_CHAR_PTR (6 * sizeof(sljit_w))
+/* End pointer of the first line. */
+#define FIRSTLINE_END (7 * sizeof(sljit_w))
+/* The output vector is stored on the stack, and contains pointers
+to characters. The vector data is divided into two groups: the first
+group contains the start / end character pointers, and the second is
+the start pointers when the end of the capturing group has not yet reached. */
+#define OVECTOR_START (8 * sizeof(sljit_w))
+#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w))
+#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w))
+#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start])
+
+#ifdef COMPILE_PCRE8
+#define MOV_UCHAR SLJIT_MOV_UB
+#define MOVU_UCHAR SLJIT_MOVU_UB
+#else
+#ifdef COMPILE_PCRE16
+#define MOV_UCHAR SLJIT_MOV_UH
+#define MOVU_UCHAR SLJIT_MOVU_UH
+#else
+#error Unsupported compiling mode
+#endif
+#endif
+
+/* Shortcuts. */
+#define DEFINE_COMPILER \
+ struct sljit_compiler *compiler = common->compiler
+#define OP1(op, dst, dstw, src, srcw) \
+ sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
+#define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
+ sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
+#define LABEL() \
+ sljit_emit_label(compiler)
+#define JUMP(type) \
+ sljit_emit_jump(compiler, (type))
+#define JUMPTO(type, label) \
+ sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
+#define JUMPHERE(jump) \
+ sljit_set_label((jump), sljit_emit_label(compiler))
+#define CMP(type, src1, src1w, src2, src2w) \
+ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
+#define CMPTO(type, src1, src1w, src2, src2w, label) \
+ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
+#define COND_VALUE(op, dst, dstw, type) \
+ sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
+
+static pcre_uchar* bracketend(pcre_uchar* cc)
+{
+SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
+do cc += GET(cc, 1); while (*cc == OP_ALT);
+SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+/* Functions whose might need modification for all new supported opcodes:
+ next_opcode
+ get_localspace
+ set_localptrs
+ get_framesize
+ init_frame
+ get_localsize
+ copy_locals
+ compile_hotpath
+ compile_fallbackpath
+*/
+
+static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
+{
+SLJIT_UNUSED_ARG(common);
+switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_SET_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_DEF:
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_SKIPZERO:
+ return cc + 1;
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UTF
+ if (common->utf) return NULL;
+#endif
+ return cc + 1;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSUPTO:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSUPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSUPTOI:
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ return cc;
+
+ case OP_NOTPROP:
+ case OP_PROP:
+ return cc + 1 + 2;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSUPTO:
+ case OP_REF:
+ case OP_REFI:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_CLOSE:
+ cc += 1 + IMM2_SIZE;
+ return cc;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ return cc + 1 + 2 * IMM2_SIZE;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ return cc + 1 + 32 / sizeof(pcre_uchar);
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ return cc + GET(cc, 1);
+#endif
+
+ case OP_RECURSE:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_REVERSE:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ return cc + 1 + LINK_SIZE;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ return cc + 1 + LINK_SIZE + IMM2_SIZE;
+
+ default:
+ return NULL;
+ }
+}
+
+static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+{
+int localspace = 0;
+pcre_uchar *alternative;
+/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ localspace += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ if (cc == NULL)
+ return -1;
+ break;
+ }
+ }
+return localspace;
+}
+
+static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
+{
+pcre_uchar *cc = common->start;
+pcre_uchar *alternative;
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ common->localptrs[cc - common->start] = localptr;
+ localptr += sizeof(sljit_w);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+}
+
+/* Returns with -1 if no need for frame. */
+static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
+{
+pcre_uchar *ccend = bracketend(cc);
+int length = 0;
+BOOL possessive = FALSE;
+BOOL setsom_found = FALSE;
+
+if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
+ {
+ length = 3;
+ possessive = TRUE;
+ }
+
+cc = next_opcode(common, cc);
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ case OP_RECURSE:
+ if (!setsom_found)
+ {
+ length += 2;
+ setsom_found = TRUE;
+ }
+ cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ length += 3;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+/* Possessive quantifiers can use a special case. */
+if (SLJIT_UNLIKELY(possessive) && length == 3)
+ return -1;
+
+if (length > 0)
+ return length + 1;
+return -1;
+}
+
+static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
+{
+DEFINE_COMPILER;
+pcre_uchar *ccend = bracketend(cc);
+BOOL setsom_found = FALSE;
+int offset;
+
+/* >= 1 + shortest item size (2) */
+SLJIT_UNUSED_ARG(stacktop);
+SLJIT_ASSERT(stackpos >= stacktop + 2);
+
+stackpos = STACK(stackpos);
+if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
+ cc = next_opcode(common, cc);
+SLJIT_ASSERT(cc != NULL);
+while (cc < ccend)
+ switch(*cc)
+ {
+ case OP_SET_SOM:
+ case OP_RECURSE:
+ if (!setsom_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ setsom_found = TRUE;
+ }
+ cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_w);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
+ stackpos += (int)sizeof(sljit_w);
+
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
+SLJIT_ASSERT(stackpos == STACK(stacktop));
+}
+
+static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+{
+int localsize = 2;
+pcre_uchar *alternative;
+/* Calculate the sum of the local variables. */
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ localsize++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ localsize++;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ localsize += 2;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ localsize++;
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ }
+SLJIT_ASSERT(cc == ccend);
+return localsize;
+}
+
+static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
+ BOOL save, int stackptr, int stacktop)
+{
+DEFINE_COMPILER;
+int srcw[2];
+int count;
+BOOL tmp1next = TRUE;
+BOOL tmp1empty = TRUE;
+BOOL tmp2empty = TRUE;
+pcre_uchar *alternative;
+enum {
+ start,
+ loop,
+ end
+} status;
+
+status = save ? start : loop;
+stackptr = STACK(stackptr - 2);
+stacktop = STACK(stacktop - 1);
+
+if (!save)
+ {
+ stackptr += sizeof(sljit_w);
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ tmp1empty = FALSE;
+ }
+ if (stackptr < stacktop)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ tmp2empty = FALSE;
+ }
+ /* The tmp1next must be TRUE in either way. */
+ }
+
+while (status != end)
+ {
+ count = 0;
+ switch(status)
+ {
+ case start:
+ SLJIT_ASSERT(save);
+ count = 1;
+ srcw[0] = RECURSIVE_HEAD;
+ status = loop;
+ break;
+
+ case loop:
+ if (cc >= ccend)
+ {
+ status = end;
+ break;
+ }
+
+ switch(*cc)
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRAPOS:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCOND:
+ count = 1;
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ count = 1;
+ srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ count = 2;
+ srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ case OP_COND:
+ /* Might be a hidden SCOND. */
+ alternative = cc + GET(cc, 1);
+ if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
+ {
+ count = 1;
+ srcw[0] = PRIV_DATA(cc);
+ SLJIT_ASSERT(srcw[0] != 0);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ default:
+ cc = next_opcode(common, cc);
+ SLJIT_ASSERT(cc != NULL);
+ break;
+ }
+ break;
+
+ case end:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ while (count > 0)
+ {
+ count--;
+ if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
+ tmp1empty = FALSE;
+ tmp1next = FALSE;
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
+ tmp2empty = FALSE;
+ tmp1next = TRUE;
+ }
+ }
+ else
+ {
+ if (tmp1next)
+ {
+ SLJIT_ASSERT(!tmp1empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
+ tmp1empty = stackptr >= stacktop;
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ }
+ tmp1next = FALSE;
+ }
+ else
+ {
+ SLJIT_ASSERT(!tmp2empty);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
+ tmp2empty = stackptr >= stacktop;
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
+ stackptr += sizeof(sljit_w);
+ }
+ tmp1next = TRUE;
+ }
+ }
+ }
+ }
+
+if (save)
+ {
+ if (tmp1next)
+ {
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ }
+ else
+ {
+ if (!tmp2empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ if (!tmp1empty)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
+ stackptr += sizeof(sljit_w);
+ }
+ }
+ }
+SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
+}
+
+static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
+{
+return (value & (value - 1)) == 0;
+}
+
+static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
+{
+while (list)
+ {
+ /* sljit_set_label is clever enough to do nothing
+ if either the jump or the label is NULL */
+ sljit_set_label(list->jump, label);
+ list = list->next;
+ }
+}
+
+static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
+{
+jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
+if (list_item)
+ {
+ list_item->next = *list;
+ list_item->jump = jump;
+ *list = list_item;
+ }
+}
+
+static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
+{
+DEFINE_COMPILER;
+stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
+
+if (list_item)
+ {
+ list_item->type = type;
+ list_item->data = data;
+ list_item->start = start;
+ list_item->leave = LABEL();
+ list_item->next = common->stubs;
+ common->stubs = list_item;
+ }
+}
+
+static void flush_stubs(compiler_common *common)
+{
+DEFINE_COMPILER;
+stub_list* list_item = common->stubs;
+
+while (list_item)
+ {
+ JUMPHERE(list_item->start);
+ switch(list_item->type)
+ {
+ case stack_alloc:
+ add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
+ break;
+ }
+ JUMPTO(SLJIT_JUMP, list_item->leave);
+ list_item = list_item->next;
+ }
+common->stubs = NULL;
+}
+
+static SLJIT_INLINE void decrease_call_count(compiler_common *common)
+{
+DEFINE_COMPILER;
+
+OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
+add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
+}
+
+static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
+{
+/* May destroy all locals and registers except TMP2. */
+DEFINE_COMPILER;
+
+OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
+#ifdef DESTROY_REGISTERS
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
+OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
+#endif
+add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
+}
+
+static SLJIT_INLINE void free_stack(compiler_common *common, int size)
+{
+DEFINE_COMPILER;
+OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
+}
+
+static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+int i;
+/* At this point we can freely use all temporary registers. */
+/* TMP1 returns with begin - 1. */
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
+if (length < 8)
+ {
+ for (i = 0; i < length; i++)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
+ }
+else
+ {
+ OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, loop);
+ }
+}
+
+static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *earlyexit;
+
+/* At this point we can freely use all registers. */
+OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
+
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
+OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
+OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
+/* Unlikely, but possible */
+earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
+loop = LABEL();
+OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
+OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
+/* Copy the integer value to the output buffer */
+#ifdef COMPILE_PCRE16
+OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
+#endif
+OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
+JUMPTO(SLJIT_C_NOT_ZERO, loop);
+JUMPHERE(earlyexit);
+
+/* Calculate the return value, which is the maximum ovector value. */
+if (topbracket > 1)
+ {
+ OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
+
+ /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
+ OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
+ CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
+ }
+else
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
+}
+
+static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
+{
+/* Detects if the character has an othercase. */
+unsigned int c;
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c > 127)
+ {
+#ifdef SUPPORT_UCP
+ return c != UCD_OTHERCASE(c);
+#else
+ return FALSE;
+#endif
+ }
+#ifndef COMPILE_PCRE8
+ return common->fcc[c] != c;
+#endif
+ }
+else
+#endif
+ c = *cc;
+return MAX_255(c) ? common->fcc[c] != c : FALSE;
+}
+
+static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
+{
+/* Returns with the othercase. */
+#ifdef SUPPORT_UTF
+if (common->utf && c > 127)
+ {
+#ifdef SUPPORT_UCP
+ return UCD_OTHERCASE(c);
+#else
+ return c;
+#endif
+ }
+#endif
+return TABLE_GET(c, common->fcc, c);
+}
+
+static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
+{
+/* Detects if the character and its othercase has only 1 bit difference. */
+unsigned int c, oc, bit;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+int n;
+#endif
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ GETCHAR(c, cc);
+ if (c <= 127)
+ oc = common->fcc[c];
+ else
+ {
+#ifdef SUPPORT_UCP
+ oc = UCD_OTHERCASE(c);
+#else
+ oc = c;
+#endif
+ }
+ }
+else
+ {
+ c = *cc;
+ oc = TABLE_GET(c, common->fcc, c);
+ }
+#else
+c = *cc;
+oc = TABLE_GET(c, common->fcc, c);
+#endif
+
+SLJIT_ASSERT(c != oc);
+
+bit = c ^ oc;
+/* Optimized for English alphabet. */
+if (c <= 127 && bit == 0x20)
+ return (0 << 8) | 0x20;
+
+/* Since c != oc, they must have at least 1 bit difference. */
+if (!ispowerof2(bit))
+ return 0;
+
+#ifdef COMPILE_PCRE8
+
+#ifdef SUPPORT_UTF
+if (common->utf && c > 127)
+ {
+ n = GET_EXTRALEN(*cc);
+ while ((bit & 0x3f) == 0)
+ {
+ n--;
+ bit >>= 6;
+ }
+ return (n << 8) | bit;
+ }
+#endif /* SUPPORT_UTF */
+return (0 << 8) | bit;
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+#ifdef SUPPORT_UTF
+if (common->utf && c > 65535)
+ {
+ if (bit >= (1 << 10))
+ bit >>= 10;
+ else
+ return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
+ }
+#endif /* SUPPORT_UTF */
+return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+}
+
+static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+}
+
+static void read_char(compiler_common *common)
+{
+/* Reads the character into TMP1, updates STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#ifdef SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+#else
+#ifdef COMPILE_PCRE16
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+#endif
+#endif /* COMPILE_PCRE8 */
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+ }
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void peek_char(compiler_common *common)
+{
+/* Reads the character into TMP1, keeps STR_PTR.
+Does not check STR_END. TMP2 Destroyed. */
+DEFINE_COMPILER;
+#ifdef SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+#else
+#ifdef COMPILE_PCRE16
+ jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+#endif
+#endif /* COMPILE_PCRE8 */
+ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ JUMPHERE(jump);
+ }
+#endif
+}
+
+static void read_char8_type(compiler_common *common)
+{
+/* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+struct sljit_jump *jump;
+#endif
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE8
+ /* This can be an extra read in some situations, but hopefully
+ it is needed in most cases. */
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
+ add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
+ JUMPHERE(jump);
+#else
+#ifdef COMPILE_PCRE16
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+ JUMPHERE(jump);
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+#endif
+#endif /* COMPILE_PCRE8 */
+ return;
+ }
+#endif
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE16
+/* The ctypes array contains only 256 values. */
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+#ifdef COMPILE_PCRE16
+JUMPHERE(jump);
+#endif
+}
+
+static void skip_char_back(compiler_common *common)
+{
+/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
+DEFINE_COMPILER;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+struct sljit_label *label;
+
+if (common->utf)
+ {
+ label = LABEL();
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
+ CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
+ return;
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ /* Skip low surrogate if necessary. */
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ return;
+ }
+#endif
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+}
+
+static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
+{
+/* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
+DEFINE_COMPILER;
+
+if (nltype == NLTYPE_ANY)
+ {
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ }
+else if (nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ }
+else
+ {
+ SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
+ add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+}
+
+#ifdef SUPPORT_UTF
+
+#ifdef COMPILE_PCRE8
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character. TMP1 contains the first byte
+of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+/* Searching for the first zero. */
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Three byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+/* Four byte sequence. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void do_utfreadtype8(compiler_common *common)
+{
+/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
+of the character (>= 0xc0). Return value in TMP1. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_jump *compare;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
+jump = JUMP(SLJIT_C_NOT_ZERO);
+/* Two byte sequence. */
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
+OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
+compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(compare);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+JUMPHERE(jump);
+
+/* We only have types for characters less than 256. */
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#else /* COMPILE_PCRE8 */
+
+#ifdef COMPILE_PCRE16
+static void do_utfreadchar(compiler_common *common)
+{
+/* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
+of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
+/* Do nothing, only return. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+/* Combine two 16 bit characters. */
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
+OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+#endif /* COMPILE_PCRE16 */
+
+#endif /* COMPILE_PCRE8 */
+
+#endif /* SUPPORT_UTF */
+
+#ifdef SUPPORT_UCP
+
+/* UCD_BLOCK_SIZE must be 128 (see the assert below). */
+#define UCD_BLOCK_MASK 127
+#define UCD_BLOCK_SHIFT 7
+
+static void do_getucd(compiler_common *common)
+{
+/* Search the UCD record for the character comes in TMP1.
+Returns chartype in TMP1 and UCD offset in TMP2. */
+DEFINE_COMPILER;
+
+SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
+OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
+OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+#endif
+
+static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *mainloop;
+struct sljit_label *newlinelabel = NULL;
+struct sljit_jump *start;
+struct sljit_jump *end = NULL;
+struct sljit_jump *nl = NULL;
+#ifdef SUPPORT_UTF
+struct sljit_jump *singlechar;
+#endif
+jump_list *newline = NULL;
+BOOL newlinecheck = FALSE;
+BOOL readuchar = FALSE;
+
+if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
+ common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
+ newlinecheck = TRUE;
+
+if (firstline)
+ {
+ /* Search for the end of the first line. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ mainloop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+ else
+ {
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ mainloop = LABEL();
+ /* Continual stores does not cause data dependency. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
+ read_char(common);
+ check_newlinechar(common, common->nltype, &newline, TRUE);
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
+ set_jumps(newline, LABEL());
+ }
+
+ JUMPHERE(end);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+ }
+
+start = JUMP(SLJIT_JUMP);
+
+if (newlinecheck)
+ {
+ newlinelabel = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ nl = JUMP(SLJIT_JUMP);
+ }
+
+mainloop = LABEL();
+
+/* Increasing the STR_PTR here requires one less jump in the most common case. */
+#ifdef SUPPORT_UTF
+if (common->utf) readuchar = TRUE;
+#endif
+if (newlinecheck) readuchar = TRUE;
+
+if (readuchar)
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+if (newlinecheck)
+ CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(singlechar);
+ }
+#endif
+JUMPHERE(start);
+
+if (newlinecheck)
+ {
+ JUMPHERE(end);
+ JUMPHERE(nl);
+ }
+
+return mainloop;
+}
+
+static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *leave;
+struct sljit_jump *found;
+pcre_uchar oc, bit;
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ }
+
+start = LABEL();
+leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+
+oc = first_char;
+if (caseless)
+ {
+ oc = TABLE_GET(first_char, common->fcc, first_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (first_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(first_char);
+#endif
+ }
+if (first_char == oc)
+ found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
+else
+ {
+ bit = first_char ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
+ }
+ else
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ found = JUMP(SLJIT_C_NOT_ZERO);
+ }
+ }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+JUMPTO(SLJIT_JUMP, start);
+JUMPHERE(found);
+JUMPHERE(leave);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *lastchar;
+struct sljit_jump *firstchar;
+struct sljit_jump *leave;
+struct sljit_jump *foundcr = NULL;
+struct sljit_jump *notfoundnl;
+jump_list *newline = NULL;
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ }
+
+if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+ loop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+
+ JUMPHERE(leave);
+ JUMPHERE(firstchar);
+ JUMPHERE(lastchar);
+
+ if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ return;
+ }
+
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+skip_char_back(common);
+
+loop = LABEL();
+read_char(common);
+lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+check_newlinechar(common, common->nltype, &newline, FALSE);
+set_jumps(newline, loop);
+
+if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ {
+ leave = JUMP(SLJIT_JUMP);
+ JUMPHERE(foundcr);
+ notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+#ifdef COMPILE_PCRE16
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(notfoundnl);
+ JUMPHERE(leave);
+ }
+JUMPHERE(lastchar);
+JUMPHERE(firstchar);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+struct sljit_jump *leave;
+struct sljit_jump *found;
+#ifndef COMPILE_PCRE8
+struct sljit_jump *jump;
+#endif
+
+if (firstline)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ }
+
+start = LABEL();
+leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+#ifdef SUPPORT_UTF
+if (common->utf)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#endif
+#ifndef COMPILE_PCRE8
+jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
+JUMPHERE(jump);
+#endif
+OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
+OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+found = JUMP(SLJIT_C_NOT_ZERO);
+
+#ifdef SUPPORT_UTF
+if (common->utf)
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#endif
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+#if defined SUPPORT_UTF && defined COMPILE_PCRE16
+if (common->utf)
+ {
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ }
+#endif
+JUMPTO(SLJIT_JUMP, start);
+JUMPHERE(found);
+JUMPHERE(leave);
+
+if (firstline)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+}
+
+static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+struct sljit_jump *toolong;
+struct sljit_jump *alreadyfound;
+struct sljit_jump *found;
+struct sljit_jump *foundoc = NULL;
+struct sljit_jump *notfound;
+pcre_uchar oc, bit;
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);
+OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
+toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
+alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
+
+if (has_firstchar)
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+else
+ OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
+
+loop = LABEL();
+notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
+
+OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+oc = req_char;
+if (caseless)
+ {
+ oc = TABLE_GET(req_char, common->fcc, req_char);
+#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
+ if (req_char > 127 && common->utf)
+ oc = UCD_OTHERCASE(req_char);
+#endif
+ }
+if (req_char == oc)
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+else
+ {
+ bit = req_char ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
+ }
+ else
+ {
+ found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
+ foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
+ }
+ }
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_JUMP, loop);
+
+JUMPHERE(found);
+if (foundoc)
+ JUMPHERE(foundoc);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);
+JUMPHERE(alreadyfound);
+JUMPHERE(toolong);
+return notfound;
+}
+
+static void do_revertframes(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *mainloop;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
+
+/* Drop frames until we reach STACK_TOP. */
+mainloop = LABEL();
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
+jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+/* End of dropping frames. */
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
+/* Set string begin. */
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
+JUMPTO(SLJIT_JUMP, mainloop);
+
+JUMPHERE(jump);
+/* Unknown command. */
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
+JUMPTO(SLJIT_JUMP, mainloop);
+}
+
+static void check_wordboundary(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *beginend;
+#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
+struct sljit_jump *jump;
+#endif
+
+SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
+
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
+/* Get type of the previous char, and put it to LOCALS1. */
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
+beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
+skip_char_back(common);
+read_char(common);
+
+/* Testing char type. */
+#ifdef SUPPORT_UCP
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ JUMPHERE(jump);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
+ }
+else
+#endif
+ {
+#ifndef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ /* Here LOCALS1 has already been zeroed. */
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif /* COMPILE_PCRE8 */
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* COMPILE_PCRE8 */
+ }
+JUMPHERE(beginend);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+peek_char(common);
+
+/* Testing char type. This is a code duplication. */
+#ifdef SUPPORT_UCP
+if (common->use_ucp)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ JUMPHERE(jump);
+ }
+else
+#endif
+ {
+#ifndef COMPILE_PCRE8
+ /* TMP2 may be destroyed by peek_char. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = NULL;
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
+ OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
+ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (jump != NULL)
+ JUMPHERE(jump);
+#endif /* COMPILE_PCRE8 */
+ }
+JUMPHERE(beginend);
+
+OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+}
+
+static void check_anynewline(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_hspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
+COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+static void check_vspace(compiler_common *common)
+{
+/* Check whether TMP1 contains a newline character. TMP2 destroyed. */
+DEFINE_COMPILER;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
+OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+#ifdef COMPILE_PCRE8
+if (common->utf)
+ {
+#endif
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+#ifdef COMPILE_PCRE8
+ }
+#endif
+#endif /* SUPPORT_UTF || COMPILE_PCRE16 */
+COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define CHAR1 STR_END
+#define CHAR2 STACK_TOP
+
+static void do_casefulcmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#define LCC_TABLE STACK_LIMIT
+
+static void do_caselesscmp(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+struct sljit_label *label;
+
+sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
+OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+label = LABEL();
+OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
+OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+#ifndef COMPILE_PCRE8
+jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
+#ifndef COMPILE_PCRE8
+JUMPHERE(jump);
+jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
+#endif
+OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
+#ifndef COMPILE_PCRE8
+JUMPHERE(jump);
+#endif
+jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
+OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
+JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+JUMPHERE(jump);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
+OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
+}
+
+#undef LCC_TABLE
+#undef CHAR1
+#undef CHAR2
+
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
+
+static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
+{
+/* This function would be ineffective to do in JIT level. */
+int c1, c2;
+const pcre_uchar *src2 = args->ptr;
+const pcre_uchar *end2 = args->end;
+
+while (src1 < end1)
+ {
+ if (src2 >= end2)
+ return 0;
+ GETCHARINC(c1, src1);
+ GETCHARINC(c2, src2);
+ if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;
+ }
+return src2;
+}
+
+#endif /* SUPPORT_UTF && SUPPORT_UCP */
+
+static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
+ compare_context* context, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+unsigned int othercasebit = 0;
+pcre_uchar *othercasechar = NULL;
+#ifdef SUPPORT_UTF
+int utflength;
+#endif
+
+if (caseless && char_has_othercase(common, cc))
+ {
+ othercasebit = char_get_othercase_bit(common, cc);
+ SLJIT_ASSERT(othercasebit);
+ /* Extracting bit difference info. */
+#ifdef COMPILE_PCRE8
+ othercasechar = cc + (othercasebit >> 8);
+ othercasebit &= 0xff;
+#else
+#ifdef COMPILE_PCRE16
+ othercasechar = cc + (othercasebit >> 9);
+ if ((othercasebit & 0x100) != 0)
+ othercasebit = (othercasebit & 0xff) << 8;
+ else
+ othercasebit &= 0xff;
+#endif
+#endif
+ }
+
+if (context->sourcereg == -1)
+ {
+#ifdef COMPILE_PCRE8
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+#ifdef COMPILE_PCRE16
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else
+#endif
+ OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+#endif /* COMPILE_PCRE8 */
+ context->sourcereg = TMP2;
+ }
+
+#ifdef SUPPORT_UTF
+utflength = 1;
+if (common->utf && HAS_EXTRALEN(*cc))
+ utflength += GET_EXTRALEN(*cc);
+
+do
+ {
+#endif
+
+ context->length -= IN_UCHARS(1);
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+
+ /* Unaligned read is supported. */
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ context->c.asuchars[context->ucharptr] = *cc | othercasebit;
+ context->oc.asuchars[context->ucharptr] = othercasebit;
+ }
+ else
+ {
+ context->c.asuchars[context->ucharptr] = *cc;
+ context->oc.asuchars[context->ucharptr] = 0;
+ }
+ context->ucharptr++;
+
+#ifdef COMPILE_PCRE8
+ if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
+#else
+ if (context->ucharptr >= 2 || context->length == 0)
+#endif
+ {
+ if (context->length >= 4)
+ OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#ifdef COMPILE_PCRE8
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+ else if (context->length >= 1)
+ OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+ else if (context->length >= 2)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ switch(context->ucharptr)
+ {
+ case 4 / sizeof(pcre_uchar):
+ if (context->oc.asint != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
+ break;
+
+ case 2 / sizeof(pcre_uchar):
+ if (context->oc.asushort != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
+ break;
+
+#ifdef COMPILE_PCRE8
+ case 1:
+ if (context->oc.asbyte != 0)
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
+ break;
+#endif
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ context->ucharptr = 0;
+ }
+
+#else
+
+ /* Unaligned read is unsupported. */
+#ifdef COMPILE_PCRE8
+ if (context->length > 0)
+ OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#else
+ if (context->length > 0)
+ OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#endif
+ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
+
+ if (othercasebit != 0 && othercasechar == cc)
+ {
+ OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
+ }
+ else
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
+
+#endif
+
+ cc++;
+#ifdef SUPPORT_UTF
+ utflength--;
+ }
+while (utflength > 0);
+#endif
+
+return cc;
+}
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+
+#define SET_TYPE_OFFSET(value) \
+ if ((value) != typeoffset) \
+ { \
+ if ((value) > typeoffset) \
+ OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
+ else \
+ OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
+ } \
+ typeoffset = (value);
+
+#define SET_CHAR_OFFSET(value) \
+ if ((value) != charoffset) \
+ { \
+ if ((value) > charoffset) \
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
+ else \
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
+ } \
+ charoffset = (value);
+
+static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+jump_list *found = NULL;
+jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;
+unsigned int c;
+int compares;
+struct sljit_jump *jump = NULL;
+pcre_uchar *ccbegin;
+#ifdef SUPPORT_UCP
+BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
+BOOL charsaved = FALSE;
+int typereg = TMP1, scriptreg = TMP1;
+unsigned int typeoffset;
+#endif
+int invertcmp, numberofcmps;
+unsigned int charoffset;
+
+/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
+check_input_end(common, fallbacks);
+read_char(common);
+
+if ((*cc++ & XCL_MAP) != 0)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+#ifndef COMPILE_PCRE8
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#elif defined SUPPORT_UTF
+ if (common->utf)
+ jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+#endif
+
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
+
+#ifndef COMPILE_PCRE8
+ JUMPHERE(jump);
+#elif defined SUPPORT_UTF
+ if (common->utf)
+ JUMPHERE(jump);
+#endif
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+#ifdef SUPPORT_UCP
+ charsaved = TRUE;
+#endif
+ cc += 32 / sizeof(pcre_uchar);
+ }
+
+/* Scanning the necessary info. */
+ccbegin = cc;
+compares = 0;
+while (*cc != XCL_END)
+ {
+ compares++;
+ if (*cc == XCL_SINGLE)
+ {
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+#ifdef SUPPORT_UCP
+ needschar = TRUE;
+#endif
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ cc++;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+#ifdef SUPPORT_UCP
+ needschar = TRUE;
+#endif
+ }
+#ifdef SUPPORT_UCP
+ else
+ {
+ SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ break;
+
+ case PT_LAMP:
+ case PT_GC:
+ case PT_PC:
+ case PT_ALNUM:
+ needstype = TRUE;
+ break;
+
+ case PT_SC:
+ needsscript = TRUE;
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ case PT_WORD:
+ needstype = TRUE;
+ needschar = TRUE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ cc += 2;
+ }
+#endif
+ }
+
+#ifdef SUPPORT_UCP
+/* Simple register allocation. TMP1 is preferred if possible. */
+if (needstype || needsscript)
+ {
+ if (needschar && !charsaved)
+ OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ if (needschar)
+ {
+ if (needstype)
+ {
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
+ typereg = RETURN_ADDR;
+ }
+
+ if (needsscript)
+ scriptreg = TMP3;
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ }
+ else if (needstype && needsscript)
+ scriptreg = TMP3;
+ /* In all other cases only one of them was specified, and that can goes to TMP1. */
+
+ if (needsscript)
+ {
+ if (scriptreg == TMP1)
+ {
+ OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
+ }
+ else
+ {
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
+ OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
+ }
+ }
+ }
+#endif
+
+/* Generating code. */
+cc = ccbegin;
+charoffset = 0;
+numberofcmps = 0;
+#ifdef SUPPORT_UCP
+typeoffset = 0;
+#endif
+
+while (*cc != XCL_END)
+ {
+ compares--;
+ invertcmp = (compares == 0 && list != fallbacks);
+ jump = NULL;
+
+ if (*cc == XCL_SINGLE)
+ {
+ cc ++;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ numberofcmps = 0;
+ }
+ }
+ else if (*cc == XCL_RANGE)
+ {
+ cc ++;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+ SET_CHAR_OFFSET(c);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHARINC(c, cc);
+ }
+ else
+#endif
+ c = *cc++;
+ if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ numberofcmps++;
+ }
+ else if (numberofcmps > 0)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ numberofcmps = 0;
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
+ numberofcmps = 0;
+ }
+ }
+#ifdef SUPPORT_UCP
+ else
+ {
+ if (*cc == XCL_NOTPROP)
+ invertcmp ^= 0x1;
+ cc++;
+ switch(*cc)
+ {
+ case PT_ANY:
+ if (list != fallbacks)
+ {
+ if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
+ continue;
+ }
+ else if (cc[-1] == XCL_NOTPROP)
+ continue;
+ jump = JUMP(SLJIT_JUMP);
+ break;
+
+ case PT_LAMP:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
+ COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_GC:
+ c = PRIV(ucp_typerange)[(int)cc[1] * 2];
+ SET_TYPE_OFFSET(c);
+ jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
+ break;
+
+ case PT_PC:
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
+ break;
+
+ case PT_SC:
+ jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
+ break;
+
+ case PT_SPACE:
+ case PT_PXSPACE:
+ if (*cc == PT_SPACE)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
+ }
+ SET_CHAR_OFFSET(9);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ if (*cc == PT_SPACE)
+ JUMPHERE(jump);
+
+ SET_TYPE_OFFSET(ucp_Zl);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_WORD:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ /* ... fall through */
+
+ case PT_ALNUM:
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
+ COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ SET_TYPE_OFFSET(ucp_Nd);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+ }
+ cc += 2;
+ }
+#endif
+
+ if (jump != NULL)
+ add_jump(compiler, compares > 0 ? list : fallbacks, jump);
+ }
+
+if (found != NULL)
+ set_jumps(found, LABEL());
+}
+
+#undef SET_TYPE_OFFSET
+#undef SET_CHAR_OFFSET
+
+#endif
+
+static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+int length;
+unsigned int c, oc, bit;
+compare_context context;
+struct sljit_jump *jump[4];
+#ifdef SUPPORT_UTF
+struct sljit_label *label;
+#ifdef SUPPORT_UCP
+pcre_uchar propdata[5];
+#endif
+#endif
+
+switch(type)
+ {
+ case OP_SOD:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
+ return cc;
+
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ check_input_end(common, fallbacks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
+ add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ check_input_end(common, fallbacks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
+ add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ check_input_end(common, fallbacks);
+ read_char8_type(common);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
+ add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
+ return cc;
+
+ case OP_ANY:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[0]);
+ }
+ else
+ check_newlinechar(common, common->nltype, fallbacks, TRUE);
+ return cc;
+
+ case OP_ALLANY:
+ check_input_end(common, fallbacks);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+#ifdef COMPILE_PCRE8
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#else /* COMPILE_PCRE8 */
+#ifdef COMPILE_PCRE16
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
+ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+#endif /* COMPILE_PCRE16 */
+#endif /* COMPILE_PCRE8 */
+ JUMPHERE(jump[0]);
+ return cc;
+ }
+#endif
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+ case OP_ANYBYTE:
+ check_input_end(common, fallbacks);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ return cc;
+
+#ifdef SUPPORT_UTF
+#ifdef SUPPORT_UCP
+ case OP_NOTPROP:
+ case OP_PROP:
+ propdata[0] = 0;
+ propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
+ propdata[2] = cc[0];
+ propdata[3] = cc[1];
+ propdata[4] = XCL_END;
+ compile_xclass_hotpath(common, propdata, fallbacks);
+ return cc + 2;
+#endif
+#endif
+
+ case OP_ANYNL:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[3] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[0]);
+ check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
+ JUMPHERE(jump[1]);
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ return cc;
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
+ return cc;
+
+#ifdef SUPPORT_UCP
+ case OP_EXTUNI:
+ check_input_end(common, fallbacks);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
+
+ label = LABEL();
+ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ JUMPHERE(jump[0]);
+ return cc;
+#endif
+
+ case OP_EODN:
+ jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else if (common->nltype == NLTYPE_FIXED)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
+ }
+ else
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
+ jump[2] = JUMP(SLJIT_C_GREATER);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
+ /* Equal. */
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
+
+ JUMPHERE(jump[1]);
+ if (common->nltype == NLTYPE_ANYCRLF)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
+ read_char(common);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+ add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+ }
+ JUMPHERE(jump[2]);
+ JUMPHERE(jump[3]);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_EOD:
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
+ return cc;
+
+ case OP_CIRC:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ return cc;
+
+ case OP_CIRCM:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ skip_char_back(common);
+ read_char(common);
+ check_newlinechar(common, common->nltype, fallbacks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_DOLL:
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+
+ if (!common->endonly)
+ compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
+ else
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
+ return cc;
+
+ case OP_DOLLM:
+ jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ jump[0] = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump[1]);
+
+ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
+ {
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
+ }
+ else
+ {
+ peek_char(common);
+ check_newlinechar(common, common->nltype, fallbacks, FALSE);
+ }
+ JUMPHERE(jump[0]);
+ return cc;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ length = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
+#endif
+ if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
+ {
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.length = IN_UCHARS(length);
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
+ }
+ check_input_end(common, fallbacks);
+ read_char(common);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ GETCHAR(c, cc);
+ }
+ else
+#endif
+ c = *cc;
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
+ return cc + length;
+
+ case OP_NOT:
+ case OP_NOTI:
+ check_input_end(common, fallbacks);
+ length = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+#ifdef COMPILE_PCRE8
+ c = *cc;
+ if (c < 128)
+ {
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
+ OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
+ }
+ /* Skip the variable-length character. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+ JUMPHERE(jump[0]);
+ return cc + 1;
+ }
+ else
+#endif /* COMPILE_PCRE8 */
+ {
+ GETCHARLEN(c, cc, length);
+ read_char(common);
+ }
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ read_char(common);
+ c = *cc;
+ }
+
+ if (type == OP_NOT || !char_has_othercase(common, cc))
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ else
+ {
+ oc = char_othercase(common, c);
+ bit = c ^ oc;
+ if (ispowerof2(bit))
+ {
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
+ }
+ else
+ {
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
+ }
+ }
+ return cc + 1;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ check_input_end(common, fallbacks);
+ read_char(common);
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ jump[0] = NULL;
+#ifdef COMPILE_PCRE8
+ /* This check only affects 8 bit mode. In other modes, we
+ always need to compare the value with 255. */
+ if (common->utf)
+#endif /* COMPILE_PCRE8 */
+ {
+ jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
+ if (type == OP_CLASS)
+ {
+ add_jump(compiler, fallbacks, jump[0]);
+ jump[0] = NULL;
+ }
+ }
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
+ OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
+ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
+ OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
+ OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
+ add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ if (jump[0] != NULL)
+ JUMPHERE(jump[0]);
+#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
+ return cc + 32 / sizeof(pcre_uchar);
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
+ return cc + GET(cc, 0) - 1;
+#endif
+
+ case OP_REVERSE:
+ length = GET(cc, 0);
+ SLJIT_ASSERT(length > 0);
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
+ label = LABEL();
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
+ skip_char_back(common);
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, label);
+ return cc + LINK_SIZE;
+ }
+#endif
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
+ return cc + LINK_SIZE;
+ }
+SLJIT_ASSERT_STOP();
+return cc;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)
+{
+/* This function consumes at least one input character. */
+/* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
+DEFINE_COMPILER;
+pcre_uchar *ccbegin = cc;
+compare_context context;
+int size;
+
+context.length = 0;
+do
+ {
+ if (cc >= ccend)
+ break;
+
+ if (*cc == OP_CHAR)
+ {
+ size = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+#endif
+ }
+ else if (*cc == OP_CHARI)
+ {
+ size = 1;
+#ifdef SUPPORT_UTF
+ if (common->utf)
+ {
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ else if (HAS_EXTRALEN(cc[1]))
+ size += GET_EXTRALEN(cc[1]);
+ }
+ else
+#endif
+ if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
+ size = 0;
+ }
+ else
+ size = 0;
+
+ cc += 1 + size;
+ context.length += IN_UCHARS(size);
+ }
+while (size > 0 && context.length <= 128);
+
+cc = ccbegin;
+if (context.length > 0)
+ {
+ /* We have a fixed-length byte sequence. */
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+
+ context.sourcereg = -1;
+#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+ context.ucharptr = 0;
+#endif
+ do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);
+ return cc;
+ }
+
+/* A non-fixed length character will be checked if length == 0. */
+return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
+}
+
+static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1) << 1;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+if (!common->jscript_compat)
+ {
+ if (fallbacks == NULL)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
+ return JUMP(SLJIT_C_NOT_ZERO);
+ }
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ }
+return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+}
+
+/* Forward definitions. */
+static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
+static void compile_fallbackpath(compiler_common *, struct fallback_common *);
+
+#define PUSH_FALLBACK(size, ccstart, error) \
+ do \
+ { \
+ fallback = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return error; \
+ memset(fallback, 0, size); \
+ fallback->prev = parent->top; \
+ fallback->cc = (ccstart); \
+ parent->top = fallback; \
+ } \
+ while (0)
+
+#define PUSH_FALLBACK_NOVALUE(size, ccstart) \
+ do \
+ { \
+ fallback = sljit_alloc_memory(compiler, (size)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ memset(fallback, 0, size); \
+ fallback->prev = parent->top; \
+ fallback->cc = (ccstart); \
+ parent->top = fallback; \
+ } \
+ while (0)
+
+#define FALLBACK_AS(type) ((type*)fallback)
+
+static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1) << 1;
+struct sljit_jump *jump = NULL;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+if (withchecks && !common->jscript_compat)
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
+if (common->utf && *cc == OP_REFI)
+ {
+ SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ if (withchecks)
+ jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
+
+ /* Needed to save important temporary registers. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+ }
+else
+#endif /* SUPPORT_UTF && SUPPORT_UCP */
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
+ if (withchecks)
+ jump = JUMP(SLJIT_C_ZERO);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
+ add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
+ add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+ }
+
+if (jump != NULL)
+ {
+ if (emptyfail)
+ add_jump(compiler, fallbacks, jump);
+ else
+ JUMPHERE(jump);
+ }
+return cc + 1 + IMM2_SIZE;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar type;
+struct sljit_label *label;
+struct sljit_jump *zerolength;
+struct sljit_jump *jump = NULL;
+pcre_uchar *ccbegin = cc;
+int min = 0, max = 0;
+BOOL minimize;
+
+PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
+
+type = cc[1 + IMM2_SIZE];
+minimize = (type & 0x1) != 0;
+switch(type)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ min = 0;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ max = 0;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ min = 0;
+ max = 1;
+ cc += 1 + IMM2_SIZE + 1;
+ break;
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1 + IMM2_SIZE + 1);
+ max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
+ cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+if (!minimize)
+ {
+ if (min == 0)
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ /* Temporary release of STR_PTR. */
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ zerolength = compile_ref_checks(common, ccbegin, NULL);
+ /* Restore if not zero length. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
+ }
+
+ if (min > 1 || max > 1)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);
+
+ if (min > 1 || max > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ if (min > 1)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
+ if (max > 1)
+ {
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ JUMPHERE(jump);
+ }
+ }
+
+ if (max == 0)
+ {
+ /* Includes min > 1 case as well. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+
+ JUMPHERE(zerolength);
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+
+ decrease_call_count(common);
+ return cc;
+ }
+
+allocate_stack(common, 2);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+if (type != OP_CRMINSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+
+if (min == 0)
+ {
+ zerolength = compile_ref_checks(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ jump = JUMP(SLJIT_JUMP);
+ }
+else
+ zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
+
+FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+if (max > 0)
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
+
+compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+if (min > 1)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);
+ }
+else if (max > 0)
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+
+if (jump != NULL)
+ JUMPHERE(jump);
+JUMPHERE(zerolength);
+
+decrease_call_count(common);
+return cc;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+recurse_entry *entry = common->entries;
+recurse_entry *prev = NULL;
+int start = GET(cc, 1);
+
+PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);
+while (entry != NULL)
+ {
+ if (entry->start == start)
+ break;
+ prev = entry;
+ entry = entry->next;
+ }
+
+if (entry == NULL)
+ {
+ entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ entry->next = NULL;
+ entry->entry = NULL;
+ entry->calls = NULL;
+ entry->start = start;
+
+ if (prev != NULL)
+ prev->next = entry;
+ else
+ common->entries = entry;
+ }
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+allocate_stack(common, 1);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+
+if (entry->entry == NULL)
+ add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
+else
+ JUMPTO(SLJIT_FAST_CALL, entry->entry);
+/* Leave if the match is failed. */
+add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
+return cc + 1 + LINK_SIZE;
+}
+
+static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)
+{
+DEFINE_COMPILER;
+int framesize;
+int localptr;
+fallback_common altfallback;
+pcre_uchar *ccbegin;
+pcre_uchar opcode;
+pcre_uchar bra = OP_BRA;
+jump_list *tmp = NULL;
+jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
+jump_list **found;
+/* Saving previous accept variables. */
+struct sljit_label *save_acceptlabel = common->acceptlabel;
+struct sljit_jump *jump;
+struct sljit_jump *brajump = NULL;
+jump_list *save_accept = common->accept;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ SLJIT_ASSERT(!conditional);
+ bra = *cc;
+ cc++;
+ }
+localptr = PRIV_DATA(cc);
+SLJIT_ASSERT(localptr != 0);
+framesize = get_framesize(common, cc, FALSE);
+fallback->framesize = framesize;
+fallback->localptr = localptr;
+opcode = *cc;
+SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
+found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
+ccbegin = cc;
+cc += GET(cc, 1);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a braminzero fallback path. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+else
+ {
+ allocate_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, framesize + 1, 2, FALSE);
+ }
+
+memset(&altfallback, 0, sizeof(fallback_common));
+while (1)
+ {
+ common->acceptlabel = NULL;
+ common->accept = NULL;
+ altfallback.top = NULL;
+ altfallback.topfallbacks = NULL;
+
+ if (*ccbegin == OP_ALT)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ altfallback.cc = ccbegin;
+ compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->acceptlabel = save_acceptlabel;
+ common->accept = save_accept;
+ return NULL;
+ }
+ common->acceptlabel = LABEL();
+ if (common->accept != NULL)
+ set_jumps(common->accept, common->acceptlabel);
+
+ /* Reset stack. */
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ else {
+ if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ }
+
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ if (conditional)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (bra == OP_BRAZERO)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else if (framesize >= 0)
+ {
+ /* For OP_BRA and OP_BRAMINZERO. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ }
+ }
+ add_jump(compiler, found, JUMP(SLJIT_JUMP));
+
+ compile_fallbackpath(common, altfallback.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ common->acceptlabel = save_acceptlabel;
+ common->accept = save_accept;
+ return NULL;
+ }
+ set_jumps(altfallback.topfallbacks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ ccbegin = cc;
+ cc += GET(cc, 1);
+ }
+/* None of them matched. */
+
+if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
+ {
+ /* Assert is failed. */
+ if (conditional || bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ if (framesize < 0)
+ {
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ else
+ free_stack(common, 1);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* The topmost item should be 0. */
+ if (bra == OP_BRAZERO)
+ {
+ free_stack(common, framesize + 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ jump = JUMP(SLJIT_JUMP);
+ if (bra != OP_BRAZERO)
+ add_jump(compiler, target, jump);
+
+ /* Assert is successful. */
+ set_jumps(tmp, LABEL());
+ if (framesize < 0)
+ {
+ /* We know that STR_PTR was stored on the top of the stack. */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ /* Keep the STR_PTR on the top of the stack. */
+ if (bra == OP_BRAZERO)
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ else if (bra == OP_BRAMINZERO)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ else
+ {
+ if (bra == OP_BRA)
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ else
+ {
+ /* We don't need to keep the STR_PTR, only the previous localptr. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
+ }
+ }
+
+ if (bra == OP_BRAZERO)
+ {
+ fallback->hotpath = LABEL();
+ sljit_set_label(jump, fallback->hotpath);
+ }
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, fallback->hotpath);
+ JUMPHERE(brajump);
+ if (framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
+ }
+ set_jumps(fallback->common.topfallbacks, LABEL());
+ }
+ }
+else
+ {
+ /* AssertNot is successful. */
+ if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra != OP_BRA)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ else
+ free_stack(common, 1);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* The topmost item should be 0. */
+ if (bra != OP_BRA)
+ {
+ free_stack(common, framesize + 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ free_stack(common, framesize + 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+
+ if (bra == OP_BRAZERO)
+ fallback->hotpath = LABEL();
+ else if (bra == OP_BRAMINZERO)
+ {
+ JUMPTO(SLJIT_JUMP, fallback->hotpath);
+ JUMPHERE(brajump);
+ }
+
+ if (bra != OP_BRA)
+ {
+ SLJIT_ASSERT(found == &fallback->common.topfallbacks);
+ set_jumps(fallback->common.topfallbacks, LABEL());
+ fallback->common.topfallbacks = NULL;
+ }
+ }
+
+common->acceptlabel = save_acceptlabel;
+common->accept = save_accept;
+return cc + 1 + LINK_SIZE;
+}
+
+static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
+{
+int condition = FALSE;
+pcre_uchar *slotA = name_table;
+pcre_uchar *slotB;
+sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
+sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
+sljit_w no_capture;
+int i;
+
+locals += OVECTOR_START / sizeof(sljit_w);
+no_capture = locals[1];
+
+for (i = 0; i < name_count; i++)
+ {
+ if (GET2(slotA, 0) == refno) break;
+ slotA += name_entry_size;
+ }
+
+if (i < name_count)
+ {
+ /* Found a name for the number - there can be only one; duplicate names
+ for different numbers are allowed, but not vice versa. First scan down
+ for duplicates. */
+
+ slotB = slotA;
+ while (slotB > name_table)
+ {
+ slotB -= name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = locals[GET2(slotB, 0) << 1] != no_capture;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < name_count; i++)
+ {
+ slotB += name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = locals[GET2(slotB, 0) << 1] != no_capture;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+return condition;
+}
+
+static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
+{
+int condition = FALSE;
+pcre_uchar *slotA = name_table;
+pcre_uchar *slotB;
+sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
+sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
+sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
+int i;
+
+for (i = 0; i < name_count; i++)
+ {
+ if (GET2(slotA, 0) == recno) break;
+ slotA += name_entry_size;
+ }
+
+if (i < name_count)
+ {
+ /* Found a name for the number - there can be only one; duplicate
+ names for different numbers are allowed, but not vice versa. First
+ scan down for duplicates. */
+
+ slotB = slotA;
+ while (slotB > name_table)
+ {
+ slotB -= name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+
+ /* Scan up for duplicates */
+ if (!condition)
+ {
+ slotB = slotA;
+ for (i++; i < name_count; i++)
+ {
+ slotB += name_entry_size;
+ if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
+ {
+ condition = GET2(slotB, 0) == group_num;
+ if (condition) break;
+ }
+ else break;
+ }
+ }
+ }
+return condition;
+}
+
+/*
+ Handling bracketed expressions is probably the most complex part.
+
+ Stack layout naming characters:
+ S - Push the current STR_PTR
+ 0 - Push a 0 (NULL)
+ A - Push the current STR_PTR. Needed for restoring the STR_PTR
+ before the next alternative. Not pushed if there are no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+ C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
+ L - Push the previous local (pointed by localptr) to the stack
+ () - opional values stored on the stack
+ ()* - optonal, can be stored multiple times
+
+ The following list shows the regular expression templates, their PCRE byte codes
+ and stack layout supported by pcre-sljit.
+
+ (?:) OP_BRA | OP_KET A M
+ () OP_CBRA | OP_KET C M
+ (?:)+ OP_BRA | OP_KETRMAX 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMAX 0 L M S ( L M S )*
+ (?:)+? OP_BRA | OP_KETRMIN 0 A M S ( A M S )*
+ OP_SBRA | OP_KETRMIN 0 L M S ( L M S )*
+ ()+ OP_CBRA | OP_KETRMAX 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMAX 0 C M S ( C M S )*
+ ()+? OP_CBRA | OP_KETRMIN 0 C M S ( C M S )*
+ OP_SCBRA | OP_KETRMIN 0 C M S ( C M S )*
+ (?:)? OP_BRAZERO | OP_BRA | OP_KET S ( A M 0 )
+ (?:)?? OP_BRAMINZERO | OP_BRA | OP_KET S ( A M 0 )
+ ()? OP_BRAZERO | OP_CBRA | OP_KET S ( C M 0 )
+ ()?? OP_BRAMINZERO | OP_CBRA | OP_KET S ( C M 0 )
+ (?:)* OP_BRAZERO | OP_BRA | OP_KETRMAX S 0 ( A M S )*
+ OP_BRAZERO | OP_SBRA | OP_KETRMAX S 0 ( L M S )*
+ (?:)*? OP_BRAMINZERO | OP_BRA | OP_KETRMIN S 0 ( A M S )*
+ OP_BRAMINZERO | OP_SBRA | OP_KETRMIN S 0 ( L M S )*
+ ()* OP_BRAZERO | OP_CBRA | OP_KETRMAX S 0 ( C M S )*
+ OP_BRAZERO | OP_SCBRA | OP_KETRMAX S 0 ( C M S )*
+ ()*? OP_BRAMINZERO | OP_CBRA | OP_KETRMIN S 0 ( C M S )*
+ OP_BRAMINZERO | OP_SCBRA | OP_KETRMIN S 0 ( C M S )*
+
+
+ Stack layout naming characters:
+ A - Push the alternative index (starting from 0) on the stack.
+ Not pushed if there is no alternatives.
+ M - Any values pushed by the current alternative. Can be empty, or anything.
+
+ The next list shows the possible content of a bracket:
+ (|) OP_*BRA | OP_ALT ... M A
+ (?()|) OP_*COND | OP_ALT M A
+ (?>|) OP_ONCE | OP_ALT ... [stack trace] M A
+ (?>|) OP_ONCE_NC | OP_ALT ... [stack trace] M A
+ Or nothing, if trace is unnecessary
+*/
+
+static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar opcode;
+int localptr = 0;
+int offset = 0;
+int stacksize;
+pcre_uchar *ccbegin;
+pcre_uchar *hotpath;
+pcre_uchar bra = OP_BRA;
+pcre_uchar ket;
+assert_fallback *assert;
+BOOL has_alternatives;
+struct sljit_jump *jump;
+struct sljit_jump *skip;
+struct sljit_label *rmaxlabel = NULL;
+struct sljit_jump *braminzerojump = NULL;
+
+PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ opcode = *cc;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+hotpath = ccbegin + 1 + LINK_SIZE;
+
+if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
+ {
+ /* Drop this bracket_fallback. */
+ parent->top = fallback->prev;
+ return bracketend(cc);
+ }
+
+ket = *(bracketend(cc) - 1 - LINK_SIZE);
+SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
+SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
+cc += GET(cc, 1);
+
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
+ if (*hotpath == OP_NRREF)
+ {
+ stacksize = GET2(hotpath, 1);
+ if (common->currententry == NULL || stacksize == RREF_ANY)
+ has_alternatives = FALSE;
+ else if (common->currententry->start == 0)
+ has_alternatives = stacksize != 0;
+ else
+ has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+ }
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Capturing brackets has a pre-allocated space. */
+ offset = GET2(ccbegin, 1 + LINK_SIZE);
+ localptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ FALLBACK_AS(bracket_fallback)->localptr = localptr;
+ hotpath += IMM2_SIZE;
+ }
+else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Other brackets simply allocate the next entry. */
+ localptr = PRIV_DATA(ccbegin);
+ SLJIT_ASSERT(localptr != 0);
+ FALLBACK_AS(bracket_fallback)->localptr = localptr;
+ if (opcode == OP_ONCE)
+ FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);
+ }
+
+/* Instructions before the first alternative. */
+stacksize = 0;
+if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ stacksize++;
+if (bra == OP_BRAZERO)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (bra == OP_BRAZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (ket != OP_KETRMIN)
+ {
+ free_stack(common, 1);
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* Nothing stored during the first run. */
+ skip = JUMP(SLJIT_JUMP);
+ JUMPHERE(jump);
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)
+ {
+ /* When we come from outside, localptr contains the previous STR_PTR. */
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ }
+ else
+ {
+ /* Except when the whole stack frame must be saved. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));
+ }
+ JUMPHERE(skip);
+ }
+ else
+ {
+ jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPHERE(jump);
+ }
+ }
+ }
+
+if (ket == OP_KETRMIN)
+ FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();
+
+if (ket == OP_KETRMAX)
+ {
+ rmaxlabel = LABEL();
+ if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
+ FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;
+ }
+
+/* Handling capturing brackets and alternatives. */
+if (opcode == OP_ONCE)
+ {
+ if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)
+ {
+ /* Neither capturing brackets nor recursions are not found in the block. */
+ if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ else if (ket == OP_KETRMAX || has_alternatives)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+ }
+ else
+ {
+ if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
+ {
+ allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE);
+ }
+ else
+ {
+ allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);
+ }
+ }
+ }
+else if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ {
+ /* Saving the previous values. */
+ allocate_stack(common, 3);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ /* Saving the previous value. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+else if (has_alternatives)
+ {
+ /* Pushing the starting string pointer. */
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+/* Generating code for the first alternative. */
+if (opcode == OP_COND || opcode == OP_SCOND)
+ {
+ if (*hotpath == OP_CREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
+ CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ hotpath += 1 + IMM2_SIZE;
+ }
+ else if (*hotpath == OP_NCREF)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ stacksize = GET2(hotpath, 1);
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
+
+ JUMPHERE(jump);
+ hotpath += 1 + IMM2_SIZE;
+ }
+ else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
+ {
+ /* Never has other case. */
+ FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
+
+ stacksize = GET2(hotpath, 1);
+ if (common->currententry == NULL)
+ stacksize = 0;
+ else if (stacksize == RREF_ANY)
+ stacksize = 1;
+ else if (common->currententry->start == 0)
+ stacksize = stacksize == 0;
+ else
+ stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+
+ if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
+ {
+ SLJIT_ASSERT(!has_alternatives);
+ if (stacksize != 0)
+ hotpath += 1 + IMM2_SIZE;
+ else
+ {
+ if (*cc == OP_ALT)
+ {
+ hotpath = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+ else
+ hotpath = cc;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives);
+
+ stacksize = GET2(hotpath, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
+ OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
+ sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
+ hotpath += 1 + IMM2_SIZE;
+ }
+ }
+ else
+ {
+ SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
+ /* Similar code as PUSH_FALLBACK macro. */
+ assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ memset(assert, 0, sizeof(assert_fallback));
+ assert->common.cc = hotpath;
+ FALLBACK_AS(bracket_fallback)->u.assert = assert;
+ hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);
+ }
+ }
+
+compile_hotpath(common, hotpath, cc, fallback);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+if (opcode == OP_ONCE)
+ {
+ if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the localptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+ else
+ {
+ stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+ }
+
+stacksize = 0;
+if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+if (has_alternatives && opcode != OP_ONCE)
+ stacksize++;
+
+if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+stacksize = 0;
+if (ket != OP_KET)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ stacksize++;
+ }
+else if (bra != OP_BRA)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+if (has_alternatives)
+ {
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ if (ket != OP_KETRMAX)
+ FALLBACK_AS(bracket_fallback)->althotpath = LABEL();
+ }
+
+/* Must be after the hotpath label. */
+if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ if (opcode == OP_ONCE || opcode >= OP_SBRA)
+ {
+ if (has_alternatives)
+ FALLBACK_AS(bracket_fallback)->althotpath = LABEL();
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE)
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
+ else
+ /* TMP2 must contain the starting STR_PTR. */
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, rmaxlabel);
+ FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();
+ }
+
+if (bra == OP_BRAZERO)
+ FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();
+
+if (bra == OP_BRAMINZERO)
+ {
+ /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
+ JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);
+ if (braminzerojump != NULL)
+ {
+ JUMPHERE(braminzerojump);
+ /* We need to release the end pointer to perform the
+ fallback for the zero-length iteration. When
+ framesize is < 0, OP_ONCE will do the release itself. */
+ if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ else if (ket == OP_KETRMIN && opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ /* Continue to the normal fallback. */
+ }
+
+if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
+ decrease_call_count(common);
+
+/* Skip the other alternatives. */
+while (*cc == OP_ALT)
+ cc += GET(cc, 1);
+cc += 1 + LINK_SIZE;
+return cc;
+}
+
+static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar opcode;
+int localptr;
+int cbraprivptr = 0;
+int framesize;
+int stacksize;
+int offset = 0;
+BOOL zero = FALSE;
+pcre_uchar *ccbegin = NULL;
+int stack;
+struct sljit_label *loop = NULL;
+struct jump_list *emptymatch = NULL;
+
+PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);
+if (*cc == OP_BRAPOSZERO)
+ {
+ zero = TRUE;
+ cc++;
+ }
+
+opcode = *cc;
+localptr = PRIV_DATA(cc);
+SLJIT_ASSERT(localptr != 0);
+FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
+switch(opcode)
+ {
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ ccbegin = cc + 1 + LINK_SIZE;
+ break;
+
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ offset = GET2(cc, 1 + LINK_SIZE);
+ cbraprivptr = OVECTOR_PRIV(offset);
+ offset <<= 1;
+ ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+framesize = get_framesize(common, cc, FALSE);
+FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
+if (framesize < 0)
+ {
+ stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
+ if (!zero)
+ stacksize++;
+ FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
+
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
+ }
+else
+ {
+ stacksize = framesize + 1;
+ if (!zero)
+ stacksize++;
+ if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ stacksize++;
+ FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
+ allocate_stack(common, stacksize);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
+ stack = 0;
+ if (!zero)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
+ stack++;
+ }
+ if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
+ stack++;
+ }
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
+ init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
+ }
+
+if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+
+loop = LABEL();
+while (*cc != OP_KETRPOS)
+ {
+ fallback->top = NULL;
+ fallback->topfallbacks = NULL;
+ cc += GET(cc, 1);
+
+ compile_hotpath(common, ccbegin, cc, fallback);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+
+ if (framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
+ if (opcode == OP_SBRAPOS)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
+ }
+
+ if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
+ add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
+
+ if (!zero)
+ {
+ if (framesize < 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ }
+ JUMPTO(SLJIT_JUMP, loop);
+ flush_stubs(common);
+
+ compile_fallbackpath(common, fallback->top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
+ set_jumps(fallback->topfallbacks, LABEL());
+
+ if (framesize < 0)
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ else
+ {
+ if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ {
+ /* Last alternative. */
+ if (*cc == OP_KETRPOS)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
+ }
+ }
+
+ if (*cc == OP_KETRPOS)
+ break;
+ ccbegin = cc + 1 + LINK_SIZE;
+ }
+
+fallback->topfallbacks = NULL;
+if (!zero)
+ {
+ if (framesize < 0)
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
+ else /* TMP2 is set to [localptr] above. */
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
+ }
+
+/* None of them matched. */
+set_jumps(emptymatch, LABEL());
+decrease_call_count(common);
+return cc + 1 + LINK_SIZE;
+}
+
+static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
+{
+int class_len;
+
+*opcode = *cc;
+if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
+ {
+ cc++;
+ *type = OP_CHAR;
+ }
+else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
+ {
+ cc++;
+ *type = OP_CHARI;
+ *opcode -= OP_STARI - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
+ {
+ cc++;
+ *type = OP_NOT;
+ *opcode -= OP_NOTSTAR - OP_STAR;
+ }
+else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
+ {
+ cc++;
+ *type = OP_NOTI;
+ *opcode -= OP_NOTSTARI - OP_STAR;
+ }
+else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
+ {
+ cc++;
+ *opcode -= OP_TYPESTAR - OP_STAR;
+ *type = 0;
+ }
+else
+ {
+ SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
+ *type = *opcode;
+ cc++;
+ class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
+ *opcode = cc[class_len - 1];
+ if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
+ {
+ *opcode -= OP_CRSTAR - OP_STAR;
+ if (end != NULL)
+ *end = cc + class_len;
+ }
+ else
+ {
+ SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
+ *arg1 = GET2(cc, (class_len + IMM2_SIZE));
+ *arg2 = GET2(cc, class_len);
+
+ if (*arg2 == 0)
+ {
+ SLJIT_ASSERT(*arg1 != 0);
+ *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
+ }
+ if (*arg1 == *arg2)
+ *opcode = OP_EXACT;
+
+ if (end != NULL)
+ *end = cc + class_len + 2 * IMM2_SIZE;
+ }
+ return cc;
+ }
+
+if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
+ {
+ *arg1 = GET2(cc, 0);
+ cc += IMM2_SIZE;
+ }
+
+if (*type == 0)
+ {
+ *type = *cc;
+ if (end != NULL)
+ *end = next_opcode(common, cc);
+ cc++;
+ return cc;
+ }
+
+if (end != NULL)
+ {
+ *end = cc + 1;
+#ifdef SUPPORT_UTF
+ if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
+#endif
+ }
+return cc;
+}
+
+static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+pcre_uchar opcode;
+pcre_uchar type;
+int arg1 = -1, arg2 = -1;
+pcre_uchar* end;
+jump_list *nomatch = NULL;
+struct sljit_jump *jump = NULL;
+struct sljit_label *label;
+
+PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_PLUS:
+ case OP_UPTO:
+ case OP_CRRANGE:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ if (opcode == OP_STAR || opcode == OP_UPTO)
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
+ }
+ else
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ if (opcode == OP_UPTO || opcode == OP_CRRANGE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
+
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
+ if (opcode == OP_UPTO || opcode == OP_CRRANGE)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ if (opcode == OP_CRRANGE && arg2 > 0)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);
+ if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ }
+
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, label);
+ if (jump != NULL)
+ JUMPHERE(jump);
+ }
+ else
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
+ {
+ OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ }
+ set_jumps(nomatch, LABEL());
+ if (opcode == OP_PLUS || opcode == OP_CRRANGE)
+ add_jump(compiler, &fallback->topfallbacks,
+ CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_MINSTAR:
+ case OP_MINPLUS:
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode == OP_MINPLUS)
+ add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_MINUPTO:
+ case OP_CRMINRANGE:
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ if (opcode == OP_CRMINRANGE)
+ add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_QUERY:
+ case OP_MINQUERY:
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (opcode == OP_QUERY)
+ compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
+ FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
+ break;
+
+ case OP_EXACT:
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ break;
+
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSUPTO:
+ if (opcode != OP_POSSTAR)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ label = LABEL();
+ compile_char1_hotpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ if (opcode != OP_POSUPTO)
+ {
+ if (opcode == OP_POSPLUS)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);
+ JUMPTO(SLJIT_JUMP, label);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ }
+ set_jumps(nomatch, LABEL());
+ if (opcode == OP_POSPLUS)
+ add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ break;
+
+ case OP_POSQUERY:
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ compile_char1_hotpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
+ set_jumps(nomatch, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+decrease_call_count(common);
+return end;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+
+PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);
+
+if (*cc == OP_FAIL)
+ {
+ add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+ return cc + 1;
+ }
+
+if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
+ {
+ /* No need to check notempty conditions. */
+ if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->acceptlabel);
+ return cc + 1;
+ }
+
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
+else
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
+else
+ CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+if (common->acceptlabel == NULL)
+ add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
+else
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
+add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
+return cc + 1;
+}
+
+static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)
+{
+DEFINE_COMPILER;
+int offset = GET2(cc, 1);
+
+/* Data will be discarded anyway... */
+if (common->currententry != NULL)
+ return cc + 1 + IMM2_SIZE;
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
+offset <<= 1;
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+return cc + 1 + IMM2_SIZE;
+}
+
+static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)
+{
+DEFINE_COMPILER;
+fallback_common *fallback;
+
+while (cc < ccend)
+ {
+ switch(*cc)
+ {
+ case OP_SOD:
+ case OP_SOM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+ case OP_NOTPROP:
+ case OP_PROP:
+ case OP_ANYNL:
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
+ case OP_EXTUNI:
+ case OP_EODN:
+ case OP_EOD:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_REVERSE:
+ cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+
+ case OP_SET_SOM:
+ PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ cc++;
+ break;
+
+ case OP_CHAR:
+ case OP_CHARI:
+ cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ cc = compile_iterator_hotpath(common, cc, parent);
+ break;
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
+ cc = compile_iterator_hotpath(common, cc, parent);
+ else
+ cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+
+#if defined SUPPORT_UTF || defined COMPILE_PCRE16
+ case OP_XCLASS:
+ if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
+ cc = compile_iterator_hotpath(common, cc, parent);
+ else
+ cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
+ break;
+#endif
+
+ case OP_REF:
+ case OP_REFI:
+ if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
+ cc = compile_ref_iterator_hotpath(common, cc, parent);
+ else
+ cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);
+ break;
+
+ case OP_RECURSE:
+ cc = compile_recurse_hotpath(common, cc, parent);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);
+ cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);
+ break;
+
+ case OP_BRAMINZERO:
+ PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);
+ cc = bracketend(cc + 1);
+ if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
+ else
+ {
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
+ }
+ FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ decrease_call_count(common);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ cc = compile_bracket_hotpath(common, cc, parent);
+ break;
+
+ case OP_BRAZERO:
+ if (cc[1] > OP_ASSERTBACK_NOT)
+ cc = compile_bracket_hotpath(common, cc, parent);
+ else
+ {
+ PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);
+ cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);
+ }
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ cc = compile_bracketpos_hotpath(common, cc, parent);
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ cc = compile_fail_accept_hotpath(common, cc, parent);
+ break;
+
+ case OP_CLOSE:
+ cc = compile_close_hotpath(common, cc);
+ break;
+
+ case OP_SKIPZERO:
+ cc = bracketend(cc + 1);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ return;
+ }
+ if (cc == NULL)
+ return;
+ }
+SLJIT_ASSERT(cc == ccend);
+}
+
+#undef PUSH_FALLBACK
+#undef PUSH_FALLBACK_NOVALUE
+#undef FALLBACK_AS
+
+#define COMPILE_FALLBACKPATH(current) \
+ do \
+ { \
+ compile_fallbackpath(common, (current)); \
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
+ return; \
+ } \
+ while (0)
+
+#define CURRENT_AS(type) ((type*)current)
+
+static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar opcode;
+pcre_uchar type;
+int arg1 = -1, arg2 = -1;
+struct sljit_label *label = NULL;
+struct sljit_jump *jump = NULL;
+
+cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
+
+switch(opcode)
+ {
+ case OP_STAR:
+ case OP_PLUS:
+ case OP_UPTO:
+ case OP_CRRANGE:
+ if (type == OP_ANYNL || type == OP_EXTUNI)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+ }
+ else
+ {
+ if (opcode == OP_STAR || opcode == OP_UPTO)
+ arg2 = 0;
+ else if (opcode == OP_PLUS)
+ arg2 = 1;
+ jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ skip_char_back(common);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ if (opcode == OP_PLUS || opcode == OP_CRRANGE)
+ set_jumps(current->topfallbacks, LABEL());
+ JUMPHERE(jump);
+ free_stack(common, 2);
+ }
+ break;
+
+ case OP_MINSTAR:
+ case OP_MINPLUS:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (opcode == OP_MINPLUS)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ current->topfallbacks = NULL;
+ }
+ compile_char1_hotpath(common, type, cc, ¤t->topfallbacks);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ set_jumps(current->topfallbacks, LABEL());
+ free_stack(common, 1);
+ break;
+
+ case OP_MINUPTO:
+ case OP_CRMINRANGE:
+ if (opcode == OP_CRMINRANGE)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ current->topfallbacks = NULL;
+ label = LABEL();
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ compile_char1_hotpath(common, type, cc, ¤t->topfallbacks);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+
+ if (opcode == OP_CRMINRANGE)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
+
+ if (opcode == OP_CRMINRANGE && arg1 == 0)
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ else
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_fallback)->hotpath);
+
+ set_jumps(current->topfallbacks, LABEL());
+ free_stack(common, 2);
+ break;
+
+ case OP_QUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topfallbacks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ JUMPHERE(jump);
+ free_stack(common, 1);
+ break;
+
+ case OP_MINQUERY:
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ compile_char1_hotpath(common, type, cc, ¤t->topfallbacks);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
+ set_jumps(current->topfallbacks, LABEL());
+ JUMPHERE(jump);
+ free_stack(common, 1);
+ break;
+
+ case OP_EXACT:
+ case OP_POSPLUS:
+ set_jumps(current->topfallbacks, LABEL());
+ break;
+
+ case OP_POSSTAR:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+}
+
+static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar type;
+
+type = cc[1 + IMM2_SIZE];
+if ((type & 0x1) == 0)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+ return;
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
+set_jumps(current->topfallbacks, LABEL());
+free_stack(common, 2);
+}
+
+static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+
+set_jumps(current->topfallbacks, LABEL());
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+free_stack(common, 1);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
+}
+
+static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = current->cc;
+pcre_uchar bra = OP_BRA;
+struct sljit_jump *brajump = NULL;
+
+SLJIT_ASSERT(*cc != OP_BRAMINZERO);
+if (*cc == OP_BRAZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ SLJIT_ASSERT(current->topfallbacks == NULL);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+
+if (CURRENT_AS(assert_fallback)->framesize < 0)
+ {
+ set_jumps(current->topfallbacks, LABEL());
+
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);
+ free_stack(common, 1);
+ }
+ return;
+ }
+
+if (bra == OP_BRAZERO)
+ {
+ if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);
+ free_stack(common, 1);
+ return;
+ }
+ free_stack(common, 1);
+ brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ }
+
+if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));
+
+ set_jumps(current->topfallbacks, LABEL());
+ }
+else
+ set_jumps(current->topfallbacks, LABEL());
+
+if (bra == OP_BRAZERO)
+ {
+ /* We know there is enough place on the stack. */
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath);
+ JUMPHERE(brajump);
+ }
+}
+
+static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+int opcode;
+int offset = 0;
+int localptr = CURRENT_AS(bracket_fallback)->localptr;
+int stacksize;
+int count;
+pcre_uchar *cc = current->cc;
+pcre_uchar *ccbegin;
+pcre_uchar *ccprev;
+jump_list *jumplist = NULL;
+jump_list *jumplistitem = NULL;
+pcre_uchar bra = OP_BRA;
+pcre_uchar ket;
+assert_fallback *assert;
+BOOL has_alternatives;
+struct sljit_jump *brazero = NULL;
+struct sljit_jump *once = NULL;
+struct sljit_jump *cond = NULL;
+struct sljit_label *rminlabel = NULL;
+
+if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
+ {
+ bra = *cc;
+ cc++;
+ }
+
+opcode = *cc;
+ccbegin = cc;
+ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
+cc += GET(cc, 1);
+has_alternatives = *cc == OP_ALT;
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
+if (opcode == OP_CBRA || opcode == OP_SCBRA)
+ offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
+if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
+ opcode = OP_SCOND;
+if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
+ opcode = OP_ONCE;
+
+if (ket == OP_KETRMAX)
+ {
+ if (bra != OP_BRAZERO)
+ free_stack(common, 1);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+ }
+else if (ket == OP_KETRMIN)
+ {
+ if (bra != OP_BRAMINZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (opcode >= OP_SBRA || opcode == OP_ONCE)
+ {
+ /* Checking zero-length iteration. */
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0)
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_fallback)->recursivehotpath);
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_fallback)->recursivehotpath);
+ }
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath);
+ }
+ rminlabel = LABEL();
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
+ }
+
+if (SLJIT_UNLIKELY(opcode == OP_ONCE))
+ {
+ if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ }
+ once = JUMP(SLJIT_JUMP);
+ }
+else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ if (has_alternatives)
+ {
+ /* Always exactly one alternative. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+
+ jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
+ if (SLJIT_UNLIKELY(!jumplistitem))
+ return;
+ jumplist = jumplistitem;
+ jumplistitem->next = NULL;
+ jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
+ }
+ }
+else if (*cc == OP_ALT)
+ {
+ /* Build a jump list. Get the last successfully matched branch index. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ count = 1;
+ do
+ {
+ /* Append as the last item. */
+ if (jumplist != NULL)
+ {
+ jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
+ jumplistitem = jumplistitem->next;
+ }
+ else
+ {
+ jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
+ jumplist = jumplistitem;
+ }
+
+ if (SLJIT_UNLIKELY(!jumplistitem))
+ return;
+
+ jumplistitem->next = NULL;
+ jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
+ cc += GET(cc, 1);
+ }
+ while (*cc == OP_ALT);
+
+ cc = ccbegin + GET(ccbegin, 1);
+ }
+
+COMPILE_FALLBACKPATH(current->top);
+if (current->topfallbacks)
+ set_jumps(current->topfallbacks, LABEL());
+
+if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
+ {
+ /* Conditional block always has at most one alternative. */
+ if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ assert = CURRENT_AS(bracket_fallback)->u.assert;
+ if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
+ }
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
+ }
+ else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
+ {
+ SLJIT_ASSERT(has_alternatives);
+ cond = JUMP(SLJIT_JUMP);
+ set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
+ }
+ else
+ SLJIT_ASSERT(!has_alternatives);
+ }
+
+if (has_alternatives)
+ {
+ count = 1;
+ do
+ {
+ current->top = NULL;
+ current->topfallbacks = NULL;
+ current->nextfallbacks = NULL;
+ if (*cc == OP_ALT)
+ {
+ ccprev = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ if (opcode != OP_COND && opcode != OP_SCOND)
+ {
+ if (localptr != 0 && opcode != OP_ONCE)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ compile_hotpath(common, ccprev, cc, current);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ }
+
+ /* Instructions after the current alternative is succesfully matched. */
+ /* There is a similar code in compile_bracket_hotpath. */
+ if (opcode == OP_ONCE)
+ {
+ if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ if (ket == OP_KETRMAX)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
+ else if (ket == OP_KETRMIN)
+ {
+ /* Move the STR_PTR to the localptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ }
+ else
+ {
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));
+ if (ket == OP_KETRMAX)
+ {
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
+ }
+ }
+
+ stacksize = 0;
+ if (opcode != OP_ONCE)
+ stacksize++;
+ if (ket != OP_KET || bra != OP_BRA)
+ stacksize++;
+
+ if (stacksize > 0) {
+ if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ allocate_stack(common, stacksize);
+ else
+ {
+ /* We know we have place at least for one item on the top of the stack. */
+ SLJIT_ASSERT(stacksize == 1);
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
+ }
+ }
+
+ stacksize = 0;
+ if (ket != OP_KET || bra != OP_BRA)
+ {
+ if (ket != OP_KET)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ stacksize++;
+ }
+
+ if (opcode != OP_ONCE)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
+
+ if (offset != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
+ }
+
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath);
+
+ if (opcode != OP_ONCE)
+ {
+ SLJIT_ASSERT(jumplist);
+ JUMPHERE(jumplist->jump);
+ jumplist = jumplist->next;
+ }
+
+ COMPILE_FALLBACKPATH(current->top);
+ if (current->topfallbacks)
+ set_jumps(current->topfallbacks, LABEL());
+ SLJIT_ASSERT(!current->nextfallbacks);
+ }
+ while (*cc == OP_ALT);
+ SLJIT_ASSERT(!jumplist);
+
+ if (cond != NULL)
+ {
+ SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
+ assert = CURRENT_AS(bracket_fallback)->u.assert;
+ if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
+
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
+ }
+ JUMPHERE(cond);
+ }
+
+ /* Free the STR_PTR. */
+ if (localptr == 0)
+ free_stack(common, 1);
+ }
+
+if (offset != 0)
+ {
+ /* Using both tmp register is better for instruction scheduling. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
+ free_stack(common, 3);
+ }
+else if (opcode == OP_SBRA || opcode == OP_SCOND)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ }
+else if (opcode == OP_ONCE)
+ {
+ cc = ccbegin + GET(ccbegin, 1);
+ if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ {
+ /* Reset head and drop saved frame. */
+ stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
+ free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);
+ }
+ else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
+ {
+ /* The STR_PTR must be released. */
+ free_stack(common, 1);
+ }
+
+ JUMPHERE(once);
+ /* Restore previous localptr */
+ if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_fallback)->u.framesize * sizeof(sljit_w));
+ else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ /* See the comment below. */
+ free_stack(common, 2);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
+ }
+ }
+
+if (ket == OP_KETRMAX)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath);
+ if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);
+ JUMPHERE(brazero);
+ }
+ free_stack(common, 1);
+ }
+else if (ket == OP_KETRMIN)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ /* OP_ONCE removes everything in case of a fallback, so we don't
+ need to explicitly release the STR_PTR. The extra release would
+ affect badly the free_stack(2) above. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);
+ if (opcode == OP_ONCE)
+ free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
+ else if (bra == OP_BRAMINZERO)
+ free_stack(common, 1);
+ }
+else if (bra == OP_BRAZERO)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);
+ JUMPHERE(brazero);
+ }
+}
+
+static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+int offset;
+struct sljit_jump *jump;
+
+if (CURRENT_AS(bracketpos_fallback)->framesize < 0)
+ {
+ if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
+ {
+ offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ }
+ set_jumps(current->topfallbacks, LABEL());
+ free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
+ return;
+ }
+
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr);
+add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+
+if (current->topfallbacks)
+ {
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(current->topfallbacks, LABEL());
+ /* Drop the stack frame. */
+ free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
+ JUMPHERE(jump);
+ }
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));
+}
+
+static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+assert_fallback fallback;
+
+current->top = NULL;
+current->topfallbacks = NULL;
+current->nextfallbacks = NULL;
+if (current->cc[1] > OP_ASSERTBACK_NOT)
+ {
+ /* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */
+ compile_bracket_hotpath(common, current->cc, current);
+ compile_bracket_fallbackpath(common, current->top);
+ }
+else
+ {
+ memset(&fallback, 0, sizeof(fallback));
+ fallback.common.cc = current->cc;
+ fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath;
+ /* Manual call of compile_assert_hotpath. */
+ compile_assert_hotpath(common, current->cc, &fallback, FALSE);
+ }
+SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks);
+}
+
+static void compile_fallbackpath(compiler_common *common, struct fallback_common *current)
+{
+DEFINE_COMPILER;
+
+while (current)
+ {
+ if (current->nextfallbacks != NULL)
+ set_jumps(current->nextfallbacks, LABEL());
+ switch(*current->cc)
+ {
+ case OP_SET_SOM:
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0);
+ break;
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+ case OP_NOTSTAR:
+ case OP_NOTMINSTAR:
+ case OP_NOTPLUS:
+ case OP_NOTMINPLUS:
+ case OP_NOTQUERY:
+ case OP_NOTMINQUERY:
+ case OP_NOTUPTO:
+ case OP_NOTMINUPTO:
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+ case OP_NOTSTARI:
+ case OP_NOTMINSTARI:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUSI:
+ case OP_NOTQUERYI:
+ case OP_NOTMINQUERYI:
+ case OP_NOTUPTOI:
+ case OP_NOTMINUPTOI:
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+ case OP_CLASS:
+ case OP_NCLASS:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#endif
+ compile_iterator_fallbackpath(common, current);
+ break;
+
+ case OP_REF:
+ case OP_REFI:
+ compile_ref_iterator_fallbackpath(common, current);
+ break;
+
+ case OP_RECURSE:
+ compile_recurse_fallbackpath(common, current);
+ break;
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ compile_assert_fallbackpath(common, current);
+ break;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SCBRA:
+ case OP_SCOND:
+ compile_bracket_fallbackpath(common, current);
+ break;
+
+ case OP_BRAZERO:
+ if (current->cc[1] > OP_ASSERTBACK_NOT)
+ compile_bracket_fallbackpath(common, current);
+ else
+ compile_assert_fallbackpath(common, current);
+ break;
+
+ case OP_BRAPOS:
+ case OP_CBRAPOS:
+ case OP_SBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOSZERO:
+ compile_bracketpos_fallbackpath(common, current);
+ break;
+
+ case OP_BRAMINZERO:
+ compile_braminzero_fallbackpath(common, current);
+ break;
+
+ case OP_FAIL:
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ set_jumps(current->topfallbacks, LABEL());
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ current = current->prev;
+ }
+}
+
+static SLJIT_INLINE void compile_recurse(compiler_common *common)
+{
+DEFINE_COMPILER;
+pcre_uchar *cc = common->start + common->currententry->start;
+pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
+pcre_uchar *ccend = bracketend(cc);
+int localsize = get_localsize(common, ccbegin, ccend);
+int framesize = get_framesize(common, cc, TRUE);
+int alternativesize;
+BOOL needsframe;
+fallback_common altfallback;
+struct sljit_jump *jump;
+
+SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
+needsframe = framesize >= 0;
+if (!needsframe)
+ framesize = 0;
+alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
+
+SLJIT_ASSERT(common->currententry->entry == NULL);
+common->currententry->entry = LABEL();
+set_jumps(common->currententry->calls, common->currententry->entry);
+
+sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize);
+allocate_stack(common, localsize + framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
+copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);
+if (needsframe)
+ init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
+
+if (alternativesize > 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+
+memset(&altfallback, 0, sizeof(fallback_common));
+common->acceptlabel = NULL;
+common->accept = NULL;
+altfallback.cc = ccbegin;
+cc += GET(cc, 1);
+while (1)
+ {
+ altfallback.top = NULL;
+ altfallback.topfallbacks = NULL;
+
+ if (altfallback.cc != ccbegin)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+
+ compile_hotpath(common, altfallback.cc, cc, &altfallback);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+
+ add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
+
+ compile_fallbackpath(common, altfallback.top);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return;
+ set_jumps(altfallback.topfallbacks, LABEL());
+
+ if (*cc != OP_ALT)
+ break;
+
+ altfallback.cc = cc + 1 + LINK_SIZE;
+ cc += GET(cc, 1);
+ }
+/* None of them matched. */
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+jump = JUMP(SLJIT_JUMP);
+
+set_jumps(common->accept, LABEL());
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD);
+if (needsframe)
+ {
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
+ }
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
+
+JUMPHERE(jump);
+copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);
+free_stack(common, localsize + framesize + alternativesize);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
+OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
+}
+
+#undef COMPILE_FALLBACKPATH
+#undef CURRENT_AS
+
+void
+PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)
+{
+struct sljit_compiler *compiler;
+fallback_common rootfallback;
+compiler_common common_data;
+compiler_common *common = &common_data;
+const pcre_uint8 *tables = re->tables;
+pcre_study_data *study;
+pcre_uchar *ccend;
+executable_function *function;
+void *executable_func;
+sljit_uw executable_size;
+struct sljit_label *leave;
+struct sljit_label *mainloop = NULL;
+struct sljit_label *empty_match_found;
+struct sljit_label *empty_match_fallback;
+struct sljit_jump *alloc_error;
+struct sljit_jump *reqbyte_notfound = NULL;
+struct sljit_jump *empty_match;
+
+SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
+study = extra->study_data;
+
+if (!tables)
+ tables = PRIV(default_tables);
+
+memset(&rootfallback, 0, sizeof(fallback_common));
+rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
+
+common->compiler = NULL;
+common->start = rootfallback.cc;
+common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
+common->fcc = tables + fcc_offset;
+common->lcc = (sljit_w)(tables + lcc_offset);
+common->nltype = NLTYPE_FIXED;
+switch(re->options & PCRE_NEWLINE_BITS)
+ {
+ case 0:
+ /* Compile-time default */
+ switch (NEWLINE)
+ {
+ case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: common->newline = NEWLINE; break;
+ }
+ break;
+ case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
+ case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
+ case PCRE_NEWLINE_CR+
+ PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
+ case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
+ case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
+ default: return;
+ }
+if ((re->options & PCRE_BSR_ANYCRLF) != 0)
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+else if ((re->options & PCRE_BSR_UNICODE) != 0)
+ common->bsr_nltype = NLTYPE_ANY;
+else
+ {
+#ifdef BSR_ANYCRLF
+ common->bsr_nltype = NLTYPE_ANYCRLF;
+#else
+ common->bsr_nltype = NLTYPE_ANY;
+#endif
+ }
+common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+common->ctypes = (sljit_w)(tables + ctypes_offset);
+common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
+common->name_count = re->name_count;
+common->name_entry_size = re->name_entry_size;
+common->acceptlabel = NULL;
+common->stubs = NULL;
+common->entries = NULL;
+common->currententry = NULL;
+common->accept = NULL;
+common->calllimit = NULL;
+common->stackalloc = NULL;
+common->revertframes = NULL;
+common->wordboundary = NULL;
+common->anynewline = NULL;
+common->hspace = NULL;
+common->vspace = NULL;
+common->casefulcmp = NULL;
+common->caselesscmp = NULL;
+common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+#ifdef SUPPORT_UTF
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+common->utf = (re->options & PCRE_UTF8) != 0;
+#ifdef SUPPORT_UCP
+common->use_ucp = (re->options & PCRE_UCP) != 0;
+#endif
+common->utfreadchar = NULL;
+#ifdef COMPILE_PCRE8
+common->utfreadtype8 = NULL;
+#endif
+#endif /* SUPPORT_UTF */
+#ifdef SUPPORT_UCP
+common->getucd = NULL;
+#endif
+ccend = bracketend(rootfallback.cc);
+SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
+common->localsize = get_localspace(common, rootfallback.cc, ccend);
+if (common->localsize < 0)
+ return;
+common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
+if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
+ return;
+common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
+if (!common->localptrs)
+ return;
+memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
+set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
+
+compiler = sljit_create_compiler();
+if (!compiler)
+ {
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+common->compiler = compiler;
+
+/* Main pcre_jit_exec entry. */
+sljit_emit_enter(compiler, 1, 5, 5, common->localsize);
+
+/* Register init. */
+reset_ovector(common, (re->top_bracket + 1) * 2);
+if ((re->flags & PCRE_REQCHSET) != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);
+
+OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
+
+/* Main part of the matching */
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ /* Forward search if possible. */
+ if ((re->flags & PCRE_FIRSTSET) != 0)
+ fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ else if ((re->flags & PCRE_STARTLINE) != 0)
+ fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
+ else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
+ fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
+ }
+if ((re->flags & PCRE_REQCHSET) != 0)
+ reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
+
+/* Store the current STR_PTR in OVECTOR(0). */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
+/* Copy the limit of allowed recursions. */
+OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
+
+compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+
+empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+empty_match_found = LABEL();
+
+common->acceptlabel = LABEL();
+if (common->accept != NULL)
+ set_jumps(common->accept, common->acceptlabel);
+
+/* This means we have a match. Update the ovector. */
+copy_ovector(common, re->top_bracket + 1);
+leave = LABEL();
+sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
+
+empty_match_fallback = LABEL();
+compile_fallbackpath(common, rootfallback.top);
+if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+
+SLJIT_ASSERT(rootfallback.prev == NULL);
+
+/* Check we have remaining characters. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+
+if ((re->options & PCRE_ANCHORED) == 0)
+ {
+ if ((re->options & PCRE_FIRSTLINE) == 0)
+ {
+ if (study != NULL && study->minlength > 1)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
+ }
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
+ }
+ else
+ {
+ if (study != NULL && study->minlength > 1)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
+ COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
+ COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+ JUMPTO(SLJIT_C_ZERO, mainloop);
+ }
+ else
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop);
+ }
+ }
+
+if (reqbyte_notfound != NULL)
+ JUMPHERE(reqbyte_notfound);
+/* Copy OVECTOR(1) to OVECTOR(0) */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+JUMPTO(SLJIT_JUMP, leave);
+
+flush_stubs(common);
+
+JUMPHERE(empty_match);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_fallback);
+OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
+CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
+JUMPTO(SLJIT_JUMP, empty_match_fallback);
+
+common->currententry = common->entries;
+while (common->currententry != NULL)
+ {
+ /* Might add new entries. */
+ compile_recurse(common);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ {
+ sljit_free_compiler(compiler);
+ SLJIT_FREE(common->localptrs);
+ return;
+ }
+ flush_stubs(common);
+ common->currententry = common->currententry->next;
+ }
+
+/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
+/* This is a (really) rare case. */
+set_jumps(common->stackalloc, LABEL());
+/* RETURN_ADDR is not a saved register. */
+sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
+OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
+
+sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
+alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
+OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
+sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+
+/* Allocation failed. */
+JUMPHERE(alloc_error);
+/* We break the return address cache here, but this is a really rare case. */
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
+JUMPTO(SLJIT_JUMP, leave);
+
+/* Call limit reached. */
+set_jumps(common->calllimit, LABEL());
+OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
+JUMPTO(SLJIT_JUMP, leave);
+
+if (common->revertframes != NULL)
+ {
+ set_jumps(common->revertframes, LABEL());
+ do_revertframes(common);
+ }
+if (common->wordboundary != NULL)
+ {
+ set_jumps(common->wordboundary, LABEL());
+ check_wordboundary(common);
+ }
+if (common->anynewline != NULL)
+ {
+ set_jumps(common->anynewline, LABEL());
+ check_anynewline(common);
+ }
+if (common->hspace != NULL)
+ {
+ set_jumps(common->hspace, LABEL());
+ check_hspace(common);
+ }
+if (common->vspace != NULL)
+ {
+ set_jumps(common->vspace, LABEL());
+ check_vspace(common);
+ }
+if (common->casefulcmp != NULL)
+ {
+ set_jumps(common->casefulcmp, LABEL());
+ do_casefulcmp(common);
+ }
+if (common->caselesscmp != NULL)
+ {
+ set_jumps(common->caselesscmp, LABEL());
+ do_caselesscmp(common);
+ }
+#ifdef SUPPORT_UTF
+if (common->utfreadchar != NULL)
+ {
+ set_jumps(common->utfreadchar, LABEL());
+ do_utfreadchar(common);
+ }
+#ifdef COMPILE_PCRE8
+if (common->utfreadtype8 != NULL)
+ {
+ set_jumps(common->utfreadtype8, LABEL());
+ do_utfreadtype8(common);
+ }
+#endif
+#endif /* COMPILE_PCRE8 */
+#ifdef SUPPORT_UCP
+if (common->getucd != NULL)
+ {
+ set_jumps(common->getucd, LABEL());
+ do_getucd(common);
+ }
+#endif
+
+SLJIT_FREE(common->localptrs);
+executable_func = sljit_generate_code(compiler);
+executable_size = sljit_get_generated_code_size(compiler);
+sljit_free_compiler(compiler);
+if (executable_func == NULL)
+ return;
+
+function = SLJIT_MALLOC(sizeof(executable_function));
+if (function == NULL)
+ {
+ /* This case is highly unlikely since we just recently
+ freed a lot of memory. Although not impossible. */
+ sljit_free_code(executable_func);
+ return;
+ }
+
+function->executable_func = executable_func;
+function->executable_size = executable_size;
+function->callback = NULL;
+function->userdata = NULL;
+extra->executable_jit = function;
+extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
+}
+
+static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)
+{
+union {
+ void* executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+pcre_uint8 local_area[LOCAL_SPACE_SIZE];
+struct sljit_stack local_stack;
+
+local_stack.top = (sljit_w)&local_area;
+local_stack.base = local_stack.top;
+local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
+local_stack.max_limit = local_stack.limit;
+arguments->stack = &local_stack;
+convert_executable_func.executable_func = function->executable_func;
+return convert_executable_func.call_executable_func(arguments);
+}
+
+int
+PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,
+ const pcre_uchar *subject, int length, int start_offset, int options,
+ int match_limit, int *offsets, int offsetcount)
+{
+executable_function *function = (executable_function*)executable_func;
+union {
+ void* executable_func;
+ jit_function call_executable_func;
+} convert_executable_func;
+jit_arguments arguments;
+int maxoffsetcount;
+int retval;
+
+/* Sanity checks should be handled by pcre_exec. */
+arguments.stack = NULL;
+arguments.str = subject + start_offset;
+arguments.begin = subject;
+arguments.end = subject + length;
+arguments.calllimit = match_limit; /* JIT decreases this value less times. */
+arguments.notbol = (options & PCRE_NOTBOL) != 0;
+arguments.noteol = (options & PCRE_NOTEOL) != 0;
+arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
+arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
+arguments.offsets = offsets;
+
+/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
+the output vector for storing captured strings, with the remainder used as
+workspace. We don't need the workspace here. For compatibility, we limit the
+number of captured strings in the same way as pcre_exec(), so that the user
+gets the same result with and without JIT. */
+
+if (offsetcount != 2)
+ offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
+maxoffsetcount = (re->top_bracket + 1) * 2;
+if (offsetcount > maxoffsetcount)
+ offsetcount = maxoffsetcount;
+arguments.offsetcount = offsetcount;
+
+if (function->callback)
+ arguments.stack = (struct sljit_stack*)function->callback(function->userdata);
+else
+ arguments.stack = (struct sljit_stack*)function->userdata;
+
+if (arguments.stack == NULL)
+ retval = jit_machine_stack_exec(&arguments, function);
+else
+ {
+ convert_executable_func.executable_func = function->executable_func;
+ retval = convert_executable_func.call_executable_func(&arguments);
+ }
+
+if (retval * 2 > offsetcount)
+ retval = 0;
+return retval;
+}
+
+void
+PRIV(jit_free)(void *executable_func)
+{
+executable_function *function = (executable_function*)executable_func;
+sljit_free_code(function->executable_func);
+SLJIT_FREE(function);
+}
+
+int
+PRIV(jit_get_size)(void *executable_func)
+{
+return ((executable_function*)executable_func)->executable_size;
+}
+
+const char*
+PRIV(jit_get_target)(void)
+{
+return sljit_get_platform_name();
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL pcre_jit_stack *
+pcre_jit_stack_alloc(int startsize, int maxsize)
+#else
+PCRE_EXP_DECL pcre16_jit_stack *
+pcre16_jit_stack_alloc(int startsize, int maxsize)
+#endif
+{
+if (startsize < 1 || maxsize < 1)
+ return NULL;
+if (startsize > maxsize)
+ startsize = maxsize;
+startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_stack_free(pcre_jit_stack *stack)
+#else
+PCRE_EXP_DECL void
+pcre16_jit_stack_free(pcre16_jit_stack *stack)
+#endif
+{
+sljit_free_stack((struct sljit_stack*)stack);
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
+#else
+PCRE_EXP_DECL void
+pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
+#endif
+{
+executable_function *function;
+if (extra != NULL &&
+ (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra->executable_jit != NULL)
+ {
+ function = (executable_function*)extra->executable_jit;
+ function->callback = callback;
+ function->userdata = userdata;
+ }
+}
+
+#else /* SUPPORT_JIT */
+
+/* These are dummy functions to avoid linking errors when JIT support is not
+being compiled. */
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL pcre_jit_stack *
+pcre_jit_stack_alloc(int startsize, int maxsize)
+#else
+PCRE_EXP_DECL pcre16_jit_stack *
+pcre16_jit_stack_alloc(int startsize, int maxsize)
+#endif
+{
+(void)startsize;
+(void)maxsize;
+return NULL;
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_stack_free(pcre_jit_stack *stack)
+#else
+PCRE_EXP_DECL void
+pcre16_jit_stack_free(pcre16_jit_stack *stack)
+#endif
+{
+(void)stack;
+}
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
+#else
+PCRE_EXP_DECL void
+pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
+#endif
+{
+(void)extra;
+(void)callback;
+(void)userdata;
+}
+
+#endif
+
+/* End of pcre_jit_compile.c */
diff --git a/src/3rdparty/pcre/pcre_maketables.c b/src/3rdparty/pcre/pcre_maketables.c
new file mode 100644
index 00000000000..caacdba3e68
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_maketables.c
@@ -0,0 +1,148 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_maketables(), which builds
+character tables for PCRE in the current locale. The file is compiled on its
+own as part of the PCRE library. However, it is also included in the
+compilation of dftables.c, in which case the macro DFTABLES is defined. */
+
+
+#ifndef DFTABLES
+# ifdef PCRE_HAVE_CONFIG_H
+# include "config.h"
+# endif
+# include "pcre_internal.h"
+#endif
+
+
+/*************************************************
+* Create PCRE character tables *
+*************************************************/
+
+/* This function builds a set of character tables for use by PCRE and returns
+a pointer to them. They are build using the ctype functions, and consequently
+their contents will depend upon the current locale setting. When compiled as
+part of the library, the store is obtained via PUBL(malloc)(), but when
+compiled inside dftables, use malloc().
+
+Arguments: none
+Returns: pointer to the contiguous block of data
+*/
+
+#ifdef COMPILE_PCRE8
+const unsigned char *
+pcre_maketables(void)
+#else
+const unsigned char *
+pcre16_maketables(void)
+#endif
+{
+unsigned char *yield, *p;
+int i;
+
+#ifndef DFTABLES
+yield = (unsigned char*)(PUBL(malloc))(tables_length);
+#else
+yield = (unsigned char*)malloc(tables_length);
+#endif
+
+if (yield == NULL) return NULL;
+p = yield;
+
+/* First comes the lower casing table */
+
+for (i = 0; i < 256; i++) *p++ = tolower(i);
+
+/* Next the case-flipping table */
+
+for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
+
+/* Then the character class tables. Don't try to be clever and save effort on
+exclusive ones - in some locales things may be different. Note that the table
+for "space" includes everything "isspace" gives, including VT in the default
+locale. This makes it work for the POSIX class [:space:]. Note also that it is
+possible for a character to be alnum or alpha without being lower or upper,
+such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at
+least under Debian Linux's locales as of 12/2005). So we must test for alnum
+specially. */
+
+memset(p, 0, cbit_length);
+for (i = 0; i < 256; i++)
+ {
+ if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7);
+ if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7);
+ if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7);
+ if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7);
+ if (i == '_') p[cbit_word + i/8] |= 1 << (i&7);
+ if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7);
+ if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
+ if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7);
+ if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7);
+ if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7);
+ if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7);
+ }
+p += cbit_length;
+
+/* Finally, the character type table. In this, we exclude VT from the white
+space chars, because Perl doesn't recognize it as such for \s and for comments
+within regexes. */
+
+for (i = 0; i < 256; i++)
+ {
+ int x = 0;
+ if (i != 0x0b && isspace(i)) x += ctype_space;
+ if (isalpha(i)) x += ctype_letter;
+ if (isdigit(i)) x += ctype_digit;
+ if (isxdigit(i)) x += ctype_xdigit;
+ if (isalnum(i) || i == '_') x += ctype_word;
+
+ /* Note: strchr includes the terminating zero in the characters it considers.
+ In this instance, that is ok because we want binary zero to be flagged as a
+ meta-character, which in this sense is any character that terminates a run
+ of data characters. */
+
+ if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta;
+ *p++ = x;
+ }
+
+return yield;
+}
+
+/* End of pcre_maketables.c */
diff --git a/src/3rdparty/pcre/pcre_newline.c b/src/3rdparty/pcre/pcre_newline.c
new file mode 100644
index 00000000000..8ee2a6e588b
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_newline.c
@@ -0,0 +1,184 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains internal functions for testing newlines when more than
+one kind of newline is to be recognized. When a newline is found, its length is
+returned. In principle, we could implement several newline "types", each
+referring to a different set of newline characters. At present, PCRE supports
+only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
+and NLTYPE_ANY. The full list of Unicode newline characters is taken from
+http://unicode.org/unicode/reports/tr18/. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+
+/*************************************************
+* Check for newline at given position *
+*************************************************/
+
+/* It is guaranteed that the initial value of ptr is less than the end of the
+string that is being processed.
+
+Arguments:
+ ptr pointer to possible newline
+ type the newline type
+ endptr pointer to the end of the string
+ lenptr where to return the length
+ utf TRUE if in utf mode
+
+Returns: TRUE or FALSE
+*/
+
+BOOL
+PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
+ BOOL utf)
+{
+int c;
+(void)utf;
+#ifdef SUPPORT_UTF
+if (utf)
+ {
+ GETCHAR(c, ptr);
+ }
+else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+ {
+ case 0x000a: *lenptr = 1; return TRUE; /* LF */
+ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
+ return TRUE; /* CR */
+ default: return FALSE;
+ }
+
+/* NLTYPE_ANY */
+
+else switch(c)
+ {
+ case 0x000a: /* LF */
+ case 0x000b: /* VT */
+ case 0x000c: *lenptr = 1; return TRUE; /* FF */
+ case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
+ return TRUE; /* CR */
+#ifdef COMPILE_PCRE8
+ case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 3; return TRUE; /* PS */
+#else
+ case 0x0085: /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 1; return TRUE; /* PS */
+#endif /* COMPILE_PCRE8 */
+ default: return FALSE;
+ }
+}
+
+
+
+/*************************************************
+* Check for newline at previous position *
+*************************************************/
+
+/* It is guaranteed that the initial value of ptr is greater than the start of
+the string that is being processed.
+
+Arguments:
+ ptr pointer to possible newline
+ type the newline type
+ startptr pointer to the start of the string
+ lenptr where to return the length
+ utf TRUE if in utf mode
+
+Returns: TRUE or FALSE
+*/
+
+BOOL
+PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
+ BOOL utf)
+{
+int c;
+(void)utf;
+ptr--;
+#ifdef SUPPORT_UTF
+if (utf)
+ {
+ BACKCHAR(ptr);
+ GETCHAR(c, ptr);
+ }
+else
+#endif /* SUPPORT_UTF */
+ c = *ptr;
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+ {
+ case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
+ return TRUE; /* LF */
+ case 0x000d: *lenptr = 1; return TRUE; /* CR */
+ default: return FALSE;
+ }
+
+else switch(c)
+ {
+ case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
+ return TRUE; /* LF */
+ case 0x000b: /* VT */
+ case 0x000c: /* FF */
+ case 0x000d: *lenptr = 1; return TRUE; /* CR */
+#ifdef COMPILE_PCRE8
+ case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 3; return TRUE; /* PS */
+#else
+ case 0x0085: /* NEL */
+ case 0x2028: /* LS */
+ case 0x2029: *lenptr = 1; return TRUE; /* PS */
+#endif /* COMPILE_PCRE8 */
+ default: return FALSE;
+ }
+}
+
+/* End of pcre_newline.c */
diff --git a/src/3rdparty/pcre/pcre_ord2utf8.c b/src/3rdparty/pcre/pcre_ord2utf8.c
new file mode 100644
index 00000000000..6afd235f799
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_ord2utf8.c
@@ -0,0 +1,97 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF8 string. */
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Convert character value to UTF-8 *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x10ffff
+and encodes it as a UTF-8 character in 1 to 6 pcre_uchars.
+
+Arguments:
+ cvalue the character value
+ buffer pointer to buffer for result - at least 6 pcre_uchars long
+
+Returns: number of characters placed in the buffer
+*/
+
+int
+PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
+{
+#ifdef SUPPORT_UTF
+
+register int i, j;
+
+/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
+Should never happen in practice. */
+if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
+ cvalue = 0xfffe;
+
+for (i = 0; i < PRIV(utf8_table1_size); i++)
+ if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
+buffer += i;
+for (j = i; j > 0; j--)
+ {
+ *buffer-- = 0x80 | (cvalue & 0x3f);
+ cvalue >>= 6;
+ }
+*buffer = PRIV(utf8_table2)[i] | cvalue;
+return i + 1;
+
+#else
+
+(void)(cvalue); /* Keep compiler happy; this function won't ever be */
+(void)(buffer); /* called when SUPPORT_UTF is not defined. */
+return 0;
+
+#endif
+}
+
+/* End of pcre_ord2utf8.c */
diff --git a/src/3rdparty/pcre/pcre_refcount.c b/src/3rdparty/pcre/pcre_refcount.c
new file mode 100644
index 00000000000..263a1e11dc2
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_refcount.c
@@ -0,0 +1,89 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_refcount(), which is an
+auxiliary function that can be used to maintain a reference count in a compiled
+pattern data block. This might be helpful in applications where the block is
+shared by different users. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Maintain reference count *
+*************************************************/
+
+/* The reference count is a 16-bit field, initialized to zero. It is not
+possible to transfer a non-zero count from one host to a different host that
+has a different byte order - though I can't see why anyone in their right mind
+would ever want to do that!
+
+Arguments:
+ argument_re points to compiled code
+ adjust value to add to the count
+
+Returns: the (possibly updated) count value (a non-negative number), or
+ a negative error number
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_refcount(pcre *argument_re, int adjust)
+#else
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre16_refcount(pcre16 *argument_re, int adjust)
+#endif
+{
+REAL_PCRE *re = (REAL_PCRE *)argument_re;
+if (re == NULL) return PCRE_ERROR_NULL;
+if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
+if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+re->ref_count = (-adjust > re->ref_count)? 0 :
+ (adjust + re->ref_count > 65535)? 65535 :
+ re->ref_count + adjust;
+return re->ref_count;
+}
+
+/* End of pcre_refcount.c */
diff --git a/src/3rdparty/pcre/pcre_string_utils.c b/src/3rdparty/pcre/pcre_string_utils.c
new file mode 100644
index 00000000000..d4545532a7e
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_string_utils.c
@@ -0,0 +1,168 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by both pcre_exec() and pcre_def_exec(). */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#ifndef COMPILE_PCRE8
+
+/*************************************************
+* Compare string utilities *
+*************************************************/
+
+/* The following two functions compares two strings. Basically an strcmp
+for non 8 bit characters.
+
+Arguments:
+ str1 first string
+ str2 second string
+
+Returns: 0 if both string are equal (like strcmp), 1 otherwise
+*/
+
+int
+PRIV(strcmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2)
+{
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (*str1 != '\0' || *str2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+int
+PRIV(strcmp_uc_c8)(const pcre_uchar *str1, const char *str2)
+{
+const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (*str1 != '\0' || *ustr2 != '\0')
+ {
+ c1 = *str1++;
+ c2 = (pcre_uchar)*ustr2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+/* The following two functions compares two, fixed length
+strings. Basically an strncmp for non 8 bit characters.
+
+Arguments:
+ str1 first string
+ str2 second string
+ num size of the string
+
+Returns: 0 if both string are equal (like strcmp), 1 otherwise
+*/
+
+int
+PRIV(strncmp_uc_uc)(const pcre_uchar *str1, const pcre_uchar *str2, unsigned int num)
+{
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (num-- > 0)
+ {
+ c1 = *str1++;
+ c2 = *str2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+int
+PRIV(strncmp_uc_c8)(const pcre_uchar *str1, const char *str2, unsigned int num)
+{
+const pcre_uint8 *ustr2 = (pcre_uint8 *)str2;
+pcre_uchar c1;
+pcre_uchar c2;
+
+while (num-- > 0)
+ {
+ c1 = *str1++;
+ c2 = (pcre_uchar)*ustr2++;
+ if (c1 != c2)
+ return ((c1 > c2) << 1) - 1;
+ }
+/* Both length and characters must be equal. */
+return 0;
+}
+
+/* The following function returns with the length of
+a zero terminated string. Basically an strlen for non 8 bit characters.
+
+Arguments:
+ str string
+
+Returns: length of the string
+*/
+
+unsigned int
+PRIV(strlen_uc)(const pcre_uchar *str)
+{
+unsigned int len = 0;
+while (*str++ != 0)
+ len++;
+return len;
+}
+
+#endif /* COMPILE_PCRE8 */
+
+/* End of pcre_string_utils.c */
diff --git a/src/3rdparty/pcre/pcre_study.c b/src/3rdparty/pcre/pcre_study.c
new file mode 100644
index 00000000000..6b6edc3f313
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_study.c
@@ -0,0 +1,1527 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_study(), along with local
+supporting functions. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#define SET_BIT(c) start_bits[c/8] |= (1 << (c&7))
+
+/* Returns from set_start_bits() */
+
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
+
+
+
+/*************************************************
+* Find the minimum subject length for a group *
+*************************************************/
+
+/* Scan a parenthesized group and compute the minimum length of subject that
+is needed to match it. This is a lower bound; it does not mean there is a
+string of that length that matches. In UTF8 mode, the result is in characters
+rather than bytes.
+
+Arguments:
+ code pointer to start of group (the bracket)
+ startcode pointer to start of the whole pattern
+ options the compiling options
+ int RECURSE depth
+
+Returns: the minimum length
+ -1 if \C in UTF-8 mode or (*ACCEPT) was encountered
+ -2 internal error (missing capturing bracket)
+ -3 internal error (opcode not listed)
+*/
+
+static int
+find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
+ int recurse_depth)
+{
+int length = -1;
+/* PCRE_UTF16 has the same value as PCRE_UTF8. */
+BOOL utf = (options & PCRE_UTF8) != 0;
+BOOL had_recurse = FALSE;
+register int branchlength = 0;
+register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
+
+if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
+
+/* Scan along the opcodes for this branch. If we get to the end of the
+branch, check the length against that of the other branches. */
+
+for (;;)
+ {
+ int d, min;
+ pcre_uchar *cs, *ce;
+ register int op = *cc;
+
+ switch (op)
+ {
+ case OP_COND:
+ case OP_SCOND:
+
+ /* If there is only one branch in a condition, the implied branch has zero
+ length, so we don't add anything. This covers the DEFINE "condition"
+ automatically. */
+
+ cs = cc + GET(cc, 1);
+ if (*cs != OP_ALT)
+ {
+ cc = cs + 1 + LINK_SIZE;
+ break;
+ }
+
+ /* Otherwise we can fall through and treat it the same as any other
+ subpattern. */
+
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_BRA:
+ case OP_SBRA:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ d = find_minlength(cc, startcode, options, recurse_depth);
+ if (d < 0) return d;
+ branchlength += d;
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* ACCEPT makes things far too complicated; we have to give up. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ return -1;
+
+ /* Reached end of a branch; if it's a ket it is the end of a nested
+ call. If it's ALT it is an alternation in a nested call. If it is END it's
+ the end of the outer call. All can be handled by the same code. If an
+ ACCEPT was previously encountered, use the length that was in force at that
+ time, and pass back the shortest ACCEPT length. */
+
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_END:
+ if (length < 0 || (!had_recurse && branchlength < length))
+ length = branchlength;
+ if (op != OP_ALT) return length;
+ cc += 1 + LINK_SIZE;
+ branchlength = 0;
+ had_recurse = FALSE;
+ break;
+
+ /* Skip over assertive subpatterns */
+
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ /* Fall through */
+
+ /* Skip over things that don't match chars */
+
+ case OP_REVERSE:
+ case OP_CREF:
+ case OP_NCREF:
+ case OP_RREF:
+ case OP_NRREF:
+ case OP_DEF:
+ case OP_CALLOUT:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_NOT_WORD_BOUNDARY:
+ case OP_WORD_BOUNDARY:
+ cc += PRIV(OP_lengths)[*cc];
+ break;
+
+ /* Skip over a subpattern that has a {0} or {0,x} quantifier */
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ case OP_SKIPZERO:
+ cc += PRIV(OP_lengths)[*cc];
+ do cc += GET(cc, 1); while (*cc == OP_ALT);
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Handle literal characters and + repetitions */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_PLUS:
+ case OP_PLUSI:
+ case OP_MINPLUS:
+ case OP_MINPLUSI:
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ branchlength++;
+ cc += 2;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ branchlength++;
+ cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
+ break;
+
+ /* Handle exact repetitions. The count is already in characters, but we
+ need to skip over a multibyte character in UTF8 mode. */
+
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE;
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ case OP_TYPEEXACT:
+ branchlength += GET2(cc,1);
+ cc += 2 + IMM2_SIZE + ((cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+ break;
+
+ /* Handle single-char non-literal matchers */
+
+ case OP_PROP:
+ case OP_NOTPROP:
+ cc += 2;
+ /* Fall through */
+
+ case OP_NOT_DIGIT:
+ case OP_DIGIT:
+ case OP_NOT_WHITESPACE:
+ case OP_WHITESPACE:
+ case OP_NOT_WORDCHAR:
+ case OP_WORDCHAR:
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_EXTUNI:
+ case OP_HSPACE:
+ case OP_NOT_HSPACE:
+ case OP_VSPACE:
+ case OP_NOT_VSPACE:
+ branchlength++;
+ cc++;
+ break;
+
+ /* "Any newline" might match two characters, but it also might match just
+ one. */
+
+ case OP_ANYNL:
+ branchlength += 1;
+ cc++;
+ break;
+
+ /* The single-byte matcher means we can't proceed in UTF-8 mode. (In
+ non-UTF-8 mode \C will actually be turned into OP_ALLANY, so won't ever
+ appear, but leave the code, just in case.) */
+
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UTF
+ if (utf) return -1;
+#endif
+ branchlength++;
+ cc++;
+ break;
+
+ /* For repeated character types, we have to test for \p and \P, which have
+ an extra two bytes of parameters. */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSQUERY:
+ if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ if (cc[1 + IMM2_SIZE] == OP_PROP
+ || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2;
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ /* Check a class for variable quantification */
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
+ /* Fall through */
+#endif
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ cc += PRIV(OP_lengths)[OP_CLASS];
+
+ switch (*cc)
+ {
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ branchlength++;
+ /* Fall through */
+
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ branchlength += GET2(cc,1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ branchlength++;
+ break;
+ }
+ break;
+
+ /* Backreferences and subroutine calls are treated in the same way: we find
+ the minimum length for the subpattern. A recursion, however, causes an
+ a flag to be set that causes the length of this branch to be ignored. The
+ logic is that a recursion can only make sense if there is another
+ alternation that stops the recursing. That will provide the minimum length
+ (when no recursion happens). A backreference within the group that it is
+ referencing behaves in the same way.
+
+ If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket
+ matches an empty string (by default it causes a matching failure), so in
+ that case we must set the minimum length to zero. */
+
+ case OP_REF:
+ case OP_REFI:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
+ {
+ ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(cc, 1));
+ if (cs == NULL) return -2;
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce)
+ {
+ d = 0;
+ had_recurse = TRUE;
+ }
+ else
+ {
+ d = find_minlength(cs, startcode, options, recurse_depth);
+ }
+ }
+ else d = 0;
+ cc += 1 + IMM2_SIZE;
+
+ /* Handle repeated back references */
+
+ switch (*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ min = 0;
+ cc++;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ min = 1;
+ cc++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ min = GET2(cc, 1);
+ cc += 1 + 2 * IMM2_SIZE;
+ break;
+
+ default:
+ min = 1;
+ break;
+ }
+
+ branchlength += min * d;
+ break;
+
+ /* We can easily detect direct recursion, but not mutual recursion. This is
+ caught by a recursion depth count. */
+
+ case OP_RECURSE:
+ cs = ce = (pcre_uchar *)startcode + GET(cc, 1);
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if ((cc > cs && cc < ce) || recurse_depth > 10)
+ had_recurse = TRUE;
+ else
+ {
+ branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
+ /* Anything else does not or need not match a character. We can get the
+ item's length from the table, but for those that can match zero occurrences
+ of a character, we must take special action for UTF-8 characters. As it
+ happens, the "NOT" versions of these opcodes are used at present only for
+ ASCII characters, so they could be omitted from this list. However, in
+ future that may change, so we include them here so as not to leave a
+ gotcha for a future maintainer. */
+
+ case OP_UPTO:
+ case OP_UPTOI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_MINUPTO:
+ case OP_MINUPTOI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_POSUPTO:
+ case OP_POSUPTOI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+
+ case OP_STAR:
+ case OP_STARI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_MINSTAR:
+ case OP_MINSTARI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_POSSTAR:
+ case OP_POSSTARI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+
+ case OP_QUERY:
+ case OP_QUERYI:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_MINQUERY:
+ case OP_MINQUERYI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_POSQUERY:
+ case OP_POSQUERYI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+
+ cc += PRIV(OP_lengths)[op];
+#ifdef SUPPORT_UTF
+ if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
+#endif
+ break;
+
+ /* Skip these, but we need to add in the name length. */
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
+ cc += PRIV(OP_lengths)[op] + cc[1];
+ break;
+
+ /* The remaining opcodes are just skipped over. */
+
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_FAIL:
+ case OP_PRUNE:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_THEN:
+ cc += PRIV(OP_lengths)[op];
+ break;
+
+ /* This should not occur: we list all opcodes explicitly so that when
+ new ones get added they are properly considered. */
+
+ default:
+ return -3;
+ }
+ }
+/* Control never gets here */
+}
+
+
+
+/*************************************************
+* Set a bit and maybe its alternate case *
+*************************************************/
+
+/* Given a character, set its first byte's bit in the table, and also the
+corresponding bit for the other version of a letter if we are caseless. In
+UTF-8 mode, for characters greater than 127, we can only do the caseless thing
+when Unicode property support is available.
+
+Arguments:
+ start_bits points to the bit map
+ p points to the character
+ caseless the caseless flag
+ cd the block with char table pointers
+ utf TRUE for UTF-8 / UTF-16 mode
+
+Returns: pointer after the character
+*/
+
+static const pcre_uchar *
+set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
+ compile_data *cd, BOOL utf)
+{
+unsigned int c = *p;
+
+#ifdef COMPILE_PCRE8
+SET_BIT(c);
+
+#ifdef SUPPORT_UTF
+if (utf && c > 127)
+ {
+ GETCHARINC(c, p);
+#ifdef SUPPORT_UCP
+ if (caseless)
+ {
+ pcre_uchar buff[6];
+ c = UCD_OTHERCASE(c);
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+ }
+#endif
+ return p;
+ }
+#endif
+
+/* Not UTF-8 mode, or character is less than 127. */
+
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
+return p + 1;
+#endif
+
+#ifdef COMPILE_PCRE16
+if (c > 0xff)
+ {
+ c = 0xff;
+ caseless = FALSE;
+ }
+SET_BIT(c);
+
+#ifdef SUPPORT_UTF
+if (utf && c > 127)
+ {
+ GETCHARINC(c, p);
+#ifdef SUPPORT_UCP
+ if (caseless)
+ {
+ c = UCD_OTHERCASE(c);
+ if (c > 0xff)
+ c = 0xff;
+ SET_BIT(c);
+ }
+#endif
+ return p;
+ }
+#endif
+
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
+return p + 1;
+#endif
+}
+
+
+
+/*************************************************
+* Set bits for a positive character type *
+*************************************************/
+
+/* This function sets starting bits for a character type. In UTF-8 mode, we can
+only do a direct setting for bytes less than 128, as otherwise there can be
+confusion with bytes in the middle of UTF-8 characters. In a "traditional"
+environment, the tables will only recognize ASCII characters anyway, but in at
+least one Windows environment, some higher bytes bits were set in the tables.
+So we deal with that case by considering the UTF-8 encoding.
+
+Arguments:
+ start_bits the starting bitmap
+ cbit type the type of character wanted
+ table_limit 32 for non-UTF-8; 16 for UTF-8
+ cd the block with char table pointers
+
+Returns: nothing
+*/
+
+static void
+set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
+ compile_data *cd)
+{
+register int c;
+for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type];
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (table_limit == 32) return;
+for (c = 128; c < 256; c++)
+ {
+ if ((cd->cbits[c/8] & (1 << (c&7))) != 0)
+ {
+ pcre_uchar buff[6];
+ (void)PRIV(ord2utf)(c, buff);
+ SET_BIT(buff[0]);
+ }
+ }
+#endif
+}
+
+
+/*************************************************
+* Set bits for a negative character type *
+*************************************************/
+
+/* This function sets starting bits for a negative character type such as \D.
+In UTF-8 mode, we can only do a direct setting for bytes less than 128, as
+otherwise there can be confusion with bytes in the middle of UTF-8 characters.
+Unlike in the positive case, where we can set appropriate starting bits for
+specific high-valued UTF-8 characters, in this case we have to set the bits for
+all high-valued characters. The lowest is 0xc2, but we overkill by starting at
+0xc0 (192) for simplicity.
+
+Arguments:
+ start_bits the starting bitmap
+ cbit type the type of character wanted
+ table_limit 32 for non-UTF-8; 16 for UTF-8
+ cd the block with char table pointers
+
+Returns: nothing
+*/
+
+static void
+set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
+ compile_data *cd)
+{
+register int c;
+for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type];
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff;
+#endif
+}
+
+
+
+/*************************************************
+* Create bitmap of starting bytes *
+*************************************************/
+
+/* This function scans a compiled unanchored expression recursively and
+attempts to build a bitmap of the set of possible starting bytes. As time goes
+by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
+useful for parenthesized groups in patterns such as (a*)b where the group
+provides some optional starting bytes but scanning must continue at the outer
+level to find at least one mandatory byte. At the outermost level, this
+function fails unless the result is SSB_DONE.
+
+Arguments:
+ code points to an expression
+ start_bits points to a 32-byte table, initialized to 0
+ utf TRUE if in UTF-8 / UTF-16 mode
+ cd the block with char table pointers
+
+Returns: SSB_FAIL => Failed to find any starting bytes
+ SSB_DONE => Found mandatory starting bytes
+ SSB_CONTINUE => Found optional starting bytes
+ SSB_UNKNOWN => Hit an unrecognized opcode
+*/
+
+static int
+set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
+ compile_data *cd)
+{
+register int c;
+int yield = SSB_DONE;
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+int table_limit = utf? 16:32;
+#else
+int table_limit = 32;
+#endif
+
+#if 0
+/* ========================================================================= */
+/* The following comment and code was inserted in January 1999. In May 2006,
+when it was observed to cause compiler warnings about unused values, I took it
+out again. If anybody is still using OS/2, they will have to put it back
+manually. */
+
+/* This next statement and the later reference to dummy are here in order to
+trick the optimizer of the IBM C compiler for OS/2 into generating correct
+code. Apparently IBM isn't going to fix the problem, and we would rather not
+disable optimization (in this module it actually makes a big difference, and
+the pcre module can use all the optimization it can get). */
+
+volatile int dummy;
+/* ========================================================================= */
+#endif
+
+do
+ {
+ BOOL try_next = TRUE;
+ const pcre_uchar *tcode = code + 1 + LINK_SIZE;
+
+ if (*code == OP_CBRA || *code == OP_SCBRA ||
+ *code == OP_CBRAPOS || *code == OP_SCBRAPOS) tcode += IMM2_SIZE;
+
+ while (try_next) /* Loop for items in this branch */
+ {
+ int rc;
+
+ switch(*tcode)
+ {
+ /* If we reach something we don't understand, it means a new opcode has
+ been created that hasn't been added to this code. Hopefully this problem
+ will be discovered during testing. */
+
+ default:
+ return SSB_UNKNOWN;
+
+ /* Fail for a valid opcode that implies no starting bits. */
+
+ case OP_ACCEPT:
+ case OP_ASSERT_ACCEPT:
+ case OP_ALLANY:
+ case OP_ANY:
+ case OP_ANYBYTE:
+ case OP_CIRC:
+ case OP_CIRCM:
+ case OP_CLOSE:
+ case OP_COMMIT:
+ case OP_COND:
+ case OP_CREF:
+ case OP_DEF:
+ case OP_DOLL:
+ case OP_DOLLM:
+ case OP_END:
+ case OP_EOD:
+ case OP_EODN:
+ case OP_EXTUNI:
+ case OP_FAIL:
+ case OP_MARK:
+ case OP_NCREF:
+ case OP_NOT:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+ case OP_NOTI:
+ case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+ case OP_NOTMINQUERY:
+ case OP_NOTMINQUERYI:
+ case OP_NOTMINSTAR:
+ case OP_NOTMINSTARI:
+ case OP_NOTMINUPTO:
+ case OP_NOTMINUPTOI:
+ case OP_NOTPLUS:
+ case OP_NOTPLUSI:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSUPTO:
+ case OP_NOTPOSUPTOI:
+ case OP_NOTPROP:
+ case OP_NOTQUERY:
+ case OP_NOTQUERYI:
+ case OP_NOTSTAR:
+ case OP_NOTSTARI:
+ case OP_NOTUPTO:
+ case OP_NOTUPTOI:
+ case OP_NOT_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_NRREF:
+ case OP_PROP:
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_RECURSE:
+ case OP_REF:
+ case OP_REFI:
+ case OP_REVERSE:
+ case OP_RREF:
+ case OP_SCOND:
+ case OP_SET_SOM:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ case OP_SOD:
+ case OP_SOM:
+ case OP_THEN:
+ case OP_THEN_ARG:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+#endif
+ return SSB_FAIL;
+
+ /* We can ignore word boundary tests. */
+
+ case OP_WORD_BOUNDARY:
+ case OP_NOT_WORD_BOUNDARY:
+ tcode++;
+ break;
+
+ /* If we hit a bracket or a positive lookahead assertion, recurse to set
+ bits from within the subpattern. If it can't find anything, we have to
+ give up. If it finds some mandatory character(s), we are done for this
+ branch. Otherwise, carry on scanning after the subpattern. */
+
+ case OP_BRA:
+ case OP_SBRA:
+ case OP_CBRA:
+ case OP_SCBRA:
+ case OP_BRAPOS:
+ case OP_SBRAPOS:
+ case OP_CBRAPOS:
+ case OP_SCBRAPOS:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_ASSERT:
+ rc = set_start_bits(tcode, start_bits, utf, cd);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+ if (rc == SSB_DONE) try_next = FALSE; else
+ {
+ do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ }
+ break;
+
+ /* If we hit ALT or KET, it means we haven't found anything mandatory in
+ this branch, though we might have found something optional. For ALT, we
+ continue with the next alternative, but we have to arrange that the final
+ result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
+ return SSB_CONTINUE: if this is the top level, that indicates failure,
+ but after a nested subpattern, it causes scanning to continue. */
+
+ case OP_ALT:
+ yield = SSB_CONTINUE;
+ try_next = FALSE;
+ break;
+
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ return SSB_CONTINUE;
+
+ /* Skip over callout */
+
+ case OP_CALLOUT:
+ tcode += 2 + 2*LINK_SIZE;
+ break;
+
+ /* Skip over lookbehind and negative lookahead assertions */
+
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* BRAZERO does the bracket, but carries on. */
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+ case OP_BRAPOSZERO:
+ rc = set_start_bits(++tcode, start_bits, utf, cd);
+ if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
+/* =========================================================================
+ See the comment at the head of this function concerning the next line,
+ which was an old fudge for the benefit of OS/2.
+ dummy = 1;
+ ========================================================================= */
+ do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* SKIPZERO skips the bracket. */
+
+ case OP_SKIPZERO:
+ tcode++;
+ do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+ tcode += 1 + LINK_SIZE;
+ break;
+
+ /* Single-char * or ? sets the bit and tries the next item */
+
+ case OP_STAR:
+ case OP_MINSTAR:
+ case OP_POSSTAR:
+ case OP_QUERY:
+ case OP_MINQUERY:
+ case OP_POSQUERY:
+ tcode = set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
+ break;
+
+ case OP_STARI:
+ case OP_MINSTARI:
+ case OP_POSSTARI:
+ case OP_QUERYI:
+ case OP_MINQUERYI:
+ case OP_POSQUERYI:
+ tcode = set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
+ break;
+
+ /* Single-char upto sets the bit and tries the next */
+
+ case OP_UPTO:
+ case OP_MINUPTO:
+ case OP_POSUPTO:
+ tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, FALSE, cd, utf);
+ break;
+
+ case OP_UPTOI:
+ case OP_MINUPTOI:
+ case OP_POSUPTOI:
+ tcode = set_table_bit(start_bits, tcode + 1 + IMM2_SIZE, TRUE, cd, utf);
+ break;
+
+ /* At least one single char sets the bit and stops */
+
+ case OP_EXACT:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHAR:
+ case OP_PLUS:
+ case OP_MINPLUS:
+ case OP_POSPLUS:
+ (void)set_table_bit(start_bits, tcode + 1, FALSE, cd, utf);
+ try_next = FALSE;
+ break;
+
+ case OP_EXACTI:
+ tcode += IMM2_SIZE;
+ /* Fall through */
+ case OP_CHARI:
+ case OP_PLUSI:
+ case OP_MINPLUSI:
+ case OP_POSPLUSI:
+ (void)set_table_bit(start_bits, tcode + 1, TRUE, cd, utf);
+ try_next = FALSE;
+ break;
+
+ /* Special spacing and line-terminating items. These recognize specific
+ lists of characters. The difference between VSPACE and ANYNL is that the
+ latter can match the two-character CRLF sequence, but that is not
+ relevant for finding the first character, so their code here is
+ identical. */
+
+ case OP_HSPACE:
+ SET_BIT(0x09);
+ SET_BIT(0x20);
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+00A0 */
+ SET_BIT(0xE1); /* For U+1680, U+180E */
+ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
+ SET_BIT(0xE3); /* For U+3000 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xA0);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ SET_BIT(0xA0);
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ try_next = FALSE;
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ SET_BIT(0x0A);
+ SET_BIT(0x0B);
+ SET_BIT(0x0C);
+ SET_BIT(0x0D);
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+0085 */
+ SET_BIT(0xE2); /* For U+2028, U+2029 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0x85);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ {
+ SET_BIT(0x85);
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ try_next = FALSE;
+ break;
+
+ /* Single character types set the bits and stop. Note that if PCRE_UCP
+ is set, we do not see these op codes because \d etc are converted to
+ properties. Therefore, these apply in the case when only characters less
+ than 256 are recognized to match the types. */
+
+ case OP_NOT_DIGIT:
+ set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ case OP_DIGIT:
+ set_type_bits(start_bits, cbit_digit, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ ensure it is set as not whitespace. */
+
+ case OP_NOT_WHITESPACE:
+ set_nottype_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] |= 0x08;
+ try_next = FALSE;
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ not set it from the table. */
+
+ case OP_WHITESPACE:
+ c = start_bits[1]; /* Save in case it was already set */
+ set_type_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] = (start_bits[1] & ~0x08) | c;
+ try_next = FALSE;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ set_nottype_bits(start_bits, cbit_word, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ case OP_WORDCHAR:
+ set_type_bits(start_bits, cbit_word, table_limit, cd);
+ try_next = FALSE;
+ break;
+
+ /* One or more character type fudges the pointer and restarts, knowing
+ it will hit a single character type and stop there. */
+
+ case OP_TYPEPLUS:
+ case OP_TYPEMINPLUS:
+ case OP_TYPEPOSPLUS:
+ tcode++;
+ break;
+
+ case OP_TYPEEXACT:
+ tcode += 1 + IMM2_SIZE;
+ break;
+
+ /* Zero or more repeats of character types set the bits and then
+ try again. */
+
+ case OP_TYPEUPTO:
+ case OP_TYPEMINUPTO:
+ case OP_TYPEPOSUPTO:
+ tcode += IMM2_SIZE; /* Fall through */
+
+ case OP_TYPESTAR:
+ case OP_TYPEMINSTAR:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEQUERY:
+ case OP_TYPEMINQUERY:
+ case OP_TYPEPOSQUERY:
+ switch(tcode[1])
+ {
+ default:
+ case OP_ANY:
+ case OP_ALLANY:
+ return SSB_FAIL;
+
+ case OP_HSPACE:
+ SET_BIT(0x09);
+ SET_BIT(0x20);
+#ifdef COMPILE_PCRE8
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+00A0 */
+ SET_BIT(0xE1); /* For U+1680, U+180E */
+ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
+ SET_BIT(0xE3); /* For U+3000 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xA0);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ SET_BIT(0xA0);
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ SET_BIT(0x0A);
+ SET_BIT(0x0B);
+ SET_BIT(0x0C);
+ SET_BIT(0x0D);
+#ifdef COMPILE_PCRE8
+ if (utf)
+ {
+#ifdef COMPILE_PCRE8
+ SET_BIT(0xC2); /* For U+0085 */
+ SET_BIT(0xE2); /* For U+2028, U+2029 */
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0x85);
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ }
+ else
+#endif /* SUPPORT_UTF */
+ SET_BIT(0x85);
+ break;
+
+ case OP_NOT_DIGIT:
+ set_nottype_bits(start_bits, cbit_digit, table_limit, cd);
+ break;
+
+ case OP_DIGIT:
+ set_type_bits(start_bits, cbit_digit, table_limit, cd);
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ ensure it gets set as not whitespace. */
+
+ case OP_NOT_WHITESPACE:
+ set_nottype_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] |= 0x08;
+ break;
+
+ /* The cbit_space table has vertical tab as whitespace; we have to
+ avoid setting it. */
+
+ case OP_WHITESPACE:
+ c = start_bits[1]; /* Save in case it was already set */
+ set_type_bits(start_bits, cbit_space, table_limit, cd);
+ start_bits[1] = (start_bits[1] & ~0x08) | c;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ set_nottype_bits(start_bits, cbit_word, table_limit, cd);
+ break;
+
+ case OP_WORDCHAR:
+ set_type_bits(start_bits, cbit_word, table_limit, cd);
+ break;
+ }
+
+ tcode += 2;
+ break;
+
+ /* Character class where all the information is in a bit map: set the
+ bits and either carry on or not, according to the repeat count. If it was
+ a negative class, and we are operating with UTF-8 characters, any byte
+ with a value >= 0xc4 is a potentially valid starter because it starts a
+ character with a value > 255. */
+
+ case OP_NCLASS:
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
+ {
+ start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
+ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
+ }
+#endif
+#ifdef COMPILE_PCRE16
+ SET_BIT(0xFF); /* For characters > 255 */
+#endif
+ /* Fall through */
+
+ case OP_CLASS:
+ {
+ pcre_uint8 *map;
+ tcode++;
+ map = (pcre_uint8 *)tcode;
+
+ /* In UTF-8 mode, the bits in a bit map correspond to character
+ values, not to byte values. However, the bit map we are constructing is
+ for byte values. So we have to do a conversion for characters whose
+ value is > 127. In fact, there are only two possible starting bytes for
+ characters in the range 128 - 255. */
+
+#if defined SUPPORT_UTF && defined COMPILE_PCRE8
+ if (utf)
+ {
+ for (c = 0; c < 16; c++) start_bits[c] |= map[c];
+ for (c = 128; c < 256; c++)
+ {
+ if ((map[c/8] && (1 << (c&7))) != 0)
+ {
+ int d = (c >> 6) | 0xc0; /* Set bit for this starter */
+ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
+ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
+ }
+ }
+ }
+ else
+#endif
+ {
+ /* In non-UTF-8 mode, the two bit maps are completely compatible. */
+ for (c = 0; c < 32; c++) start_bits[c] |= map[c];
+ }
+
+ /* Advance past the bit map, and act on what follows. For a zero
+ minimum repeat, continue; otherwise stop processing. */
+
+ tcode += 32 / sizeof(pcre_uchar);
+ switch (*tcode)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ tcode++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
+ else try_next = FALSE;
+ break;
+
+ default:
+ try_next = FALSE;
+ break;
+ }
+ }
+ break; /* End of bitmap class handling */
+
+ } /* End of switch */
+ } /* End of try_next loop */
+
+ code += GET(code, 1); /* Advance to next branch */
+ }
+while (*code == OP_ALT);
+return yield;
+}
+
+
+
+
+
+/*************************************************
+* Study a compiled expression *
+*************************************************/
+
+/* This function is handed a compiled expression that it must study to produce
+information that will speed up the matching. It returns a pcre[16]_extra block
+which then gets handed back to pcre_exec().
+
+Arguments:
+ re points to the compiled expression
+ options contains option bits
+ errorptr points to where to place error messages;
+ set NULL unless error
+
+Returns: pointer to a pcre[16]_extra block, with study_data filled in and
+ the appropriate flags set;
+ NULL on error or if no optimization possible
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
+pcre_study(const pcre *external_re, int options, const char **errorptr)
+#else
+PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION
+pcre16_study(const pcre16 *external_re, int options, const char **errorptr)
+#endif
+{
+int min;
+BOOL bits_set = FALSE;
+pcre_uint8 start_bits[32];
+PUBL(extra) *extra = NULL;
+pcre_study_data *study;
+const pcre_uint8 *tables;
+pcre_uchar *code;
+compile_data compile_block;
+const REAL_PCRE *re = (const REAL_PCRE *)external_re;
+
+*errorptr = NULL;
+
+if (re == NULL || re->magic_number != MAGIC_NUMBER)
+ {
+ *errorptr = "argument is not a compiled regular expression";
+ return NULL;
+ }
+
+if ((re->flags & PCRE_MODE) == 0)
+ {
+#ifdef COMPILE_PCRE8
+ *errorptr = "argument is compiled in 16 bit mode";
+#else
+ *errorptr = "argument is compiled in 8 bit mode";
+#endif
+ return NULL;
+ }
+
+if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
+ {
+ *errorptr = "unknown or incorrect option bit(s) set";
+ return NULL;
+ }
+
+code = (pcre_uchar *)re + re->name_table_offset +
+ (re->name_count * re->name_entry_size);
+
+/* For an anchored pattern, or an unanchored pattern that has a first char, or
+a multiline pattern that matches only at "line starts", there is no point in
+seeking a list of starting bytes. */
+
+if ((re->options & PCRE_ANCHORED) == 0 &&
+ (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
+ {
+ int rc;
+
+ /* Set the character tables in the block that is passed around */
+
+ tables = re->tables;
+
+#ifdef COMPILE_PCRE8
+ if (tables == NULL)
+ (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+ (void *)(&tables));
+#else
+ if (tables == NULL)
+ (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+ (void *)(&tables));
+#endif
+
+ compile_block.lcc = tables + lcc_offset;
+ compile_block.fcc = tables + fcc_offset;
+ compile_block.cbits = tables + cbits_offset;
+ compile_block.ctypes = tables + ctypes_offset;
+
+ /* See if we can find a fixed set of initial characters for the pattern. */
+
+ memset(start_bits, 0, 32 * sizeof(pcre_uint8));
+ rc = set_start_bits(code, start_bits, (re->options & PCRE_UTF8) != 0,
+ &compile_block);
+ bits_set = rc == SSB_DONE;
+ if (rc == SSB_UNKNOWN)
+ {
+ *errorptr = "internal error: opcode not recognized";
+ return NULL;
+ }
+ }
+
+/* Find the minimum length of subject string. */
+
+switch(min = find_minlength(code, code, re->options, 0))
+ {
+ case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
+ case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
+ default: break;
+ }
+
+/* If a set of starting bytes has been identified, or if the minimum length is
+greater than zero, or if JIT optimization has been requested, get a
+pcre[16]_extra block and a pcre_study_data block. The study data is put in the
+latter, which is pointed to by the former, which may also get additional data
+set later by the calling program. At the moment, the size of pcre_study_data
+is fixed. We nevertheless save it in a field for returning via the
+pcre_fullinfo() function so that if it becomes variable in the future,
+we don't have to change that code. */
+
+if (bits_set || min > 0
+#ifdef SUPPORT_JIT
+ || (options & PCRE_STUDY_JIT_COMPILE) != 0
+#endif
+ )
+ {
+ extra = (PUBL(extra) *)(PUBL(malloc))
+ (sizeof(PUBL(extra)) + sizeof(pcre_study_data));
+ if (extra == NULL)
+ {
+ *errorptr = "failed to get memory";
+ return NULL;
+ }
+
+ study = (pcre_study_data *)((char *)extra + sizeof(PUBL(extra)));
+ extra->flags = PCRE_EXTRA_STUDY_DATA;
+ extra->study_data = study;
+
+ study->size = sizeof(pcre_study_data);
+ study->flags = 0;
+
+ /* Set the start bits always, to avoid unset memory errors if the
+ study data is written to a file, but set the flag only if any of the bits
+ are set, to save time looking when none are. */
+
+ if (bits_set)
+ {
+ study->flags |= PCRE_STUDY_MAPPED;
+ memcpy(study->start_bits, start_bits, sizeof(start_bits));
+ }
+ else memset(study->start_bits, 0, 32 * sizeof(pcre_uint8));
+
+#ifdef PCRE_DEBUG
+ if (bits_set)
+ {
+ pcre_uint8 *ptr = start_bits;
+ int i;
+
+ printf("Start bits:\n");
+ for (i = 0; i < 32; i++)
+ printf("%3d: %02x%s", i * 8, *ptr++, ((i + 1) & 0x7) != 0? " " : "\n");
+ }
+#endif
+
+ /* Always set the minlength value in the block, because the JIT compiler
+ makes use of it. However, don't set the bit unless the length is greater than
+ zero - the interpretive pcre_exec() and pcre_dfa_exec() needn't waste time
+ checking the zero case. */
+
+ if (min > 0)
+ {
+ study->flags |= PCRE_STUDY_MINLEN;
+ study->minlength = min;
+ }
+ else study->minlength = 0;
+
+ /* If JIT support was compiled and requested, attempt the JIT compilation.
+ If no starting bytes were found, and the minimum length is zero, and JIT
+ compilation fails, abandon the extra block and return NULL. */
+
+#ifdef SUPPORT_JIT
+ extra->executable_jit = NULL;
+ if ((options & PCRE_STUDY_JIT_COMPILE) != 0) PRIV(jit_compile)(re, extra);
+ if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0)
+ {
+#ifdef COMPILE_PCRE8
+ pcre_free_study(extra);
+#endif
+#ifdef COMPILE_PCRE16
+ pcre16_free_study(extra);
+#endif
+ extra = NULL;
+ }
+#endif
+ }
+
+return extra;
+}
+
+
+/*************************************************
+* Free the study data *
+*************************************************/
+
+/* This function frees the memory that was obtained by pcre_study().
+
+Argument: a pointer to the pcre[16]_extra block
+Returns: nothing
+*/
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN void
+pcre_free_study(pcre_extra *extra)
+#else
+PCRE_EXP_DEFN void
+pcre16_free_study(pcre16_extra *extra)
+#endif
+{
+if (extra == NULL)
+ return;
+#ifdef SUPPORT_JIT
+if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
+ extra->executable_jit != NULL)
+ PRIV(jit_free)(extra->executable_jit);
+#endif
+PUBL(free)(extra);
+}
+
+/* End of pcre_study.c */
diff --git a/src/3rdparty/pcre/pcre_tables.c b/src/3rdparty/pcre/pcre_tables.c
new file mode 100644
index 00000000000..9e449f88889
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_tables.c
@@ -0,0 +1,568 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef PCRE_INCLUDED
+
+/* This module contains some fixed tables that are used by more than one of the
+PCRE code modules. The tables are also #included by the pcretest program, which
+uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
+clashes with the library. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#endif /* PCRE_INCLUDED */
+
+/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
+the definition is next to the definition of the opcodes in pcre_internal.h. */
+
+const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
+
+
+
+/*************************************************
+* Tables for UTF-8 support *
+*************************************************/
+
+/* These are the breakpoints for different numbers of bytes in a UTF-8
+character. */
+
+#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
+ || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16)
+
+/* These tables are also required by pcretest in 16 bit mode. */
+
+const int PRIV(utf8_table1)[] =
+ { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+
+const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
+
+/* These are the indicator bits and the mask for the data bits to set in the
+first byte of a character, indexed by the number of additional bytes. */
+
+const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+
+/* Table of the number of extra bytes, indexed by the first byte masked with
+0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
+
+const pcre_uint8 PRIV(utf8_table4)[] = {
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
+
+#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/
+
+#ifdef SUPPORT_UTF
+
+/* Table to translate from particular type value to the general value. */
+
+const int PRIV(ucp_gentype)[] = {
+ ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
+ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
+ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
+ ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
+ ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
+ ucp_P, ucp_P, /* Ps, Po */
+ ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
+ ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
+};
+
+#ifdef SUPPORT_JIT
+/* This table reverses PRIV(ucp_gentype). We can save the cost
+of a memory load. */
+
+const int PRIV(ucp_typerange)[] = {
+ ucp_Cc, ucp_Cs,
+ ucp_Ll, ucp_Lu,
+ ucp_Mc, ucp_Mn,
+ ucp_Nd, ucp_No,
+ ucp_Pc, ucp_Ps,
+ ucp_Sc, ucp_So,
+ ucp_Zl, ucp_Zs,
+};
+#endif /* SUPPORT_JIT */
+
+/* The pcre_utt[] table below translates Unicode property names into type and
+code values. It is searched by binary chop, so must be in collating sequence of
+name. Originally, the table contained pointers to the name strings in the first
+field of each entry. However, that leads to a large number of relocations when
+a shared library is dynamically loaded. A significant reduction is made by
+putting all the names into a single, large string and then using offsets in the
+table itself. Maintenance is more error-prone, but frequent changes to this
+data are unlikely.
+
+July 2008: There is now a script called maint/GenerateUtt.py that can be used
+to generate this data automatically instead of maintaining it by hand.
+
+The script was updated in March 2009 to generate a new EBCDIC-compliant
+version. Like all other character and string literals that are compared against
+the regular expression pattern, we must use STR_ macros instead of literal
+strings to make sure that UTF-8 support works on EBCDIC platforms. */
+
+#define STRING_Any0 STR_A STR_n STR_y "\0"
+#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"
+#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
+#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
+#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
+#define STRING_Batak0 STR_B STR_a STR_t STR_a STR_k "\0"
+#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
+#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
+#define STRING_Brahmi0 STR_B STR_r STR_a STR_h STR_m STR_i "\0"
+#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
+#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
+#define STRING_C0 STR_C "\0"
+#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
+#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
+#define STRING_Cc0 STR_C STR_c "\0"
+#define STRING_Cf0 STR_C STR_f "\0"
+#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
+#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
+#define STRING_Cn0 STR_C STR_n "\0"
+#define STRING_Co0 STR_C STR_o "\0"
+#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
+#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"
+#define STRING_Cs0 STR_C STR_s "\0"
+#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
+#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"
+#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
+#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
+#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
+#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
+#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
+#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
+#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
+#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
+#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
+#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
+#define STRING_Han0 STR_H STR_a STR_n "\0"
+#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"
+#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"
+#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"
+#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
+#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"
+#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
+#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
+#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
+#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"
+#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"
+#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
+#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
+#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
+#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
+#define STRING_L0 STR_L "\0"
+#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
+#define STRING_Lao0 STR_L STR_a STR_o "\0"
+#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
+#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
+#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
+#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
+#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
+#define STRING_Ll0 STR_L STR_l "\0"
+#define STRING_Lm0 STR_L STR_m "\0"
+#define STRING_Lo0 STR_L STR_o "\0"
+#define STRING_Lt0 STR_L STR_t "\0"
+#define STRING_Lu0 STR_L STR_u "\0"
+#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
+#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
+#define STRING_M0 STR_M "\0"
+#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
+#define STRING_Mandaic0 STR_M STR_a STR_n STR_d STR_a STR_i STR_c "\0"
+#define STRING_Mc0 STR_M STR_c "\0"
+#define STRING_Me0 STR_M STR_e "\0"
+#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
+#define STRING_Mn0 STR_M STR_n "\0"
+#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
+#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
+#define STRING_N0 STR_N "\0"
+#define STRING_Nd0 STR_N STR_d "\0"
+#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
+#define STRING_Nko0 STR_N STR_k STR_o "\0"
+#define STRING_Nl0 STR_N STR_l "\0"
+#define STRING_No0 STR_N STR_o "\0"
+#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
+#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
+#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
+#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
+#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
+#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
+#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
+#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
+#define STRING_P0 STR_P "\0"
+#define STRING_Pc0 STR_P STR_c "\0"
+#define STRING_Pd0 STR_P STR_d "\0"
+#define STRING_Pe0 STR_P STR_e "\0"
+#define STRING_Pf0 STR_P STR_f "\0"
+#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"
+#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
+#define STRING_Pi0 STR_P STR_i "\0"
+#define STRING_Po0 STR_P STR_o "\0"
+#define STRING_Ps0 STR_P STR_s "\0"
+#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
+#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
+#define STRING_S0 STR_S "\0"
+#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
+#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
+#define STRING_Sc0 STR_S STR_c "\0"
+#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
+#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
+#define STRING_Sk0 STR_S STR_k "\0"
+#define STRING_Sm0 STR_S STR_m "\0"
+#define STRING_So0 STR_S STR_o "\0"
+#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
+#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
+#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"
+#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
+#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
+#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
+#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
+#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
+#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
+#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
+#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
+#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
+#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
+#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
+#define STRING_Vai0 STR_V STR_a STR_i "\0"
+#define STRING_Xan0 STR_X STR_a STR_n "\0"
+#define STRING_Xps0 STR_X STR_p STR_s "\0"
+#define STRING_Xsp0 STR_X STR_s STR_p "\0"
+#define STRING_Xwd0 STR_X STR_w STR_d "\0"
+#define STRING_Yi0 STR_Y STR_i "\0"
+#define STRING_Z0 STR_Z "\0"
+#define STRING_Zl0 STR_Z STR_l "\0"
+#define STRING_Zp0 STR_Z STR_p "\0"
+#define STRING_Zs0 STR_Z STR_s "\0"
+
+const char PRIV(utt_names)[] =
+ STRING_Any0
+ STRING_Arabic0
+ STRING_Armenian0
+ STRING_Avestan0
+ STRING_Balinese0
+ STRING_Bamum0
+ STRING_Batak0
+ STRING_Bengali0
+ STRING_Bopomofo0
+ STRING_Brahmi0
+ STRING_Braille0
+ STRING_Buginese0
+ STRING_Buhid0
+ STRING_C0
+ STRING_Canadian_Aboriginal0
+ STRING_Carian0
+ STRING_Cc0
+ STRING_Cf0
+ STRING_Cham0
+ STRING_Cherokee0
+ STRING_Cn0
+ STRING_Co0
+ STRING_Common0
+ STRING_Coptic0
+ STRING_Cs0
+ STRING_Cuneiform0
+ STRING_Cypriot0
+ STRING_Cyrillic0
+ STRING_Deseret0
+ STRING_Devanagari0
+ STRING_Egyptian_Hieroglyphs0
+ STRING_Ethiopic0
+ STRING_Georgian0
+ STRING_Glagolitic0
+ STRING_Gothic0
+ STRING_Greek0
+ STRING_Gujarati0
+ STRING_Gurmukhi0
+ STRING_Han0
+ STRING_Hangul0
+ STRING_Hanunoo0
+ STRING_Hebrew0
+ STRING_Hiragana0
+ STRING_Imperial_Aramaic0
+ STRING_Inherited0
+ STRING_Inscriptional_Pahlavi0
+ STRING_Inscriptional_Parthian0
+ STRING_Javanese0
+ STRING_Kaithi0
+ STRING_Kannada0
+ STRING_Katakana0
+ STRING_Kayah_Li0
+ STRING_Kharoshthi0
+ STRING_Khmer0
+ STRING_L0
+ STRING_L_AMPERSAND0
+ STRING_Lao0
+ STRING_Latin0
+ STRING_Lepcha0
+ STRING_Limbu0
+ STRING_Linear_B0
+ STRING_Lisu0
+ STRING_Ll0
+ STRING_Lm0
+ STRING_Lo0
+ STRING_Lt0
+ STRING_Lu0
+ STRING_Lycian0
+ STRING_Lydian0
+ STRING_M0
+ STRING_Malayalam0
+ STRING_Mandaic0
+ STRING_Mc0
+ STRING_Me0
+ STRING_Meetei_Mayek0
+ STRING_Mn0
+ STRING_Mongolian0
+ STRING_Myanmar0
+ STRING_N0
+ STRING_Nd0
+ STRING_New_Tai_Lue0
+ STRING_Nko0
+ STRING_Nl0
+ STRING_No0
+ STRING_Ogham0
+ STRING_Ol_Chiki0
+ STRING_Old_Italic0
+ STRING_Old_Persian0
+ STRING_Old_South_Arabian0
+ STRING_Old_Turkic0
+ STRING_Oriya0
+ STRING_Osmanya0
+ STRING_P0
+ STRING_Pc0
+ STRING_Pd0
+ STRING_Pe0
+ STRING_Pf0
+ STRING_Phags_Pa0
+ STRING_Phoenician0
+ STRING_Pi0
+ STRING_Po0
+ STRING_Ps0
+ STRING_Rejang0
+ STRING_Runic0
+ STRING_S0
+ STRING_Samaritan0
+ STRING_Saurashtra0
+ STRING_Sc0
+ STRING_Shavian0
+ STRING_Sinhala0
+ STRING_Sk0
+ STRING_Sm0
+ STRING_So0
+ STRING_Sundanese0
+ STRING_Syloti_Nagri0
+ STRING_Syriac0
+ STRING_Tagalog0
+ STRING_Tagbanwa0
+ STRING_Tai_Le0
+ STRING_Tai_Tham0
+ STRING_Tai_Viet0
+ STRING_Tamil0
+ STRING_Telugu0
+ STRING_Thaana0
+ STRING_Thai0
+ STRING_Tibetan0
+ STRING_Tifinagh0
+ STRING_Ugaritic0
+ STRING_Vai0
+ STRING_Xan0
+ STRING_Xps0
+ STRING_Xsp0
+ STRING_Xwd0
+ STRING_Yi0
+ STRING_Z0
+ STRING_Zl0
+ STRING_Zp0
+ STRING_Zs0;
+
+const ucp_type_table PRIV(utt)[] = {
+ { 0, PT_ANY, 0 },
+ { 4, PT_SC, ucp_Arabic },
+ { 11, PT_SC, ucp_Armenian },
+ { 20, PT_SC, ucp_Avestan },
+ { 28, PT_SC, ucp_Balinese },
+ { 37, PT_SC, ucp_Bamum },
+ { 43, PT_SC, ucp_Batak },
+ { 49, PT_SC, ucp_Bengali },
+ { 57, PT_SC, ucp_Bopomofo },
+ { 66, PT_SC, ucp_Brahmi },
+ { 73, PT_SC, ucp_Braille },
+ { 81, PT_SC, ucp_Buginese },
+ { 90, PT_SC, ucp_Buhid },
+ { 96, PT_GC, ucp_C },
+ { 98, PT_SC, ucp_Canadian_Aboriginal },
+ { 118, PT_SC, ucp_Carian },
+ { 125, PT_PC, ucp_Cc },
+ { 128, PT_PC, ucp_Cf },
+ { 131, PT_SC, ucp_Cham },
+ { 136, PT_SC, ucp_Cherokee },
+ { 145, PT_PC, ucp_Cn },
+ { 148, PT_PC, ucp_Co },
+ { 151, PT_SC, ucp_Common },
+ { 158, PT_SC, ucp_Coptic },
+ { 165, PT_PC, ucp_Cs },
+ { 168, PT_SC, ucp_Cuneiform },
+ { 178, PT_SC, ucp_Cypriot },
+ { 186, PT_SC, ucp_Cyrillic },
+ { 195, PT_SC, ucp_Deseret },
+ { 203, PT_SC, ucp_Devanagari },
+ { 214, PT_SC, ucp_Egyptian_Hieroglyphs },
+ { 235, PT_SC, ucp_Ethiopic },
+ { 244, PT_SC, ucp_Georgian },
+ { 253, PT_SC, ucp_Glagolitic },
+ { 264, PT_SC, ucp_Gothic },
+ { 271, PT_SC, ucp_Greek },
+ { 277, PT_SC, ucp_Gujarati },
+ { 286, PT_SC, ucp_Gurmukhi },
+ { 295, PT_SC, ucp_Han },
+ { 299, PT_SC, ucp_Hangul },
+ { 306, PT_SC, ucp_Hanunoo },
+ { 314, PT_SC, ucp_Hebrew },
+ { 321, PT_SC, ucp_Hiragana },
+ { 330, PT_SC, ucp_Imperial_Aramaic },
+ { 347, PT_SC, ucp_Inherited },
+ { 357, PT_SC, ucp_Inscriptional_Pahlavi },
+ { 379, PT_SC, ucp_Inscriptional_Parthian },
+ { 402, PT_SC, ucp_Javanese },
+ { 411, PT_SC, ucp_Kaithi },
+ { 418, PT_SC, ucp_Kannada },
+ { 426, PT_SC, ucp_Katakana },
+ { 435, PT_SC, ucp_Kayah_Li },
+ { 444, PT_SC, ucp_Kharoshthi },
+ { 455, PT_SC, ucp_Khmer },
+ { 461, PT_GC, ucp_L },
+ { 463, PT_LAMP, 0 },
+ { 466, PT_SC, ucp_Lao },
+ { 470, PT_SC, ucp_Latin },
+ { 476, PT_SC, ucp_Lepcha },
+ { 483, PT_SC, ucp_Limbu },
+ { 489, PT_SC, ucp_Linear_B },
+ { 498, PT_SC, ucp_Lisu },
+ { 503, PT_PC, ucp_Ll },
+ { 506, PT_PC, ucp_Lm },
+ { 509, PT_PC, ucp_Lo },
+ { 512, PT_PC, ucp_Lt },
+ { 515, PT_PC, ucp_Lu },
+ { 518, PT_SC, ucp_Lycian },
+ { 525, PT_SC, ucp_Lydian },
+ { 532, PT_GC, ucp_M },
+ { 534, PT_SC, ucp_Malayalam },
+ { 544, PT_SC, ucp_Mandaic },
+ { 552, PT_PC, ucp_Mc },
+ { 555, PT_PC, ucp_Me },
+ { 558, PT_SC, ucp_Meetei_Mayek },
+ { 571, PT_PC, ucp_Mn },
+ { 574, PT_SC, ucp_Mongolian },
+ { 584, PT_SC, ucp_Myanmar },
+ { 592, PT_GC, ucp_N },
+ { 594, PT_PC, ucp_Nd },
+ { 597, PT_SC, ucp_New_Tai_Lue },
+ { 609, PT_SC, ucp_Nko },
+ { 613, PT_PC, ucp_Nl },
+ { 616, PT_PC, ucp_No },
+ { 619, PT_SC, ucp_Ogham },
+ { 625, PT_SC, ucp_Ol_Chiki },
+ { 634, PT_SC, ucp_Old_Italic },
+ { 645, PT_SC, ucp_Old_Persian },
+ { 657, PT_SC, ucp_Old_South_Arabian },
+ { 675, PT_SC, ucp_Old_Turkic },
+ { 686, PT_SC, ucp_Oriya },
+ { 692, PT_SC, ucp_Osmanya },
+ { 700, PT_GC, ucp_P },
+ { 702, PT_PC, ucp_Pc },
+ { 705, PT_PC, ucp_Pd },
+ { 708, PT_PC, ucp_Pe },
+ { 711, PT_PC, ucp_Pf },
+ { 714, PT_SC, ucp_Phags_Pa },
+ { 723, PT_SC, ucp_Phoenician },
+ { 734, PT_PC, ucp_Pi },
+ { 737, PT_PC, ucp_Po },
+ { 740, PT_PC, ucp_Ps },
+ { 743, PT_SC, ucp_Rejang },
+ { 750, PT_SC, ucp_Runic },
+ { 756, PT_GC, ucp_S },
+ { 758, PT_SC, ucp_Samaritan },
+ { 768, PT_SC, ucp_Saurashtra },
+ { 779, PT_PC, ucp_Sc },
+ { 782, PT_SC, ucp_Shavian },
+ { 790, PT_SC, ucp_Sinhala },
+ { 798, PT_PC, ucp_Sk },
+ { 801, PT_PC, ucp_Sm },
+ { 804, PT_PC, ucp_So },
+ { 807, PT_SC, ucp_Sundanese },
+ { 817, PT_SC, ucp_Syloti_Nagri },
+ { 830, PT_SC, ucp_Syriac },
+ { 837, PT_SC, ucp_Tagalog },
+ { 845, PT_SC, ucp_Tagbanwa },
+ { 854, PT_SC, ucp_Tai_Le },
+ { 861, PT_SC, ucp_Tai_Tham },
+ { 870, PT_SC, ucp_Tai_Viet },
+ { 879, PT_SC, ucp_Tamil },
+ { 885, PT_SC, ucp_Telugu },
+ { 892, PT_SC, ucp_Thaana },
+ { 899, PT_SC, ucp_Thai },
+ { 904, PT_SC, ucp_Tibetan },
+ { 912, PT_SC, ucp_Tifinagh },
+ { 921, PT_SC, ucp_Ugaritic },
+ { 930, PT_SC, ucp_Vai },
+ { 934, PT_ALNUM, 0 },
+ { 938, PT_PXSPACE, 0 },
+ { 942, PT_SPACE, 0 },
+ { 946, PT_WORD, 0 },
+ { 950, PT_SC, ucp_Yi },
+ { 953, PT_GC, ucp_Z },
+ { 955, PT_PC, ucp_Zl },
+ { 958, PT_PC, ucp_Zp },
+ { 961, PT_PC, ucp_Zs }
+};
+
+const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
+
+#endif /* SUPPORT_UTF */
+
+/* End of pcre_tables.c */
diff --git a/src/3rdparty/pcre/pcre_ucd.c b/src/3rdparty/pcre/pcre_ucd.c
new file mode 100644
index 00000000000..48fa4866358
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_ucd.c
@@ -0,0 +1,2981 @@
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+/* Unicode character database. */
+/* This file was autogenerated by the MultiStage2.py script. */
+/* Total size: 60384 bytes, block size: 128. */
+
+/* The tables herein are needed only when UCP support is built */
+/* into PCRE. This module should not be referenced otherwise, so */
+/* it should not matter whether it is compiled or not. However */
+/* a comment was received about space saving - maybe the guy linked */
+/* all the modules rather than using a library - so we include a */
+/* condition to cut out the tables when not needed. But don't leave */
+/* a totally empty module because some compilers barf at that. */
+/* Instead, just supply small dummy tables. */
+
+#ifndef SUPPORT_UCP
+const ucd_record PRIV(ucd_records)[] = {{0,0,0 }};
+const pcre_uint8 PRIV(ucd_stage1)[] = {0};
+const pcre_uint16 PRIV(ucd_stage2)[] = {0};
+#else
+
+/* When recompiling tables with a new Unicode version,
+please check types in the structure definition from pcre_internal.h:
+typedef struct {
+pcre_uint8 property_0;
+pcre_uint8 property_1;
+pcre_int32 property_2;
+} ucd_record; */
+
+
+const ucd_record PRIV(ucd_records)[] = { /* 4320 bytes, record size 8 */
+ { 9, 0, 0, }, /* 0 */
+ { 9, 29, 0, }, /* 1 */
+ { 9, 21, 0, }, /* 2 */
+ { 9, 23, 0, }, /* 3 */
+ { 9, 22, 0, }, /* 4 */
+ { 9, 18, 0, }, /* 5 */
+ { 9, 25, 0, }, /* 6 */
+ { 9, 17, 0, }, /* 7 */
+ { 9, 13, 0, }, /* 8 */
+ { 33, 9, 32, }, /* 9 */
+ { 9, 24, 0, }, /* 10 */
+ { 9, 16, 0, }, /* 11 */
+ { 33, 5, -32, }, /* 12 */
+ { 9, 26, 0, }, /* 13 */
+ { 33, 5, 0, }, /* 14 */
+ { 9, 20, 0, }, /* 15 */
+ { 9, 1, 0, }, /* 16 */
+ { 9, 15, 0, }, /* 17 */
+ { 9, 5, 743, }, /* 18 */
+ { 9, 19, 0, }, /* 19 */
+ { 33, 5, 121, }, /* 20 */
+ { 33, 9, 1, }, /* 21 */
+ { 33, 5, -1, }, /* 22 */
+ { 33, 9, -199, }, /* 23 */
+ { 33, 5, -232, }, /* 24 */
+ { 33, 9, -121, }, /* 25 */
+ { 33, 5, -300, }, /* 26 */
+ { 33, 5, 195, }, /* 27 */
+ { 33, 9, 210, }, /* 28 */
+ { 33, 9, 206, }, /* 29 */
+ { 33, 9, 205, }, /* 30 */
+ { 33, 9, 79, }, /* 31 */
+ { 33, 9, 202, }, /* 32 */
+ { 33, 9, 203, }, /* 33 */
+ { 33, 9, 207, }, /* 34 */
+ { 33, 5, 97, }, /* 35 */
+ { 33, 9, 211, }, /* 36 */
+ { 33, 9, 209, }, /* 37 */
+ { 33, 5, 163, }, /* 38 */
+ { 33, 9, 213, }, /* 39 */
+ { 33, 5, 130, }, /* 40 */
+ { 33, 9, 214, }, /* 41 */
+ { 33, 9, 218, }, /* 42 */
+ { 33, 9, 217, }, /* 43 */
+ { 33, 9, 219, }, /* 44 */
+ { 33, 7, 0, }, /* 45 */
+ { 33, 5, 56, }, /* 46 */
+ { 33, 9, 2, }, /* 47 */
+ { 33, 8, -1, }, /* 48 */
+ { 33, 5, -2, }, /* 49 */
+ { 33, 5, -79, }, /* 50 */
+ { 33, 9, -97, }, /* 51 */
+ { 33, 9, -56, }, /* 52 */
+ { 33, 9, -130, }, /* 53 */
+ { 33, 9, 10795, }, /* 54 */
+ { 33, 9, -163, }, /* 55 */
+ { 33, 9, 10792, }, /* 56 */
+ { 33, 5, 10815, }, /* 57 */
+ { 33, 9, -195, }, /* 58 */
+ { 33, 9, 69, }, /* 59 */
+ { 33, 9, 71, }, /* 60 */
+ { 33, 5, 10783, }, /* 61 */
+ { 33, 5, 10780, }, /* 62 */
+ { 33, 5, 10782, }, /* 63 */
+ { 33, 5, -210, }, /* 64 */
+ { 33, 5, -206, }, /* 65 */
+ { 33, 5, -205, }, /* 66 */
+ { 33, 5, -202, }, /* 67 */
+ { 33, 5, -203, }, /* 68 */
+ { 33, 5, -207, }, /* 69 */
+ { 33, 5, 42280, }, /* 70 */
+ { 33, 5, -209, }, /* 71 */
+ { 33, 5, -211, }, /* 72 */
+ { 33, 5, 10743, }, /* 73 */
+ { 33, 5, 10749, }, /* 74 */
+ { 33, 5, -213, }, /* 75 */
+ { 33, 5, -214, }, /* 76 */
+ { 33, 5, 10727, }, /* 77 */
+ { 33, 5, -218, }, /* 78 */
+ { 33, 5, -69, }, /* 79 */
+ { 33, 5, -217, }, /* 80 */
+ { 33, 5, -71, }, /* 81 */
+ { 33, 5, -219, }, /* 82 */
+ { 33, 6, 0, }, /* 83 */
+ { 9, 6, 0, }, /* 84 */
+ { 3, 24, 0, }, /* 85 */
+ { 27, 12, 0, }, /* 86 */
+ { 27, 12, 84, }, /* 87 */
+ { 19, 9, 1, }, /* 88 */
+ { 19, 5, -1, }, /* 89 */
+ { 19, 24, 0, }, /* 90 */
+ { 9, 2, 0, }, /* 91 */
+ { 19, 6, 0, }, /* 92 */
+ { 19, 5, 130, }, /* 93 */
+ { 19, 9, 38, }, /* 94 */
+ { 19, 9, 37, }, /* 95 */
+ { 19, 9, 64, }, /* 96 */
+ { 19, 9, 63, }, /* 97 */
+ { 19, 5, 0, }, /* 98 */
+ { 19, 9, 32, }, /* 99 */
+ { 19, 5, -38, }, /* 100 */
+ { 19, 5, -37, }, /* 101 */
+ { 19, 5, -32, }, /* 102 */
+ { 19, 5, -31, }, /* 103 */
+ { 19, 5, -64, }, /* 104 */
+ { 19, 5, -63, }, /* 105 */
+ { 19, 9, 8, }, /* 106 */
+ { 19, 5, -62, }, /* 107 */
+ { 19, 5, -57, }, /* 108 */
+ { 19, 9, 0, }, /* 109 */
+ { 19, 5, -47, }, /* 110 */
+ { 19, 5, -54, }, /* 111 */
+ { 19, 5, -8, }, /* 112 */
+ { 10, 9, 1, }, /* 113 */
+ { 10, 5, -1, }, /* 114 */
+ { 19, 5, -86, }, /* 115 */
+ { 19, 5, -80, }, /* 116 */
+ { 19, 5, 7, }, /* 117 */
+ { 19, 9, -60, }, /* 118 */
+ { 19, 5, -96, }, /* 119 */
+ { 19, 25, 0, }, /* 120 */
+ { 19, 9, -7, }, /* 121 */
+ { 19, 9, -130, }, /* 122 */
+ { 12, 9, 80, }, /* 123 */
+ { 12, 9, 32, }, /* 124 */
+ { 12, 5, -32, }, /* 125 */
+ { 12, 5, -80, }, /* 126 */
+ { 12, 9, 1, }, /* 127 */
+ { 12, 5, -1, }, /* 128 */
+ { 12, 26, 0, }, /* 129 */
+ { 12, 12, 0, }, /* 130 */
+ { 12, 11, 0, }, /* 131 */
+ { 12, 9, 15, }, /* 132 */
+ { 12, 5, -15, }, /* 133 */
+ { 1, 9, 48, }, /* 134 */
+ { 1, 6, 0, }, /* 135 */
+ { 1, 21, 0, }, /* 136 */
+ { 1, 5, -48, }, /* 137 */
+ { 1, 5, 0, }, /* 138 */
+ { 1, 17, 0, }, /* 139 */
+ { 25, 12, 0, }, /* 140 */
+ { 25, 17, 0, }, /* 141 */
+ { 25, 21, 0, }, /* 142 */
+ { 25, 7, 0, }, /* 143 */
+ { 0, 1, 0, }, /* 144 */
+ { 0, 25, 0, }, /* 145 */
+ { 0, 21, 0, }, /* 146 */
+ { 0, 23, 0, }, /* 147 */
+ { 0, 26, 0, }, /* 148 */
+ { 0, 12, 0, }, /* 149 */
+ { 0, 7, 0, }, /* 150 */
+ { 0, 6, 0, }, /* 151 */
+ { 0, 13, 0, }, /* 152 */
+ { 49, 21, 0, }, /* 153 */
+ { 49, 1, 0, }, /* 154 */
+ { 49, 7, 0, }, /* 155 */
+ { 49, 12, 0, }, /* 156 */
+ { 55, 7, 0, }, /* 157 */
+ { 55, 12, 0, }, /* 158 */
+ { 63, 13, 0, }, /* 159 */
+ { 63, 7, 0, }, /* 160 */
+ { 63, 12, 0, }, /* 161 */
+ { 63, 6, 0, }, /* 162 */
+ { 63, 26, 0, }, /* 163 */
+ { 63, 21, 0, }, /* 164 */
+ { 89, 7, 0, }, /* 165 */
+ { 89, 12, 0, }, /* 166 */
+ { 89, 6, 0, }, /* 167 */
+ { 89, 21, 0, }, /* 168 */
+ { 94, 7, 0, }, /* 169 */
+ { 94, 12, 0, }, /* 170 */
+ { 94, 21, 0, }, /* 171 */
+ { 14, 12, 0, }, /* 172 */
+ { 14, 10, 0, }, /* 173 */
+ { 14, 7, 0, }, /* 174 */
+ { 14, 13, 0, }, /* 175 */
+ { 14, 6, 0, }, /* 176 */
+ { 2, 12, 0, }, /* 177 */
+ { 2, 10, 0, }, /* 178 */
+ { 2, 7, 0, }, /* 179 */
+ { 2, 13, 0, }, /* 180 */
+ { 2, 23, 0, }, /* 181 */
+ { 2, 15, 0, }, /* 182 */
+ { 2, 26, 0, }, /* 183 */
+ { 21, 12, 0, }, /* 184 */
+ { 21, 10, 0, }, /* 185 */
+ { 21, 7, 0, }, /* 186 */
+ { 21, 13, 0, }, /* 187 */
+ { 20, 12, 0, }, /* 188 */
+ { 20, 10, 0, }, /* 189 */
+ { 20, 7, 0, }, /* 190 */
+ { 20, 13, 0, }, /* 191 */
+ { 20, 23, 0, }, /* 192 */
+ { 43, 12, 0, }, /* 193 */
+ { 43, 10, 0, }, /* 194 */
+ { 43, 7, 0, }, /* 195 */
+ { 43, 13, 0, }, /* 196 */
+ { 43, 26, 0, }, /* 197 */
+ { 43, 15, 0, }, /* 198 */
+ { 53, 12, 0, }, /* 199 */
+ { 53, 7, 0, }, /* 200 */
+ { 53, 10, 0, }, /* 201 */
+ { 53, 13, 0, }, /* 202 */
+ { 53, 15, 0, }, /* 203 */
+ { 53, 26, 0, }, /* 204 */
+ { 53, 23, 0, }, /* 205 */
+ { 54, 10, 0, }, /* 206 */
+ { 54, 7, 0, }, /* 207 */
+ { 54, 12, 0, }, /* 208 */
+ { 54, 13, 0, }, /* 209 */
+ { 54, 15, 0, }, /* 210 */
+ { 54, 26, 0, }, /* 211 */
+ { 28, 10, 0, }, /* 212 */
+ { 28, 7, 0, }, /* 213 */
+ { 28, 12, 0, }, /* 214 */
+ { 28, 13, 0, }, /* 215 */
+ { 36, 10, 0, }, /* 216 */
+ { 36, 7, 0, }, /* 217 */
+ { 36, 12, 0, }, /* 218 */
+ { 36, 13, 0, }, /* 219 */
+ { 36, 15, 0, }, /* 220 */
+ { 36, 26, 0, }, /* 221 */
+ { 47, 10, 0, }, /* 222 */
+ { 47, 7, 0, }, /* 223 */
+ { 47, 12, 0, }, /* 224 */
+ { 47, 21, 0, }, /* 225 */
+ { 56, 7, 0, }, /* 226 */
+ { 56, 12, 0, }, /* 227 */
+ { 56, 6, 0, }, /* 228 */
+ { 56, 21, 0, }, /* 229 */
+ { 56, 13, 0, }, /* 230 */
+ { 32, 7, 0, }, /* 231 */
+ { 32, 12, 0, }, /* 232 */
+ { 32, 6, 0, }, /* 233 */
+ { 32, 13, 0, }, /* 234 */
+ { 57, 7, 0, }, /* 235 */
+ { 57, 26, 0, }, /* 236 */
+ { 57, 21, 0, }, /* 237 */
+ { 57, 12, 0, }, /* 238 */
+ { 57, 13, 0, }, /* 239 */
+ { 57, 15, 0, }, /* 240 */
+ { 57, 22, 0, }, /* 241 */
+ { 57, 18, 0, }, /* 242 */
+ { 57, 10, 0, }, /* 243 */
+ { 38, 7, 0, }, /* 244 */
+ { 38, 10, 0, }, /* 245 */
+ { 38, 12, 0, }, /* 246 */
+ { 38, 13, 0, }, /* 247 */
+ { 38, 21, 0, }, /* 248 */
+ { 38, 26, 0, }, /* 249 */
+ { 16, 9, 7264, }, /* 250 */
+ { 16, 7, 0, }, /* 251 */
+ { 16, 6, 0, }, /* 252 */
+ { 23, 7, 0, }, /* 253 */
+ { 15, 7, 0, }, /* 254 */
+ { 15, 12, 0, }, /* 255 */
+ { 15, 26, 0, }, /* 256 */
+ { 15, 21, 0, }, /* 257 */
+ { 15, 15, 0, }, /* 258 */
+ { 8, 7, 0, }, /* 259 */
+ { 7, 17, 0, }, /* 260 */
+ { 7, 7, 0, }, /* 261 */
+ { 7, 21, 0, }, /* 262 */
+ { 40, 29, 0, }, /* 263 */
+ { 40, 7, 0, }, /* 264 */
+ { 40, 22, 0, }, /* 265 */
+ { 40, 18, 0, }, /* 266 */
+ { 45, 7, 0, }, /* 267 */
+ { 45, 14, 0, }, /* 268 */
+ { 50, 7, 0, }, /* 269 */
+ { 50, 12, 0, }, /* 270 */
+ { 24, 7, 0, }, /* 271 */
+ { 24, 12, 0, }, /* 272 */
+ { 6, 7, 0, }, /* 273 */
+ { 6, 12, 0, }, /* 274 */
+ { 51, 7, 0, }, /* 275 */
+ { 51, 12, 0, }, /* 276 */
+ { 31, 7, 0, }, /* 277 */
+ { 31, 1, 0, }, /* 278 */
+ { 31, 10, 0, }, /* 279 */
+ { 31, 12, 0, }, /* 280 */
+ { 31, 21, 0, }, /* 281 */
+ { 31, 6, 0, }, /* 282 */
+ { 31, 23, 0, }, /* 283 */
+ { 31, 13, 0, }, /* 284 */
+ { 31, 15, 0, }, /* 285 */
+ { 37, 21, 0, }, /* 286 */
+ { 37, 17, 0, }, /* 287 */
+ { 37, 12, 0, }, /* 288 */
+ { 37, 29, 0, }, /* 289 */
+ { 37, 13, 0, }, /* 290 */
+ { 37, 7, 0, }, /* 291 */
+ { 37, 6, 0, }, /* 292 */
+ { 34, 7, 0, }, /* 293 */
+ { 34, 12, 0, }, /* 294 */
+ { 34, 10, 0, }, /* 295 */
+ { 34, 26, 0, }, /* 296 */
+ { 34, 21, 0, }, /* 297 */
+ { 34, 13, 0, }, /* 298 */
+ { 52, 7, 0, }, /* 299 */
+ { 39, 7, 0, }, /* 300 */
+ { 39, 10, 0, }, /* 301 */
+ { 39, 13, 0, }, /* 302 */
+ { 39, 15, 0, }, /* 303 */
+ { 39, 26, 0, }, /* 304 */
+ { 31, 26, 0, }, /* 305 */
+ { 5, 7, 0, }, /* 306 */
+ { 5, 12, 0, }, /* 307 */
+ { 5, 10, 0, }, /* 308 */
+ { 5, 21, 0, }, /* 309 */
+ { 90, 7, 0, }, /* 310 */
+ { 90, 10, 0, }, /* 311 */
+ { 90, 12, 0, }, /* 312 */
+ { 90, 13, 0, }, /* 313 */
+ { 90, 21, 0, }, /* 314 */
+ { 90, 6, 0, }, /* 315 */
+ { 61, 12, 0, }, /* 316 */
+ { 61, 10, 0, }, /* 317 */
+ { 61, 7, 0, }, /* 318 */
+ { 61, 13, 0, }, /* 319 */
+ { 61, 21, 0, }, /* 320 */
+ { 61, 26, 0, }, /* 321 */
+ { 75, 12, 0, }, /* 322 */
+ { 75, 10, 0, }, /* 323 */
+ { 75, 7, 0, }, /* 324 */
+ { 75, 13, 0, }, /* 325 */
+ { 92, 7, 0, }, /* 326 */
+ { 92, 12, 0, }, /* 327 */
+ { 92, 10, 0, }, /* 328 */
+ { 92, 21, 0, }, /* 329 */
+ { 69, 7, 0, }, /* 330 */
+ { 69, 10, 0, }, /* 331 */
+ { 69, 12, 0, }, /* 332 */
+ { 69, 21, 0, }, /* 333 */
+ { 69, 13, 0, }, /* 334 */
+ { 72, 13, 0, }, /* 335 */
+ { 72, 7, 0, }, /* 336 */
+ { 72, 6, 0, }, /* 337 */
+ { 72, 21, 0, }, /* 338 */
+ { 9, 10, 0, }, /* 339 */
+ { 9, 7, 0, }, /* 340 */
+ { 12, 5, 0, }, /* 341 */
+ { 12, 6, 0, }, /* 342 */
+ { 33, 5, 35332, }, /* 343 */
+ { 33, 5, 3814, }, /* 344 */
+ { 33, 5, -59, }, /* 345 */
+ { 33, 9, -7615, }, /* 346 */
+ { 19, 5, 8, }, /* 347 */
+ { 19, 9, -8, }, /* 348 */
+ { 19, 5, 74, }, /* 349 */
+ { 19, 5, 86, }, /* 350 */
+ { 19, 5, 100, }, /* 351 */
+ { 19, 5, 128, }, /* 352 */
+ { 19, 5, 112, }, /* 353 */
+ { 19, 5, 126, }, /* 354 */
+ { 19, 8, -8, }, /* 355 */
+ { 19, 5, 9, }, /* 356 */
+ { 19, 9, -74, }, /* 357 */
+ { 19, 8, -9, }, /* 358 */
+ { 19, 5, -7205, }, /* 359 */
+ { 19, 9, -86, }, /* 360 */
+ { 19, 9, -100, }, /* 361 */
+ { 19, 9, -112, }, /* 362 */
+ { 19, 9, -128, }, /* 363 */
+ { 19, 9, -126, }, /* 364 */
+ { 27, 1, 0, }, /* 365 */
+ { 9, 27, 0, }, /* 366 */
+ { 9, 28, 0, }, /* 367 */
+ { 27, 11, 0, }, /* 368 */
+ { 9, 9, 0, }, /* 369 */
+ { 9, 5, 0, }, /* 370 */
+ { 19, 9, -7517, }, /* 371 */
+ { 33, 9, -8383, }, /* 372 */
+ { 33, 9, -8262, }, /* 373 */
+ { 33, 9, 28, }, /* 374 */
+ { 33, 5, -28, }, /* 375 */
+ { 33, 14, 16, }, /* 376 */
+ { 33, 14, -16, }, /* 377 */
+ { 33, 14, 0, }, /* 378 */
+ { 9, 26, 26, }, /* 379 */
+ { 9, 26, -26, }, /* 380 */
+ { 4, 26, 0, }, /* 381 */
+ { 17, 9, 48, }, /* 382 */
+ { 17, 5, -48, }, /* 383 */
+ { 33, 9, -10743, }, /* 384 */
+ { 33, 9, -3814, }, /* 385 */
+ { 33, 9, -10727, }, /* 386 */
+ { 33, 5, -10795, }, /* 387 */
+ { 33, 5, -10792, }, /* 388 */
+ { 33, 9, -10780, }, /* 389 */
+ { 33, 9, -10749, }, /* 390 */
+ { 33, 9, -10783, }, /* 391 */
+ { 33, 9, -10782, }, /* 392 */
+ { 33, 9, -10815, }, /* 393 */
+ { 10, 5, 0, }, /* 394 */
+ { 10, 26, 0, }, /* 395 */
+ { 10, 12, 0, }, /* 396 */
+ { 10, 21, 0, }, /* 397 */
+ { 10, 15, 0, }, /* 398 */
+ { 16, 5, -7264, }, /* 399 */
+ { 58, 7, 0, }, /* 400 */
+ { 58, 6, 0, }, /* 401 */
+ { 58, 21, 0, }, /* 402 */
+ { 58, 12, 0, }, /* 403 */
+ { 22, 26, 0, }, /* 404 */
+ { 22, 6, 0, }, /* 405 */
+ { 22, 14, 0, }, /* 406 */
+ { 23, 12, 0, }, /* 407 */
+ { 26, 7, 0, }, /* 408 */
+ { 26, 6, 0, }, /* 409 */
+ { 29, 7, 0, }, /* 410 */
+ { 29, 6, 0, }, /* 411 */
+ { 3, 7, 0, }, /* 412 */
+ { 23, 26, 0, }, /* 413 */
+ { 29, 26, 0, }, /* 414 */
+ { 22, 7, 0, }, /* 415 */
+ { 60, 7, 0, }, /* 416 */
+ { 60, 6, 0, }, /* 417 */
+ { 60, 26, 0, }, /* 418 */
+ { 85, 7, 0, }, /* 419 */
+ { 85, 6, 0, }, /* 420 */
+ { 85, 21, 0, }, /* 421 */
+ { 76, 7, 0, }, /* 422 */
+ { 76, 6, 0, }, /* 423 */
+ { 76, 21, 0, }, /* 424 */
+ { 76, 13, 0, }, /* 425 */
+ { 12, 7, 0, }, /* 426 */
+ { 12, 21, 0, }, /* 427 */
+ { 78, 7, 0, }, /* 428 */
+ { 78, 14, 0, }, /* 429 */
+ { 78, 12, 0, }, /* 430 */
+ { 78, 21, 0, }, /* 431 */
+ { 33, 9, -35332, }, /* 432 */
+ { 33, 9, -42280, }, /* 433 */
+ { 48, 7, 0, }, /* 434 */
+ { 48, 12, 0, }, /* 435 */
+ { 48, 10, 0, }, /* 436 */
+ { 48, 26, 0, }, /* 437 */
+ { 64, 7, 0, }, /* 438 */
+ { 64, 21, 0, }, /* 439 */
+ { 74, 10, 0, }, /* 440 */
+ { 74, 7, 0, }, /* 441 */
+ { 74, 12, 0, }, /* 442 */
+ { 74, 21, 0, }, /* 443 */
+ { 74, 13, 0, }, /* 444 */
+ { 14, 21, 0, }, /* 445 */
+ { 68, 13, 0, }, /* 446 */
+ { 68, 7, 0, }, /* 447 */
+ { 68, 12, 0, }, /* 448 */
+ { 68, 21, 0, }, /* 449 */
+ { 73, 7, 0, }, /* 450 */
+ { 73, 12, 0, }, /* 451 */
+ { 73, 10, 0, }, /* 452 */
+ { 73, 21, 0, }, /* 453 */
+ { 83, 12, 0, }, /* 454 */
+ { 83, 10, 0, }, /* 455 */
+ { 83, 7, 0, }, /* 456 */
+ { 83, 21, 0, }, /* 457 */
+ { 83, 6, 0, }, /* 458 */
+ { 83, 13, 0, }, /* 459 */
+ { 67, 7, 0, }, /* 460 */
+ { 67, 12, 0, }, /* 461 */
+ { 67, 10, 0, }, /* 462 */
+ { 67, 13, 0, }, /* 463 */
+ { 67, 21, 0, }, /* 464 */
+ { 38, 6, 0, }, /* 465 */
+ { 91, 7, 0, }, /* 466 */
+ { 91, 12, 0, }, /* 467 */
+ { 91, 6, 0, }, /* 468 */
+ { 91, 21, 0, }, /* 469 */
+ { 86, 7, 0, }, /* 470 */
+ { 86, 10, 0, }, /* 471 */
+ { 86, 12, 0, }, /* 472 */
+ { 86, 21, 0, }, /* 473 */
+ { 86, 13, 0, }, /* 474 */
+ { 9, 4, 0, }, /* 475 */
+ { 9, 3, 0, }, /* 476 */
+ { 25, 25, 0, }, /* 477 */
+ { 0, 24, 0, }, /* 478 */
+ { 35, 7, 0, }, /* 479 */
+ { 19, 14, 0, }, /* 480 */
+ { 19, 15, 0, }, /* 481 */
+ { 19, 26, 0, }, /* 482 */
+ { 70, 7, 0, }, /* 483 */
+ { 66, 7, 0, }, /* 484 */
+ { 41, 7, 0, }, /* 485 */
+ { 41, 15, 0, }, /* 486 */
+ { 18, 7, 0, }, /* 487 */
+ { 18, 14, 0, }, /* 488 */
+ { 59, 7, 0, }, /* 489 */
+ { 59, 21, 0, }, /* 490 */
+ { 42, 7, 0, }, /* 491 */
+ { 42, 21, 0, }, /* 492 */
+ { 42, 14, 0, }, /* 493 */
+ { 13, 9, 40, }, /* 494 */
+ { 13, 5, -40, }, /* 495 */
+ { 46, 7, 0, }, /* 496 */
+ { 44, 7, 0, }, /* 497 */
+ { 44, 13, 0, }, /* 498 */
+ { 11, 7, 0, }, /* 499 */
+ { 80, 7, 0, }, /* 500 */
+ { 80, 21, 0, }, /* 501 */
+ { 80, 15, 0, }, /* 502 */
+ { 65, 7, 0, }, /* 503 */
+ { 65, 15, 0, }, /* 504 */
+ { 65, 21, 0, }, /* 505 */
+ { 71, 7, 0, }, /* 506 */
+ { 71, 21, 0, }, /* 507 */
+ { 30, 7, 0, }, /* 508 */
+ { 30, 12, 0, }, /* 509 */
+ { 30, 15, 0, }, /* 510 */
+ { 30, 21, 0, }, /* 511 */
+ { 87, 7, 0, }, /* 512 */
+ { 87, 15, 0, }, /* 513 */
+ { 87, 21, 0, }, /* 514 */
+ { 77, 7, 0, }, /* 515 */
+ { 77, 21, 0, }, /* 516 */
+ { 82, 7, 0, }, /* 517 */
+ { 82, 15, 0, }, /* 518 */
+ { 81, 7, 0, }, /* 519 */
+ { 81, 15, 0, }, /* 520 */
+ { 88, 7, 0, }, /* 521 */
+ { 0, 15, 0, }, /* 522 */
+ { 93, 10, 0, }, /* 523 */
+ { 93, 12, 0, }, /* 524 */
+ { 93, 7, 0, }, /* 525 */
+ { 93, 21, 0, }, /* 526 */
+ { 93, 15, 0, }, /* 527 */
+ { 93, 13, 0, }, /* 528 */
+ { 84, 12, 0, }, /* 529 */
+ { 84, 10, 0, }, /* 530 */
+ { 84, 7, 0, }, /* 531 */
+ { 84, 21, 0, }, /* 532 */
+ { 84, 1, 0, }, /* 533 */
+ { 62, 7, 0, }, /* 534 */
+ { 62, 14, 0, }, /* 535 */
+ { 62, 21, 0, }, /* 536 */
+ { 79, 7, 0, }, /* 537 */
+ { 19, 12, 0, }, /* 538 */
+ { 26, 26, 0, }, /* 539 */
+};
+
+const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* U+0000 */
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* U+0800 */
+ 32, 33, 34, 34, 35, 36, 37, 38, 39, 40, 40, 40, 41, 42, 43, 44, /* U+1000 */
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, /* U+1800 */
+ 61, 62, 63, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 70, 73, 74, /* U+2000 */
+ 75, 75, 65, 76, 65, 65, 77, 17, 78, 79, 80, 81, 82, 83, 84, 85, /* U+2800 */
+ 86, 87, 88, 89, 90, 91, 92, 70, 93, 93, 93, 93, 93, 93, 93, 93, /* U+3000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+3800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+4000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, /* U+4800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+5000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+5800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+6000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+6800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+7000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+7800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+8000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+8800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+9000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 95, /* U+9800 */
+ 96, 97, 97, 97, 97, 97, 97, 97, 97, 98, 99, 99,100,101,102,103, /* U+A000 */
+104,105,106,107,108,109,110,111, 34, 34, 34, 34, 34, 34, 34, 34, /* U+A800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B000 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+B800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C000 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, /* U+C800 */
+ 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,112, /* U+D000 */
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, /* U+D800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+E800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F000 */
+114,114, 93, 93,115,116,117,118,119,119,120,121,122,123,124,125, /* U+F800 */
+126,127,128,129, 17,130,131,132,133,134, 17, 17, 17, 17, 17, 17, /* U+10000 */
+135, 17,136, 17,137, 17,138, 17,139, 17, 17, 17,140, 17, 17, 17, /* U+10800 */
+141,142, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+11800 */
+143,143,143,143,143,143,144, 17,145, 17, 17, 17, 17, 17, 17, 17, /* U+12000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+12800 */
+146,146,146,146,146,146,146,146,147, 17, 17, 17, 17, 17, 17, 17, /* U+13000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+13800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+14800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+15800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16000 */
+148,148,148,148,149, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+16800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+17800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+18800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+19800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1A800 */
+150, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1C800 */
+ 70,151,152,153,154, 17,155, 17,156,157,158,159,160,161,162,163, /* U+1D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1E800 */
+164,165,166,167,168, 17,169,170,171,172,173,174,175,176,177, 17, /* U+1F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+1F800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+20000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+20800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+21000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+21800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+22000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+22800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+23000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+23800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+24000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+24800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+25000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+25800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+26000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+26800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+27000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+27800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+28000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+28800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+29000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+29800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,178, 93, 93, /* U+2A000 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, /* U+2A800 */
+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,179, 93, /* U+2B000 */
+180, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F000 */
+ 93, 93, 93, 93,180, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+2F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+30800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+31800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+32800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+33800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+34800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+35800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+36800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+37800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+38800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+39800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+3F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+40800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+41800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+42800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+43800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+44800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+45800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+46800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+47800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+48800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+49800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+4F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+50800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+51800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+52800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+53800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+54800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+55800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+56800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+57800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+58800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+59800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+5F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+60800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+61800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+62800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+63800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+64800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+65800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+66800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+67800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+68800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+69800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+6F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+70800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+71800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+72800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+73800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+74800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+75800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+76800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+77800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+78800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+79800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+7F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+80800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+81800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+82800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+83800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+84800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+85800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+86800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+87800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+88800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+89800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+8F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+90800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+91800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+92800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+93800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+94800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+95800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+96800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+97800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+98800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+99800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9A800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9B800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9C800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9D800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9E800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+9F800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+A9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+AF800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+B9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+BF800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+C9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+CF800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+D9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DD800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+DF800 */
+181, 17,182,183, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E0800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E1800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E2800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E3800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E4800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E5800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E6800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E7800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E8800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+E9800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EA800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EB800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EC800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+ED800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EE800 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF000 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, /* U+EF800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F0800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F1800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F2800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F3800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F4800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F5800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F6800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F7800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F8800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+F9800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FA800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FB800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FC800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FD800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FE800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+FF000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,184, /* U+FF800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+100800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+101800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+102800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+103800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+104800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+105800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+106800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+107800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+108800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+109800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10A800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10B800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10C800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10D800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10E800 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114, /* U+10F000 */
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,184, /* U+10F800 */
+};
+
+const pcre_uint16 PRIV(ucd_stage2)[] = { /* 47360 bytes, block = 128 */
+/* block 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2,
+ 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11,
+ 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 0,
+
+/* block 1 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 3, 3, 3, 3, 13, 13, 10, 13, 14, 15, 6, 16, 13, 10,
+ 13, 6, 17, 17, 10, 18, 13, 2, 10, 17, 14, 19, 17, 17, 17, 2,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 9, 9, 9, 9, 14,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 6, 12, 12, 12, 12, 12, 12, 12, 20,
+
+/* block 2 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 23, 24, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22, 21,
+ 22, 21, 22, 21, 22, 21, 22, 21, 22, 14, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 25, 21, 22, 21, 22, 21, 22, 26,
+
+/* block 3 */
+ 27, 28, 21, 22, 21, 22, 29, 21, 22, 30, 30, 21, 22, 14, 31, 32,
+ 33, 21, 22, 30, 34, 35, 36, 37, 21, 22, 38, 14, 36, 39, 40, 41,
+ 21, 22, 21, 22, 21, 22, 42, 21, 22, 42, 14, 14, 21, 22, 42, 21,
+ 22, 43, 43, 21, 22, 21, 22, 44, 21, 22, 14, 45, 21, 22, 14, 46,
+ 45, 45, 45, 45, 47, 48, 49, 47, 48, 49, 47, 48, 49, 21, 22, 21,
+ 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 50, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 14, 47, 48, 49, 21, 22, 51, 52, 21, 22, 21, 22, 21, 22, 21, 22,
+
+/* block 4 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 53, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 14, 14, 14, 14, 14, 14, 54, 21, 22, 55, 56, 57,
+ 57, 21, 22, 58, 59, 60, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 61, 62, 63, 64, 65, 14, 66, 66, 14, 67, 14, 68, 14, 14, 14, 14,
+ 66, 14, 14, 69, 14, 70, 14, 14, 71, 72, 14, 73, 14, 14, 14, 72,
+ 14, 74, 75, 14, 14, 76, 14, 14, 14, 14, 14, 14, 14, 77, 14, 14,
+
+/* block 5 */
+ 78, 14, 14, 78, 14, 14, 14, 14, 78, 79, 80, 80, 81, 14, 14, 14,
+ 14, 14, 82, 14, 45, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 10, 10, 10, 10, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 84, 84, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 83, 83, 83, 83, 83, 10, 10, 10, 10, 10, 85, 85, 84, 10, 84, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+
+/* block 6 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 88, 89, 88, 89, 84, 90, 88, 89, 91, 91, 92, 93, 93, 93, 2, 91,
+
+/* block 7 */
+ 91, 91, 91, 91, 90, 10, 94, 2, 95, 95, 95, 91, 96, 91, 97, 97,
+ 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 91, 99, 99, 99, 99, 99, 99, 99, 99, 99,100,101,101,101,
+ 98,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,103,102,102,102,102,102,102,102,102,102,104,105,105,106,
+107,108,109,109,109,110,111,112, 88, 89, 88, 89, 88, 89, 88, 89,
+ 88, 89,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+115,116,117, 98,118,119,120, 88, 89,121, 88, 89, 98,122,122,122,
+
+/* block 8 */
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+
+/* block 9 */
+127,128,129,130,130, 86, 86,130,131,131,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+132,127,128,127,128,127,128,127,128,127,128,127,128,127,128,133,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+
+/* block 10 */
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134, 91, 91,135,136,136,136,136,136,136,
+ 91,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+
+/* block 11 */
+137,137,137,137,137,137,137,138, 91, 2,139, 91, 91, 91, 91, 91,
+ 91,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,141,140,
+142,140,140,142,140,140,142,140, 91, 91, 91, 91, 91, 91, 91, 91,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143, 91, 91, 91, 91, 91,
+143,143,143,142,142, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 12 */
+144,144,144,144, 91, 91,145,145,145,146,146,147, 2,146,148,148,
+149,149,149,149,149,149,149,149,149,149,149, 2, 91, 91,146, 2,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+ 84,150,150,150,150,150,150,150,150,150,150, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86,149,149,149,149,149,149,149,149,149, 86,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,146,146,146,146,150,150,
+ 86,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 13 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,146,150,149,149,149,149,149,149,149, 16,148,149,
+149,149,149,149,149,151,151,149,149,148,149,149,149,149,150,150,
+152,152,152,152,152,152,152,152,152,152,150,150,150,148,148,150,
+
+/* block 14 */
+153,153,153,153,153,153,153,153,153,153,153,153,153,153, 91,154,
+155,156,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156, 91, 91,155,155,155,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 15 */
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,158,158,158,158,158,158,158,158,158,158,
+158,157, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+159,159,159,159,159,159,159,159,159,159,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,161,161,161,161,161,
+161,161,161,161,162,162,163,164,164,164,162, 91, 91, 91, 91, 91,
+
+/* block 16 */
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,166,166,166,166,167,166,166,166,166,166,
+166,166,166,166,167,166,166,166,167,166,166,166,166,166, 91, 91,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168, 91,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,170,170,170, 91, 91,171, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 17 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 18 */
+172,172,172,173,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,172,173,172,174,173,173,
+173,172,172,172,172,172,172,172,172,173,173,173,173,172,173,173,
+174, 86, 86,172,172,172,172,172,174,174,174,174,174,174,174,174,
+174,174,172,172, 2, 2,175,175,175,175,175,175,175,175,175,175,
+ 2,176,174,174,174,174,174,174, 91,174,174,174,174,174,174,174,
+
+/* block 19 */
+ 91,177,178,178, 91,179,179,179,179,179,179,179,179, 91, 91,179,
+179, 91, 91,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179, 91,179,179,179,179,179,179,
+179, 91,179, 91, 91, 91,179,179,179,179, 91, 91,177,179,178,178,
+178,177,177,177,177, 91, 91,178,178, 91, 91,178,178,177,179, 91,
+ 91, 91, 91, 91, 91, 91, 91,178, 91, 91, 91, 91,179,179, 91,179,
+179,179,177,177, 91, 91,180,180,180,180,180,180,180,180,180,180,
+179,179,181,181,182,182,182,182,182,182,183,181, 91, 91, 91, 91,
+
+/* block 20 */
+ 91,184,184,185, 91,186,186,186,186,186,186, 91, 91, 91, 91,186,
+186, 91, 91,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186, 91,186,186,186,186,186,186,
+186, 91,186,186, 91,186,186, 91,186,186, 91, 91,184, 91,185,185,
+185,184,184, 91, 91, 91, 91,184,184, 91, 91,184,184,184, 91, 91,
+ 91,184, 91, 91, 91, 91, 91, 91, 91,186,186,186,186, 91,186, 91,
+ 91, 91, 91, 91, 91, 91,187,187,187,187,187,187,187,187,187,187,
+184,184,186,186,186,184, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 21 */
+ 91,188,188,189, 91,190,190,190,190,190,190,190,190,190, 91,190,
+190,190, 91,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190, 91,190,190,190,190,190,190,
+190, 91,190,190, 91,190,190,190,190,190, 91, 91,188,190,189,189,
+189,188,188,188,188,188, 91,188,188,189, 91,189,189,188, 91, 91,
+190, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+190,190,188,188, 91, 91,191,191,191,191,191,191,191,191,191,191,
+ 91,192, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 22 */
+ 91,193,194,194, 91,195,195,195,195,195,195,195,195, 91, 91,195,
+195, 91, 91,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195, 91,195,195,195,195,195,195,
+195, 91,195,195, 91,195,195,195,195,195, 91, 91,193,195,194,193,
+194,193,193,193,193, 91, 91,194,194, 91, 91,194,194,193, 91, 91,
+ 91, 91, 91, 91, 91, 91,193,194, 91, 91, 91, 91,195,195, 91,195,
+195,195,193,193, 91, 91,196,196,196,196,196,196,196,196,196,196,
+197,195,198,198,198,198,198,198, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 23 */
+ 91, 91,199,200, 91,200,200,200,200,200,200, 91, 91, 91,200,200,
+200, 91,200,200,200,200, 91, 91, 91,200,200, 91,200, 91,200,200,
+ 91, 91, 91,200,200, 91, 91, 91,200,200,200, 91, 91, 91,200,200,
+200,200,200,200,200,200,200,200,200,200, 91, 91, 91, 91,201,201,
+199,201,201, 91, 91, 91,201,201,201, 91,201,201,201,199, 91, 91,
+200, 91, 91, 91, 91, 91, 91,201, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91,202,202,202,202,202,202,202,202,202,202,
+203,203,203,204,204,204,204,204,204,205,204, 91, 91, 91, 91, 91,
+
+/* block 24 */
+ 91,206,206,206, 91,207,207,207,207,207,207,207,207, 91,207,207,
+207, 91,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207, 91,207,207,207,207,207,207,
+207,207,207,207, 91,207,207,207,207,207, 91, 91, 91,207,208,208,
+208,206,206,206,206, 91,208,208,208, 91,208,208,208,208, 91, 91,
+ 91, 91, 91, 91, 91,208,208, 91,207,207, 91, 91, 91, 91, 91, 91,
+207,207,208,208, 91, 91,209,209,209,209,209,209,209,209,209,209,
+ 91, 91, 91, 91, 91, 91, 91, 91,210,210,210,210,210,210,210,211,
+
+/* block 25 */
+ 91, 91,212,212, 91,213,213,213,213,213,213,213,213, 91,213,213,
+213, 91,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213, 91,213,213,213,213,213,213,
+213,213,213,213, 91,213,213,213,213,213, 91, 91,214,213,212,214,
+212,212,212,212,212, 91,214,212,212, 91,212,212,214,214, 91, 91,
+ 91, 91, 91, 91, 91,212,212, 91, 91, 91, 91, 91, 91, 91,213, 91,
+213,213,214,214, 91, 91,215,215,215,215,215,215,215,215,215,215,
+ 91,213,213, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 26 */
+ 91, 91,216,216, 91,217,217,217,217,217,217,217,217, 91,217,217,
+217, 91,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217, 91, 91,217,216,216,
+216,218,218,218,218, 91,216,216,216, 91,216,216,216,218,217, 91,
+ 91, 91, 91, 91, 91, 91, 91,216, 91, 91, 91, 91, 91, 91, 91, 91,
+217,217,218,218, 91, 91,219,219,219,219,219,219,219,219,219,219,
+220,220,220,220,220,220, 91, 91, 91,221,217,217,217,217,217,217,
+
+/* block 27 */
+ 91, 91,222,222, 91,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223, 91, 91, 91,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223, 91,223,223,223,223,223,223,223,223,223, 91,223, 91, 91,
+223,223,223,223,223,223,223, 91, 91, 91,224, 91, 91, 91, 91,222,
+222,222,224,224,224, 91,224, 91,222,222,222,222,222,222,222,222,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91,222,222,225, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 28 */
+ 91,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,227,226,226,227,227,227,227,227,227,227, 91, 91, 91, 91, 3,
+226,226,226,226,226,226,228,227,227,227,227,227,227,227,227,229,
+230,230,230,230,230,230,230,230,230,230,229,229, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 29 */
+ 91,231,231, 91,231, 91, 91,231,231, 91,231, 91, 91,231, 91, 91,
+ 91, 91, 91, 91,231,231,231,231, 91,231,231,231,231,231,231,231,
+ 91,231,231,231, 91,231, 91,231, 91, 91,231,231, 91,231,231,231,
+231,232,231,231,232,232,232,232,232,232, 91,232,232,231, 91, 91,
+231,231,231,231,231, 91,233, 91,232,232,232,232,232,232, 91, 91,
+234,234,234,234,234,234,234,234,234,234, 91, 91,231,231, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 30 */
+235,236,236,236,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,236,236,236,236,236,238,238,236,236,236,236,236,236,
+239,239,239,239,239,239,239,239,239,239,240,240,240,240,240,240,
+240,240,240,240,236,238,236,238,236,238,241,242,241,242,243,243,
+235,235,235,235,235,235,235,235, 91,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235, 91, 91, 91,
+ 91,238,238,238,238,238,238,238,238,238,238,238,238,238,238,243,
+
+/* block 31 */
+238,238,238,238,238,237,238,238,235,235,235,235,235,238,238,238,
+238,238,238,238,238,238,238,238, 91,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238, 91,236,236,
+236,236,236,236,236,236,238,236,236,236,236,236,236, 91,236,236,
+237,237,237,237,237, 13, 13, 13, 13,237,237, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 32 */
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,245,245,246,246,246,
+246,245,246,246,246,246,246,246,245,246,246,245,245,246,246,244,
+247,247,247,247,247,247,247,247,247,247,248,248,248,248,248,248,
+244,244,244,244,244,244,245,245,246,246,244,244,244,244,246,246,
+246,244,245,245,245,244,244,245,245,245,245,245,245,245,244,244,
+244,246,246,246,246,244,244,244,244,244,244,244,244,244,244,244,
+
+/* block 33 */
+244,244,246,245,245,246,246,245,245,245,245,245,245,246,244,245,
+247,247,247,247,247,247,247,247,247,247,245,245,245,246,249,249,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251, 2,252, 91, 91, 91,
+
+/* block 34 */
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+
+/* block 35 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254, 91,254,254,254,254, 91, 91,
+254,254,254,254,254,254,254, 91,254, 91,254,254,254,254, 91, 91,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+
+/* block 36 */
+254,254,254,254,254,254,254,254,254, 91,254,254,254,254, 91, 91,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254, 91,
+254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+
+/* block 37 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254, 91,254,254,254,254, 91, 91,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254, 91, 91,255,255,255,
+256,257,257,257,257,257,257,257,257,258,258,258,258,258,258,258,
+258,258,258,258,258,258,258,258,258,258,258,258,258, 91, 91, 91,
+
+/* block 38 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+256,256,256,256,256,256,256,256,256,256, 91, 91, 91, 91, 91, 91,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,259,
+259,259,259,259,259, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 39 */
+260,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+
+/* block 40 */
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+
+/* block 41 */
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,262,262,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+
+/* block 42 */
+263,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,
+264,264,264,264,264,264,264,264,264,264,264,265,266, 91, 91, 91,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,
+267,267,267,267,267,267,267,267,267,267,267, 2, 2, 2,268,268,
+268, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 43 */
+269,269,269,269,269,269,269,269,269,269,269,269,269, 91,269,269,
+269,269,270,270,270, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,
+271,271,272,272,272, 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,273,
+273,273,274,274, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+275,275,275,275,275,275,275,275,275,275,275,275,275, 91,275,275,
+275, 91,276,276, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 44 */
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,
+277,277,277,277,278,278,279,280,280,280,280,280,280,280,279,279,
+279,279,279,279,279,279,280,279,279,280,280,280,280,280,280,280,
+280,280,280,280,281,281,281,282,281,281,281,283,277,280, 91, 91,
+284,284,284,284,284,284,284,284,284,284, 91, 91, 91, 91, 91, 91,
+285,285,285,285,285,285,285,285,285,285, 91, 91, 91, 91, 91, 91,
+
+/* block 45 */
+286,286, 2, 2,286, 2,287,286,286,286,286,288,288,288,289, 91,
+290,290,290,290,290,290,290,290,290,290, 91, 91, 91, 91, 91, 91,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,292,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 46 */
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,291,
+291,291,291,291,291,291,291,291,291,288,291, 91, 91, 91, 91, 91,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,261,
+261,261,261,261,261,261, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 47 */
+293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,
+293,293,293,293,293,293,293,293,293,293,293,293,293, 91, 91, 91,
+294,294,294,295,295,295,295,294,294,295,295,295, 91, 91, 91, 91,
+295,295,294,295,295,295,295,295,295,294,294,294, 91, 91, 91, 91,
+296, 91, 91, 91,297,297,298,298,298,298,298,298,298,298,298,298,
+299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
+299,299,299,299,299,299,299,299,299,299,299,299,299,299, 91, 91,
+299,299,299,299,299, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 48 */
+300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,300,300,300, 91, 91, 91, 91,
+301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,
+301,300,300,300,300,300,300,300,301,301, 91, 91, 91, 91, 91, 91,
+302,302,302,302,302,302,302,302,302,302,303, 91, 91, 91,304,304,
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+
+/* block 49 */
+306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
+306,306,306,306,306,306,306,307,307,308,308,308, 91, 91,309,309,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,
+310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,310,
+310,310,310,310,310,311,312,311,312,312,312,312,312,312,312, 91,
+312,311,312,311,311,312,312,312,312,312,312,312,312,311,311,311,
+311,311,311,312,312,312,312,312,312,312,312,312,312, 91, 91,312,
+
+/* block 50 */
+313,313,313,313,313,313,313,313,313,313, 91, 91, 91, 91, 91, 91,
+313,313,313,313,313,313,313,313,313,313, 91, 91, 91, 91, 91, 91,
+314,314,314,314,314,314,314,315,314,314,314,314,314,314, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 51 */
+316,316,316,316,317,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
+318,318,318,318,316,317,316,316,316,316,316,317,316,317,317,317,
+317,317,316,317,317,318,318,318,318,318,318,318, 91, 91, 91, 91,
+319,319,319,319,319,319,319,319,319,319,320,320,320,320,320,320,
+320,321,321,321,321,321,321,321,321,321,321,316,316,316,316,316,
+316,316,316,316,321,321,321,321,321,321,321,321,321, 91, 91, 91,
+
+/* block 52 */
+322,322,323,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,324,
+324,323,322,322,322,322,323,323,322,322,323, 91, 91, 91,324,324,
+325,325,325,325,325,325,325,325,325,325, 91, 91, 91, 91, 91, 91,
+326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,
+326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,
+326,326,326,326,326,326,327,328,327,327,328,328,328,327,328,327,
+327,327,328,328, 91, 91, 91, 91, 91, 91, 91, 91,329,329,329,329,
+
+/* block 53 */
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,330,
+330,330,330,330,331,331,331,331,331,331,331,331,332,332,332,332,
+332,332,332,332,331,331,332,332, 91, 91, 91,333,333,333,333,333,
+334,334,334,334,334,334,334,334,334,334, 91, 91, 91,330,330,330,
+335,335,335,335,335,335,335,335,335,335,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,337,337,337,337,337,337,338,338,
+
+/* block 54 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 86, 86, 86, 2, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86,339, 86, 86, 86, 86, 86, 86, 86,340,340,340,340, 86,340,340,
+340,340,339, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 55 */
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 98, 98, 98, 98, 98,341, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 92, 92, 92,
+ 92, 92, 14, 14, 14, 14, 98, 98, 98, 98, 98, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14,342,343, 14, 14, 14,344, 14, 14,
+
+/* block 56 */
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 92,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 86, 86, 86, 86,
+
+/* block 57 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+
+/* block 58 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 14, 14, 14, 14, 14,345, 14, 14,346, 14,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+
+/* block 59 */
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+347,347,347,347,347,347, 91, 91,348,348,348,348,348,348, 91, 91,
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+347,347,347,347,347,347, 91, 91,348,348,348,348,348,348, 91, 91,
+ 98,347, 98,347, 98,347, 98,347, 91,348, 91,348, 91,348, 91,348,
+347,347,347,347,347,347,347,347,348,348,348,348,348,348,348,348,
+349,349,350,350,350,350,351,351,352,352,353,353,354,354, 91, 91,
+
+/* block 60 */
+347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355,
+347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355,
+347,347,347,347,347,347,347,347,355,355,355,355,355,355,355,355,
+347,347, 98,356, 98, 91, 98, 98,348,348,357,357,358, 90,359, 90,
+ 90, 90, 98,356, 98, 91, 98, 98,360,360,360,360,358, 90, 90, 90,
+347,347, 98, 98, 91, 91, 98, 98,348,348,361,361, 91, 90, 90, 90,
+347,347, 98, 98, 98,117, 98, 98,348,348,362,362,121, 90, 90, 90,
+ 91, 91, 98,356, 98, 91, 98, 98,363,363,364,364,358, 90, 90, 91,
+
+/* block 61 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16,365,365, 16, 16,
+ 7, 7, 7, 7, 7, 7, 2, 2, 15, 19, 4, 15, 15, 19, 4, 15,
+ 2, 2, 2, 2, 2, 2, 2, 2,366,367, 16, 16, 16, 16, 16, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 15, 19, 2, 2, 2, 2, 11,
+ 11, 2, 2, 2, 6, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 2, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
+ 16, 16, 16, 16, 16, 91, 91, 91, 91, 91, 16, 16, 16, 16, 16, 16,
+ 17, 83, 91, 91, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 83,
+
+/* block 62 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 6, 6, 6, 4, 5, 91,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 91, 91, 91,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,368,368,368,
+368, 86,368,368,368, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 63 */
+ 13, 13,369, 13, 13, 13, 13,369, 13, 13,370,369,369,369,370,370,
+369,369,369,370, 13,369, 13, 13, 6,369,369,369,369,369, 13, 13,
+ 13, 13, 13, 13,369, 13,371, 13,369, 13,372,373,369,369, 13,370,
+369,369,374,369,370,340,340,340,340,370, 13, 13,370,370,369,369,
+ 6, 6, 6, 6, 6,369,370,370,370,370, 13, 6, 13, 13,375, 13,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,
+
+/* block 64 */
+378,378,378, 21, 22,378,378,378,378, 17, 91, 91, 91, 91, 91, 91,
+ 6, 6, 6, 6, 6, 13, 13, 13, 13, 13, 6, 6, 13, 13, 13, 13,
+ 6, 13, 13, 6, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 6, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6,
+ 13, 13, 6, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 65 */
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 66 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 6, 6, 13, 13, 13, 13, 13, 13, 13, 4, 5, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13,
+
+/* block 67 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6,
+ 6, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 68 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+
+/* block 69 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13,379,379,379,379,379,379,379,379,379,379,
+379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,379,
+380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,
+380,380,380,380,380,380,380,380,380,380, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+
+/* block 70 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 71 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 6, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 6, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 72 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 6,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 73 */
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5,
+ 4, 5, 4, 5, 4, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+
+/* block 74 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 6, 6, 6, 6, 6, 4, 5, 6, 6, 6, 6, 91, 6, 91, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+/* block 75 */
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,381,
+
+/* block 76 */
+ 6, 6, 6, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
+ 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 4, 5, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 5, 6, 6,
+
+/* block 77 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 13, 13, 6, 6, 6, 6, 6, 6, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 78 */
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,382,
+382,382,382,382,382,382,382,382,382,382,382,382,382,382,382, 91,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, 91,
+ 21, 22,384,385,386,387,388, 21, 22, 21, 22, 21, 22,389,390,391,
+392, 14, 21, 22, 14, 21, 22, 14, 14, 14, 14, 14, 14, 83,393,393,
+
+/* block 79 */
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,113,114,113,114,113,114,113,114,113,114,113,114,
+113,114,113,114,394,395,395,395,395,395,395,113,114,113,114,396,
+396,396, 91, 91, 91, 91, 91, 91, 91,397,397,397,397,398,397,397,
+
+/* block 80 */
+399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
+399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,
+399,399,399,399,399,399, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
+400,400,400,400,400,400, 91, 91, 91, 91, 91, 91, 91, 91, 91,401,
+402, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,403,
+
+/* block 81 */
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+
+/* block 82 */
+ 2, 2, 15, 19, 15, 19, 2, 2, 2, 15, 19, 2, 15, 19, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, 7, 2, 15, 19, 2, 2,
+ 15, 19, 4, 5, 4, 5, 4, 5, 4, 5, 2, 2, 2, 2, 2, 84,
+ 2, 2, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 83 */
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404, 91,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 84 */
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+
+/* block 85 */
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,
+404,404,404,404,404,404, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91,
+
+/* block 86 */
+ 1, 2, 2, 2, 13,405,340,406, 4, 5, 4, 5, 4, 5, 4, 5,
+ 4, 5, 13, 13, 4, 5, 4, 5, 4, 5, 4, 5, 7, 4, 5, 5,
+ 13,406,406,406,406,406,406,406,406,406, 86, 86, 86, 86,407,407,
+ 7, 84, 84, 84, 84, 84, 13, 13,406,406,406,405,340, 2, 13, 13,
+ 91,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+
+/* block 87 */
+408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,408,
+408,408,408,408,408,408,408, 91, 91, 86, 86, 10, 10,409,409,408,
+ 7,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410, 2, 84,411,411,410,
+
+/* block 88 */
+ 91, 91, 91, 91, 91,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412, 91, 91,
+ 91,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+
+/* block 89 */
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 91,
+ 13, 13, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
+412,412,412,412,412,412,412,412,412,412,412, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+
+/* block 90 */
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, 91,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,
+413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, 13,
+
+/* block 91 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, 91,
+
+/* block 92 */
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 93 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+
+/* block 94 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 95 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 96 */
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,417,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+
+/* block 97 */
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
+
+/* block 98 */
+416,416,416,416,416,416,416,416,416,416,416,416,416, 91, 91, 91,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,418,
+418,418,418,418,418,418,418, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,420,420,420,420,420,420,421,421,
+
+/* block 99 */
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+
+/* block 100 */
+422,422,422,422,422,422,422,422,422,422,422,422,423,424,424,424,
+422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,
+425,425,425,425,425,425,425,425,425,425,422,422, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,426,130,
+131,131,131,427, 91, 91, 91, 91, 91, 91, 91, 91,130,130,427,342,
+
+/* block 101 */
+127,128,127,128,127,128,127,128,127,128,127,128,127,128,127,128,
+127,128,127,128,127,128,127,128, 91, 91, 91, 91, 91, 91, 91, 91,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,429,429,429,429,429,429,429,429,429,429,
+430,430,431,431,431,431,431,431, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 102 */
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+ 10, 10, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 14, 14, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 21, 22,
+ 83, 14, 14, 14, 14, 14, 14, 14, 14, 21, 22, 21, 22,432, 21, 22,
+
+/* block 103 */
+ 21, 22, 21, 22, 21, 22, 21, 22, 84, 10, 10, 21, 22,433, 14, 91,
+ 21, 22, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 21, 22, 21, 22, 21, 22, 21, 22, 21, 22, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 14, 45, 45, 45, 45, 45,
+
+/* block 104 */
+434,434,435,434,434,434,435,434,434,434,434,435,434,434,434,434,
+434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,
+434,434,434,436,436,435,435,436,437,437,437,437, 91, 91, 91, 91,
+ 17, 17, 17, 17, 17, 17, 13, 13, 3, 13, 91, 91, 91, 91, 91, 91,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
+438,438,438,438,439,439,439,439, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 105 */
+440,440,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,441,
+441,441,441,441,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,442, 91, 91, 91, 91, 91, 91, 91, 91, 91,443,443,
+444,444,444,444,444,444,444,444,444,444, 91, 91, 91, 91, 91, 91,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,174,174,174,174,174,174,445,445,445,174, 91, 91, 91, 91,
+
+/* block 106 */
+446,446,446,446,446,446,446,446,446,446,447,447,447,447,447,447,
+447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,447,
+447,447,447,447,447,447,448,448,448,448,448,448,448,448,449,449,
+450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,450,
+450,450,450,450,450,450,450,451,451,451,451,451,451,451,451,451,
+451,451,452,452, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,453,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253, 91, 91, 91,
+
+/* block 107 */
+454,454,454,455,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
+456,456,456,454,455,455,454,454,454,454,455,455,454,455,455,455,
+455,457,457,457,457,457,457,457,457,457,457,457,457,457, 91,458,
+459,459,459,459,459,459,459,459,459,459, 91, 91, 91, 91,457,457,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 108 */
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,461,461,461,461,461,461,462,
+462,461,461,462,462,461,461, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+460,460,460,461,460,460,460,460,460,460,460,460,461,462, 91, 91,
+463,463,463,463,463,463,463,463,463,463, 91, 91,464,464,464,464,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+465,244,244,244,244,244,244,249,249,249,244,245, 91, 91, 91, 91,
+
+/* block 109 */
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,466,
+467,466,467,467,467,466,466,467,467,466,466,466,466,466,467,467,
+466,467,466, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,466,466,468,469,469,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 110 */
+ 91,254,254,254,254,254,254, 91, 91,254,254,254,254,254,254, 91,
+ 91,254,254,254,254,254,254, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+254,254,254,254,254,254,254, 91,254,254,254,254,254,254,254, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 111 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,470,
+470,470,470,471,471,472,471,471,472,471,471,473,471,472, 91, 91,
+474,474,474,474,474,474,474,474,474,474, 91, 91, 91, 91, 91, 91,
+
+/* block 112 */
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253, 91, 91, 91, 91,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253, 91, 91, 91, 91,
+
+/* block 113 */
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,
+
+/* block 114 */
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+
+/* block 115 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+
+/* block 116 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 117 */
+ 14, 14, 14, 14, 14, 14, 14, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91,138,138,138,138,138, 91, 91, 91, 91, 91,143,140,143,
+143,143,143,143,143,143,143,143,143,477,143,143,143,143,143,143,
+143,143,143,143,143,143,143, 91,143,143,143,143,143, 91,143, 91,
+143,143, 91,143,143, 91,143,143,143,143,143,143,143,143,143,143,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 118 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,478,478,478,478,478,478,478,478,478,478,478,478,478,478,
+478,478, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 119 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 120 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150, 4, 5,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+
+/* block 121 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+ 91, 91,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+150,150,150,150,150,150,150,150,150,150,150,150,147, 13, 91, 91,
+
+/* block 122 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 2, 2, 2, 2, 2, 2, 2, 4, 5, 2, 91, 91, 91, 91, 91, 91,
+ 86, 86, 86, 86, 86, 86, 86, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 2, 7, 7, 11, 11, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
+ 5, 4, 5, 4, 5, 2, 2, 4, 5, 2, 2, 2, 2, 11, 11, 11,
+ 2, 2, 2, 91, 2, 2, 2, 2, 7, 4, 5, 4, 5, 4, 5, 2,
+ 2, 2, 6, 7, 6, 6, 6, 91, 2, 3, 2, 2, 91, 91, 91, 91,
+150,150,150,150,150, 91,150,150,150,150,150,150,150,150,150,150,
+
+/* block 123 */
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150, 91, 91, 16,
+
+/* block 124 */
+ 91, 2, 2, 2, 3, 2, 2, 2, 4, 5, 2, 6, 2, 7, 2, 2,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 6, 6, 6, 2,
+ 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 2, 5, 10, 11,
+ 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 6, 5, 6, 4,
+ 5, 2, 4, 5, 2, 2,410,410,410,410,410,410,410,410,410,410,
+ 84,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+
+/* block 125 */
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410, 84, 84,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 91,
+ 91, 91,253,253,253,253,253,253, 91, 91,253,253,253,253,253,253,
+ 91, 91,253,253,253,253,253,253, 91, 91,253,253,253, 91, 91, 91,
+ 3, 3, 6, 10, 13, 3, 3, 91, 13, 6, 6, 6, 6, 13, 13, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 16, 16, 16, 13, 13, 91, 91,
+
+/* block 126 */
+479,479,479,479,479,479,479,479,479,479,479,479, 91,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479, 91,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479, 91,479,479, 91,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479, 91, 91,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 127 */
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,
+479,479,479,479,479,479,479,479,479,479,479, 91, 91, 91, 91, 91,
+
+/* block 128 */
+ 2, 2, 13, 91, 91, 91, 91, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,
+480,480,480,480,480,481,481,481,481,482,482,482,482,482,482,482,
+
+/* block 129 */
+482,482,482,482,482,482,482,482,482,482,481, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 86, 91, 91,
+
+/* block 130 */
+483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,
+483,483,483,483,483,483,483,483,483,483,483,483,483, 91, 91, 91,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,
+484, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 131 */
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,
+485,485,485,485,485,485,485,485,485,485,485,485,485,485,485, 91,
+486,486,486,486, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,
+487,488,487,487,487,487,487,487,487,487,488, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 132 */
+489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,
+489,489,489,489,489,489,489,489,489,489,489,489,489,489, 91,490,
+491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
+491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,
+491,491,491,491, 91, 91, 91, 91,491,491,491,491,491,491,491,491,
+492,493,493,493,493,493, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 133 */
+494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,
+494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,494,
+494,494,494,494,494,494,494,494,495,495,495,495,495,495,495,495,
+495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
+495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,
+
+/* block 134 */
+497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,497,
+497,497,497,497,497,497,497,497,497,497,497,497,497,497, 91, 91,
+498,498,498,498,498,498,498,498,498,498, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 135 */
+499,499,499,499,499,499, 91, 91,499, 91,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499,
+499,499,499,499,499,499, 91,499,499, 91, 91, 91,499, 91, 91,499,
+500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500,
+500,500,500,500,500,500, 91,501,502,502,502,502,502,502,502,502,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 136 */
+503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,
+503,503,503,503,503,503,504,504,504,504,504,504, 91, 91, 91,505,
+506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,
+506,506,506,506,506,506,506,506,506,506, 91, 91, 91, 91, 91,507,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 137 */
+508,509,509,509, 91,509,509, 91, 91, 91, 91, 91,509,509,509,509,
+508,508,508,508, 91,508,508,508, 91,508,508,508,508,508,508,508,
+508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,508,
+508,508,508,508, 91, 91, 91, 91,509,509,509, 91, 91, 91, 91,509,
+510,510,510,510,510,510,510,510, 91, 91, 91, 91, 91, 91, 91, 91,
+511,511,511,511,511,511,511,511,511, 91, 91, 91, 91, 91, 91, 91,
+512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,
+512,512,512,512,512,512,512,512,512,512,512,512,512,513,513,514,
+
+/* block 138 */
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,
+515,515,515,515,515,515, 91, 91, 91,516,516,516,516,516,516,516,
+517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,
+517,517,517,517,517,517, 91, 91,518,518,518,518,518,518,518,518,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519, 91, 91, 91, 91, 91,520,520,520,520,520,520,520,520,
+
+/* block 139 */
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
+521,521,521,521,521,521,521,521,521, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 140 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, 91,
+
+/* block 141 */
+523,524,523,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,525,
+525,525,525,525,525,525,525,525,524,524,524,524,524,524,524,524,
+524,524,524,524,524,524,524,526,526,526,526,526,526,526, 91, 91,
+ 91, 91,527,527,527,527,527,527,527,527,527,527,527,527,527,527,
+527,527,527,527,527,527,528,528,528,528,528,528,528,528,528,528,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 142 */
+529,529,530,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+530,530,530,529,529,529,529,530,530,529,529,532,532,533,532,532,
+532,532, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 143 */
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+
+/* block 144 */
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,534,
+534,534,534,534,534,534,534,534,534,534,534,534,534,534,534, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 145 */
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,535,
+535,535,535, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+536,536,536,536, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 146 */
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+
+/* block 147 */
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+537,537,537,537,537,537,537,537,537,537,537,537,537,537,537, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 148 */
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+
+/* block 149 */
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,428,
+428,428,428,428,428,428,428,428,428, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 150 */
+410,408, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 151 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 152 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 91, 91, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13,339,339, 86, 86, 86, 13, 13, 13,339,339,339,
+339,339,339, 16, 16, 16, 16, 16, 16, 16, 16, 86, 86, 86, 86, 86,
+
+/* block 153 */
+ 86, 86, 86, 13, 13, 86, 86, 86, 86, 86, 86, 86, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 86, 86, 86, 86, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 154 */
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,
+482,482,538,538,538,482, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 155 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 156 */
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,370,370,
+370,370,370,370,370, 91,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 157 */
+369,369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,369, 91,369,369,
+ 91, 91,369, 91, 91,369,369, 91, 91,369,369,369,369, 91,369,369,
+369,369,369,369,369,369,370,370,370,370, 91,370, 91,370,370,370,
+370,370,370,370, 91,370,370,370,370,370,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+
+/* block 158 */
+370,370,370,370,369,369, 91,369,369,369,369, 91, 91,369,369,369,
+369,369,369,369,369, 91,369,369,369,369,369,369,369, 91,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,369,369, 91,369,369,369,369, 91,
+369,369,369,369,369, 91,369, 91, 91, 91,369,369,369,369,369,369,
+369, 91,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 159 */
+369,369,369,369,369,369,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+
+/* block 160 */
+370,370,370,370,370,370,370,370,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+
+/* block 161 */
+369,369,369,369,369,369,369,369,369,369,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370, 91, 91,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369, 6,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370, 6,370,370,370,370,
+370,370,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369, 6,370,370,370,370,
+
+/* block 162 */
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370, 6,370,370,370,370,370,370,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369, 6,370,370,370,370,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, 6,
+370,370,370,370,370,370,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, 6,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+
+/* block 163 */
+370,370,370,370,370,370,370,370,370, 6,370,370,370,370,370,370,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369, 6,370,370,370,370,370,370,
+370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
+370,370,370, 6,370,370,370,370,370,370,369,370, 91, 91, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+
+/* block 164 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 165 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 166 */
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 167 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 168 */
+539, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 169 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91,
+
+/* block 170 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 171 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91,
+ 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+
+/* block 172 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 91, 13, 13, 13, 13, 91, 91, 91,
+
+/* block 173 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 174 */
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 13, 13, 13, 13, 13,
+
+/* block 175 */
+ 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 13, 13, 13, 91, 13, 91, 13, 91, 13, 91, 13, 13, 13, 91,
+ 13, 13, 13, 13, 13, 13, 91, 91, 13, 13, 13, 13, 91, 13, 91, 91,
+ 13, 13, 13, 13, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 91, 91, 91, 91, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 176 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 177 */
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 178 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 179 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+
+/* block 180 */
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 181 */
+ 91, 16, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+
+/* block 182 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+
+/* block 183 */
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+
+/* block 184 */
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,
+476,476,476,476,476,476,476,476,476,476,476,476,476,476, 91, 91,
+
+};
+
+#if UCD_BLOCK_SIZE != 128
+#error Please correct UCD_BLOCK_SIZE in pcre_internal.h
+#endif
+#endif /* SUPPORT_UCP */
diff --git a/src/3rdparty/pcre/pcre_valid_utf8.c b/src/3rdparty/pcre/pcre_valid_utf8.c
new file mode 100644
index 00000000000..b2dc5c9f1ab
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_valid_utf8.c
@@ -0,0 +1,299 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function for validating UTF-8 character
+strings. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Validate a UTF-8 string *
+*************************************************/
+
+/* This function is called (optionally) at the start of compile or match, to
+check that a supposed UTF-8 string is actually valid. The early check means
+that subsequent code can assume it is dealing with a valid string. The check
+can be turned off for maximum performance, but the consequences of supplying an
+invalid string are then undefined.
+
+Originally, this function checked according to RFC 2279, allowing for values in
+the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
+the canonical format. Once somebody had pointed out RFC 3629 to me (it
+obsoletes 2279), additional restrictions were applied. The values are now
+limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
+subrange 0xd000 to 0xdfff is excluded. However, the format of 5-byte and 6-byte
+characters is still checked.
+
+From release 8.13 more information about the details of the error are passed
+back in the returned value:
+
+PCRE_UTF8_ERR0 No error
+PCRE_UTF8_ERR1 Missing 1 byte at the end of the string
+PCRE_UTF8_ERR2 Missing 2 bytes at the end of the string
+PCRE_UTF8_ERR3 Missing 3 bytes at the end of the string
+PCRE_UTF8_ERR4 Missing 4 bytes at the end of the string
+PCRE_UTF8_ERR5 Missing 5 bytes at the end of the string
+PCRE_UTF8_ERR6 2nd-byte's two top bits are not 0x80
+PCRE_UTF8_ERR7 3rd-byte's two top bits are not 0x80
+PCRE_UTF8_ERR8 4th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR9 5th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR10 6th-byte's two top bits are not 0x80
+PCRE_UTF8_ERR11 5-byte character is not permitted by RFC 3629
+PCRE_UTF8_ERR12 6-byte character is not permitted by RFC 3629
+PCRE_UTF8_ERR13 4-byte character with value > 0x10ffff is not permitted
+PCRE_UTF8_ERR14 3-byte character with value 0xd000-0xdfff is not permitted
+PCRE_UTF8_ERR15 Overlong 2-byte sequence
+PCRE_UTF8_ERR16 Overlong 3-byte sequence
+PCRE_UTF8_ERR17 Overlong 4-byte sequence
+PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
+PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
+PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
+PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
+
+Arguments:
+ string points to the string
+ length length of string, or -1 if the string is zero-terminated
+ errp pointer to an error position offset variable
+
+Returns: = 0 if the string is a valid UTF-8 string
+ > 0 otherwise, setting the offset of the bad character
+*/
+
+int
+PRIV(valid_utf)(PCRE_PUCHAR string, int length, int *erroroffset)
+{
+#ifdef SUPPORT_UTF
+register PCRE_PUCHAR p;
+
+if (length < 0)
+ {
+ for (p = string; *p != 0; p++);
+ length = (int)(p - string);
+ }
+
+for (p = string; length-- > 0; p++)
+ {
+ register int ab, c, d;
+
+ c = *p;
+ if (c < 128) continue; /* ASCII character */
+
+ if (c < 0xc0) /* Isolated 10xx xxxx byte */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE_UTF8_ERR20;
+ }
+
+ if (c >= 0xfe) /* Invalid 0xfe or 0xff bytes */
+ {
+ *erroroffset = (int)(p - string);
+ return PCRE_UTF8_ERR21;
+ }
+
+ ab = PRIV(utf8_table4)[c & 0x3f]; /* Number of additional bytes */
+ if (length < ab)
+ {
+ *erroroffset = (int)(p - string); /* Missing bytes */
+ return ab - length; /* Codes ERR1 to ERR5 */
+ }
+ length -= ab; /* Length remaining */
+
+ /* Check top bits in the second byte */
+
+ if (((d = *(++p)) & 0xc0) != 0x80)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE_UTF8_ERR6;
+ }
+
+ /* For each length, check that the remaining bytes start with the 0x80 bit
+ set and not the 0x40 bit. Then check for an overlong sequence, and for the
+ excluded range 0xd800 to 0xdfff. */
+
+ switch (ab)
+ {
+ /* 2-byte character. No further bytes to check for 0x80. Check first byte
+ for for xx00 000x (overlong sequence). */
+
+ case 1: if ((c & 0x3e) == 0)
+ {
+ *erroroffset = (int)(p - string) - 1;
+ return PCRE_UTF8_ERR15;
+ }
+ break;
+
+ /* 3-byte character. Check third byte for 0x80. Then check first 2 bytes
+ for 1110 0000, xx0x xxxx (overlong sequence) or
+ 1110 1101, 1010 xxxx (0xd800 - 0xdfff) */
+
+ case 2:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if (c == 0xe0 && (d & 0x20) == 0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR16;
+ }
+ if (c == 0xed && d >= 0xa0)
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR14;
+ }
+ break;
+
+ /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
+ bytes for for 1111 0000, xx00 xxxx (overlong sequence), then check for a
+ character greater than 0x0010ffff (f4 8f bf bf) */
+
+ case 3:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if (c == 0xf0 && (d & 0x30) == 0)
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR17;
+ }
+ if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR13;
+ }
+ break;
+
+ /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
+ rejected by the length test below. However, we do the appropriate tests
+ here so that overlong sequences get diagnosed, and also in case there is
+ ever an option for handling these larger code points. */
+
+ /* 5-byte character. Check 3rd, 4th, and 5th bytes for 0x80. Then check for
+ 1111 1000, xx00 0xxx */
+
+ case 4:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR9;
+ }
+ if (c == 0xf8 && (d & 0x38) == 0)
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR18;
+ }
+ break;
+
+ /* 6-byte character. Check 3rd-6th bytes for 0x80. Then check for
+ 1111 1100, xx00 00xx. */
+
+ case 5:
+ if ((*(++p) & 0xc0) != 0x80) /* Third byte */
+ {
+ *erroroffset = (int)(p - string) - 2;
+ return PCRE_UTF8_ERR7;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
+ {
+ *erroroffset = (int)(p - string) - 3;
+ return PCRE_UTF8_ERR8;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
+ {
+ *erroroffset = (int)(p - string) - 4;
+ return PCRE_UTF8_ERR9;
+ }
+ if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE_UTF8_ERR10;
+ }
+ if (c == 0xfc && (d & 0x3c) == 0)
+ {
+ *erroroffset = (int)(p - string) - 5;
+ return PCRE_UTF8_ERR19;
+ }
+ break;
+ }
+
+ /* Character is valid under RFC 2279, but 4-byte and 5-byte characters are
+ excluded by RFC 3629. The pointer p is currently at the last byte of the
+ character. */
+
+ if (ab > 3)
+ {
+ *erroroffset = (int)(p - string) - ab;
+ return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
+ }
+ }
+
+#else /* SUPPORT_UTF */
+(void)(string); /* Keep picky compilers happy */
+(void)(length);
+#endif
+
+return PCRE_UTF8_ERR0; /* This indicates success */
+}
+
+/* End of pcre_valid_utf8.c */
diff --git a/src/3rdparty/pcre/pcre_version.c b/src/3rdparty/pcre/pcre_version.c
new file mode 100644
index 00000000000..915ae8764c4
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_version.c
@@ -0,0 +1,95 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_version(), which returns a
+string that identifies the PCRE version that is in use. */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return version string *
+*************************************************/
+
+/* These macros are the standard way of turning unquoted text into C strings.
+They allow macros like PCRE_MAJOR to be defined without quotes, which is
+convenient for user programs that want to test its value. */
+
+#define STRING(a) # a
+#define XSTRING(s) STRING(s)
+
+/* A problem turned up with PCRE_PRERELEASE, which is defined empty for
+production releases. Originally, it was used naively in this code:
+
+ return XSTRING(PCRE_MAJOR)
+ "." XSTRING(PCRE_MINOR)
+ XSTRING(PCRE_PRERELEASE)
+ " " XSTRING(PCRE_DATE);
+
+However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of
+STRING(). The C standard states: "If (before argument substitution) any
+argument consists of no preprocessing tokens, the behavior is undefined." It
+turns out the gcc treats this case as a single empty string - which is what we
+really want - but Visual C grumbles about the lack of an argument for the
+macro. Unfortunately, both are within their rights. To cope with both ways of
+handling this, I had resort to some messy hackery that does a test at run time.
+I could find no way of detecting that a macro is defined as an empty string at
+pre-processor time. This hack uses a standard trick for avoiding calling
+the STRING macro with an empty argument when doing the test. */
+
+#ifdef COMPILE_PCRE8
+PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
+pcre_version(void)
+#else
+PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
+pcre16_version(void)
+#endif
+{
+return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
+ XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
+ XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE);
+}
+
+/* End of pcre_version.c */
diff --git a/src/3rdparty/pcre/pcre_xclass.c b/src/3rdparty/pcre/pcre_xclass.c
new file mode 100644
index 00000000000..45f1c5b1521
--- /dev/null
+++ b/src/3rdparty/pcre/pcre_xclass.c
@@ -0,0 +1,198 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Copyright (c) 1997-2012 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by both pcre_exec() and pcre_def_exec(). */
+
+
+#ifdef PCRE_HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Match character against an XCLASS *
+*************************************************/
+
+/* This function is called to match a character against an extended class that
+might contain values > 255 and/or Unicode properties.
+
+Arguments:
+ c the character
+ data points to the flag byte of the XCLASS data
+
+Returns: TRUE if character matches, else FALSE
+*/
+
+BOOL
+PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf)
+{
+int t;
+BOOL negated = (*data & XCL_NOT) != 0;
+
+(void)utf;
+#ifdef COMPILE_PCRE8
+/* In 8 bit mode, this must always be TRUE. Help the compiler to know that. */
+utf = TRUE;
+#endif
+
+/* Character values < 256 are matched against a bitmap, if one is present. If
+not, we still carry on, because there may be ranges that start below 256 in the
+additional data. */
+
+if (c < 256)
+ {
+ if ((*data & XCL_MAP) != 0 &&
+ (((pcre_uint8 *)(data + 1))[c/8] & (1 << (c&7))) != 0)
+ return !negated; /* char found */
+ }
+
+/* First skip the bit map if present. Then match against the list of Unicode
+properties or large chars or ranges that end with a large char. We won't ever
+encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
+
+if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar);
+
+while ((t = *data++) != XCL_END)
+ {
+ int x, y;
+ if (t == XCL_SINGLE)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ x = *data++;
+ if (c == x) return !negated;
+ }
+ else if (t == XCL_RANGE)
+ {
+#ifdef SUPPORT_UTF
+ if (utf)
+ {
+ GETCHARINC(x, data); /* macro generates multiple statements */
+ GETCHARINC(y, data); /* macro generates multiple statements */
+ }
+ else
+#endif
+ {
+ x = *data++;
+ y = *data++;
+ }
+ if (c >= x && c <= y) return !negated;
+ }
+
+#ifdef SUPPORT_UCP
+ else /* XCL_PROP & XCL_NOTPROP */
+ {
+ const ucd_record *prop = GET_UCD(c);
+
+ switch(*data)
+ {
+ case PT_ANY:
+ if (t == XCL_PROP) return !negated;
+ break;
+
+ case PT_LAMP:
+ if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
+ prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
+ break;
+
+ case PT_GC:
+ if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_PC:
+ if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
+ break;
+
+ case PT_SC:
+ if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
+ break;
+
+ case PT_ALNUM:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_SPACE: /* Perl space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
+ == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_PXSPACE: /* POSIX space */
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
+ c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
+ c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ case PT_WORD:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
+ == (t == XCL_PROP))
+ return !negated;
+ break;
+
+ /* This should never occur, but compilers may mutter if there is no
+ default. */
+
+ default:
+ return FALSE;
+ }
+
+ data += 2;
+ }
+#endif /* SUPPORT_UCP */
+ }
+
+return negated; /* char did not match */
+}
+
+/* End of pcre_xclass.c */
diff --git a/src/3rdparty/pcre/sljit/sljitConfig.h b/src/3rdparty/pcre/sljit/sljitConfig.h
new file mode 100644
index 00000000000..c832dfe60da
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitConfig.h
@@ -0,0 +1,96 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_CONFIG_H_
+#define _SLJIT_CONFIG_H_
+
+/* --------------------------------------------------------------------- */
+/* Architecture */
+/* --------------------------------------------------------------------- */
+
+/* Architecture selection */
+/* #define SLJIT_CONFIG_X86_32 1 */
+/* #define SLJIT_CONFIG_X86_64 1 */
+/* #define SLJIT_CONFIG_ARM_V5 1 */
+/* #define SLJIT_CONFIG_ARM_V7 1 */
+/* #define SLJIT_CONFIG_ARM_THUMB2 1 */
+/* #define SLJIT_CONFIG_PPC_32 1 */
+/* #define SLJIT_CONFIG_PPC_64 1 */
+/* #define SLJIT_CONFIG_MIPS_32 1 */
+
+/* #define SLJIT_CONFIG_AUTO 1 */
+/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
+
+/* --------------------------------------------------------------------- */
+/* Utilities */
+/* --------------------------------------------------------------------- */
+
+/* Useful for thread-safe compiling of global functions. */
+#ifndef SLJIT_UTIL_GLOBAL_LOCK
+/* Enabled by default */
+#define SLJIT_UTIL_GLOBAL_LOCK 1
+#endif
+
+/* Implements a stack like data structure (by using mmap / VirtualAlloc). */
+#ifndef SLJIT_UTIL_STACK
+/* Enabled by default */
+#define SLJIT_UTIL_STACK 1
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Configuration */
+/* --------------------------------------------------------------------- */
+
+/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should
+ define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */
+#ifndef SLJIT_STD_MACROS_DEFINED
+/* Disabled by default. */
+#define SLJIT_STD_MACROS_DEFINED 0
+#endif
+
+/* Executable code allocation:
+ If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
+ define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */
+#ifndef SLJIT_EXECUTABLE_ALLOCATOR
+/* Enabled by default. */
+#define SLJIT_EXECUTABLE_ALLOCATOR 1
+#endif
+
+/* Debug checks (assertions, etc.). */
+#ifndef SLJIT_DEBUG
+/* Enabled by default */
+#define SLJIT_DEBUG 1
+#endif
+
+/* Verbose operations */
+#ifndef SLJIT_VERBOSE
+/* Enabled by default */
+#define SLJIT_VERBOSE 1
+#endif
+
+/* See the beginning of sljitConfigInternal.h */
+
+#endif
diff --git a/src/3rdparty/pcre/sljit/sljitConfigInternal.h b/src/3rdparty/pcre/sljit/sljitConfigInternal.h
new file mode 100644
index 00000000000..de6e9f07e20
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitConfigInternal.h
@@ -0,0 +1,424 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_CONFIG_INTERNAL_H_
+#define _SLJIT_CONFIG_INTERNAL_H_
+
+/*
+ SLJIT defines the following macros depending on the target architecture:
+
+ Feature detection (boolean) macros:
+ SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
+ SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
+ SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index
+ SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index
+ SLJIT_LITTLE_ENDIAN : little endian architecture
+ SLJIT_BIG_ENDIAN : big endian architecture
+ SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
+ SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
+
+ Types and useful macros:
+ sljit_b, sljit_ub : signed and unsigned 8 bit byte
+ sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type
+ sljit_i, sljit_ui : signed and unsigned 32 bit integer type
+ sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t)
+ SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
+ SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
+*/
+
+#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
+#error "An architecture must be selected"
+#endif
+
+/* Sanity check. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
+#error "Multiple architectures are selected"
+#endif
+
+/* Auto select option (requires compiler support) */
+#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
+
+#ifndef _WIN32
+
+#if defined(__i386__) || defined(__i386)
+#define SLJIT_CONFIG_X86_32 1
+#elif defined(__x86_64__)
+#define SLJIT_CONFIG_X86_64 1
+#elif defined(__arm__) || defined(__ARM__)
+#ifdef __thumb2__
+#define SLJIT_CONFIG_ARM_THUMB2 1
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
+#define SLJIT_CONFIG_ARM_V7 1
+#else
+#define SLJIT_CONFIG_ARM_V5 1
+#endif
+#elif defined(__ppc64__) || defined(__powerpc64__)
+#define SLJIT_CONFIG_PPC_64 1
+#elif defined(__ppc__) || defined(__powerpc__)
+#define SLJIT_CONFIG_PPC_32 1
+#elif defined(__mips__)
+#define SLJIT_CONFIG_MIPS_32 1
+#else
+/* Unsupported architecture */
+#define SLJIT_CONFIG_UNSUPPORTED 1
+#endif
+
+#else /* !_WIN32 */
+
+#if defined(_M_X64) || defined(__x86_64__)
+#define SLJIT_CONFIG_X86_64 1
+#elif defined(_ARM_)
+#define SLJIT_CONFIG_ARM_V5 1
+#else
+#define SLJIT_CONFIG_X86_32 1
+#endif
+
+#endif /* !WIN32 */
+#endif /* SLJIT_CONFIG_AUTO */
+
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+#undef SLJIT_EXECUTABLE_ALLOCATOR
+#endif
+
+#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
+
+/* These libraries are needed for the macros below. */
+#include
+#include
+
+#endif /* STD_MACROS_DEFINED */
+
+/* General macros:
+ Note: SLJIT is designed to be independent from them as possible.
+
+ In release mode (SLJIT_DEBUG is not defined) only the following macros are needed:
+*/
+
+#ifndef SLJIT_MALLOC
+#define SLJIT_MALLOC(size) malloc(size)
+#endif
+
+#ifndef SLJIT_FREE
+#define SLJIT_FREE(ptr) free(ptr)
+#endif
+
+#ifndef SLJIT_MEMMOVE
+#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
+#endif
+
+#ifndef SLJIT_ZEROMEM
+#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
+#endif
+
+#if !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY)
+
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+#define SLJIT_LIKELY(x) __builtin_expect((x), 1)
+#define SLJIT_UNLIKELY(x) __builtin_expect((x), 0)
+#else
+#define SLJIT_LIKELY(x) (x)
+#define SLJIT_UNLIKELY(x) (x)
+#endif
+
+#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
+
+#ifndef SLJIT_INLINE
+/* Inline functions. */
+#define SLJIT_INLINE __inline
+#endif
+
+#ifndef SLJIT_CONST
+/* Const variables. */
+#define SLJIT_CONST const
+#endif
+
+#ifndef SLJIT_UNUSED_ARG
+/* Unused arguments. */
+#define SLJIT_UNUSED_ARG(arg) (void)arg
+#endif
+
+#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
+/* Static ABI functions. For all-in-one programs. */
+
+#if defined(__GNUC__)
+/* Disable unused warnings in gcc. */
+#define SLJIT_API_FUNC_ATTRIBUTE static __attribute__((unused))
+#else
+#define SLJIT_API_FUNC_ATTRIBUTE static
+#endif
+
+#else
+#define SLJIT_API_FUNC_ATTRIBUTE
+#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
+
+#ifndef SLJIT_CACHE_FLUSH
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+
+/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ ppc_cache_flush((from), (to))
+
+#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+/* Not required to implement on archs with unified caches. */
+#define SLJIT_CACHE_FLUSH(from, to)
+
+#else
+
+/* Calls __ARM_NR_cacheflush on ARM-Linux. */
+#define SLJIT_CACHE_FLUSH(from, to) \
+ __clear_cache((char*)(from), (char*)(to))
+
+#endif
+
+#endif /* !SLJIT_CACHE_FLUSH */
+
+/* 8 bit byte type. */
+typedef unsigned char sljit_ub;
+typedef signed char sljit_b;
+
+/* 16 bit half-word type. */
+typedef unsigned short int sljit_uh;
+typedef signed short int sljit_h;
+
+/* 32 bit integer type. */
+typedef unsigned int sljit_ui;
+typedef signed int sljit_i;
+
+/* Machine word type. Can encapsulate a pointer.
+ 32 bit for 32 bit machines.
+ 64 bit for 64 bit machines. */
+#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+/* Just to have something. */
+#define SLJIT_WORD_SHIFT 0
+typedef unsigned long int sljit_uw;
+typedef long int sljit_w;
+#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_32BIT_ARCHITECTURE 1
+#define SLJIT_WORD_SHIFT 2
+typedef unsigned int sljit_uw;
+typedef int sljit_w;
+#else
+#define SLJIT_64BIT_ARCHITECTURE 1
+#define SLJIT_WORD_SHIFT 3
+#ifdef _WIN32
+typedef unsigned __int64 sljit_uw;
+typedef __int64 sljit_w;
+#else
+typedef unsigned long int sljit_uw;
+typedef long int sljit_w;
+#endif
+#endif
+
+/* Double precision. */
+#define SLJIT_FLOAT_SHIFT 3
+
+#ifndef SLJIT_W
+
+/* Defining long constants. */
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#define SLJIT_W(w) (w##ll)
+#else
+#define SLJIT_W(w) (w)
+#endif
+
+#endif /* !SLJIT_W */
+
+#ifndef SLJIT_CALL
+
+/* ABI (Application Binary Interface) types. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+#if defined(__GNUC__)
+
+#define SLJIT_CALL __attribute__ ((fastcall))
+#define SLJIT_X86_32_FASTCALL 1
+
+#elif defined(_WIN32)
+
+#ifdef __BORLANDC__
+#define SLJIT_CALL __msfastcall
+#else /* __BORLANDC__ */
+#define SLJIT_CALL __fastcall
+#endif /* __BORLANDC__ */
+#define SLJIT_X86_32_FASTCALL 1
+
+#else /* defined(_WIN32) */
+#define SLJIT_CALL __stdcall
+#endif
+
+#else /* Other architectures. */
+
+#define SLJIT_CALL
+
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#endif /* !SLJIT_CALL */
+
+#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
+
+/* These macros are useful for the application. */
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_BIG_ENDIAN 1
+
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+
+#ifdef __MIPSEL__
+#define SLJIT_LITTLE_ENDIAN 1
+#else
+#define SLJIT_BIG_ENDIAN 1
+#endif
+
+#else
+#define SLJIT_LITTLE_ENDIAN 1
+#endif
+
+#endif /* !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) */
+
+/* Sanity check. */
+#if (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#error "Exactly one endianness must be selected"
+#endif
+
+#if !(defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN) && !(defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#error "Exactly one endianness must be selected"
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+/* It seems ppc64 compilers use an indirect addressing for functions.
+ It makes things really complicated. */
+#define SLJIT_INDIRECT_CALL 1
+#endif
+
+#ifndef SLJIT_SSE2
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+/* Turn on SSE2 support on x86 (operating on doubles).
+ (Better performance than legacy fpu instructions). */
+#define SLJIT_SSE2 1
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+/* Auto detect SSE2 support using CPUID.
+ On 64 bit x86 cpus, sse2 must be present. */
+#define SLJIT_SSE2_AUTO 1
+#endif
+
+#endif /* (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) */
+
+#endif /* !SLJIT_SSE2 */
+
+#ifndef SLJIT_UNALIGNED
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define SLJIT_UNALIGNED 1
+#endif
+
+#endif /* !SLJIT_UNALIGNED */
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
+#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
+#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
+#endif
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+#include
+#endif
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+
+/* Feel free to redefine these two macros. */
+#ifndef SLJIT_ASSERT
+
+#define SLJIT_HALT_PROCESS() \
+ *((int*)0) = 0
+
+#define SLJIT_ASSERT(x) \
+ do { \
+ if (SLJIT_UNLIKELY(!(x))) { \
+ printf("Assertion failed at " __FILE__ ":%d\n", __LINE__); \
+ SLJIT_HALT_PROCESS(); \
+ } \
+ } while (0)
+
+#endif /* !SLJIT_ASSERT */
+
+#ifndef SLJIT_ASSERT_STOP
+
+#define SLJIT_ASSERT_STOP() \
+ do { \
+ printf("Should never been reached " __FILE__ ":%d\n", __LINE__); \
+ SLJIT_HALT_PROCESS(); \
+ } while (0)
+
+#endif /* !SLJIT_ASSERT_STOP */
+
+#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
+
+#undef SLJIT_ASSERT
+#undef SLJIT_ASSERT_STOP
+
+#define SLJIT_ASSERT(x) \
+ do { } while (0)
+#define SLJIT_ASSERT_STOP() \
+ do { } while (0)
+
+#endif /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
+
+#ifndef SLJIT_COMPILE_ASSERT
+
+/* Should be improved eventually. */
+#define SLJIT_COMPILE_ASSERT(x, description) \
+ SLJIT_ASSERT(x)
+
+#endif /* !SLJIT_COMPILE_ASSERT */
+
+#endif
diff --git a/src/3rdparty/pcre/sljit/sljitExecAllocator.c b/src/3rdparty/pcre/sljit/sljitExecAllocator.c
new file mode 100644
index 00000000000..f66744df826
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitExecAllocator.c
@@ -0,0 +1,277 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ This file contains a simple executable memory allocator
+
+ It is assumed, that executable code blocks are usually medium (or sometimes
+ large) memory blocks, and the allocator is not too frequently called (less
+ optimized than other allocators). Thus, using it as a generic allocator is
+ not suggested.
+
+ How does it work:
+ Memory is allocated in continuous memory areas called chunks by alloc_chunk()
+ Chunk format:
+ [ block ][ block ] ... [ block ][ block terminator ]
+
+ All blocks and the block terminator is started with block_header. The block
+ header contains the size of the previous and the next block. These sizes
+ can also contain special values.
+ Block size:
+ 0 - The block is a free_block, with a different size member.
+ 1 - The block is a block terminator.
+ n - The block is used at the moment, and the value contains its size.
+ Previous block size:
+ 0 - This is the first block of the memory chunk.
+ n - The size of the previous block.
+
+ Using these size values we can go forward or backward on the block chain.
+ The unused blocks are stored in a chain list pointed by free_blocks. This
+ list is useful if we need to find a suitable memory area when the allocator
+ is called.
+
+ When a block is freed, the new free block is connected to its adjacent free
+ blocks if possible.
+
+ [ free block ][ used block ][ free block ]
+ and "used block" is freed, the three blocks are connected together:
+ [ one big free block ]
+*/
+
+/* --------------------------------------------------------------------- */
+/* System (OS) functions */
+/* --------------------------------------------------------------------- */
+
+/* 64 KByte. */
+#define CHUNK_SIZE 0x10000
+
+/*
+ alloc_chunk / free_chunk :
+ * allocate executable system memory chunks
+ * the size is always divisible by CHUNK_SIZE
+ allocator_grab_lock / allocator_release_lock :
+ * make the allocator thread safe
+ * can be empty if the OS (or the application) does not support threading
+ * only the allocator requires this lock, sljit is fully thread safe
+ as it only uses local variables
+*/
+
+#ifdef _WIN32
+
+static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
+{
+ return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+}
+
+static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
+{
+ SLJIT_UNUSED_ARG(size);
+ VirtualFree(chunk, 0, MEM_RELEASE);
+}
+
+#else
+
+#include
+
+static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
+{
+ void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
+ return (retval != MAP_FAILED) ? retval : NULL;
+}
+
+static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
+{
+ munmap(chunk, size);
+}
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Common functions */
+/* --------------------------------------------------------------------- */
+
+#define CHUNK_MASK (~(CHUNK_SIZE - 1))
+
+struct block_header {
+ sljit_uw size;
+ sljit_uw prev_size;
+};
+
+struct free_block {
+ struct block_header header;
+ struct free_block *next;
+ struct free_block *prev;
+ sljit_uw size;
+};
+
+#define AS_BLOCK_HEADER(base, offset) \
+ ((struct block_header*)(((sljit_ub*)base) + offset))
+#define AS_FREE_BLOCK(base, offset) \
+ ((struct free_block*)(((sljit_ub*)base) + offset))
+#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header)))
+#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7)
+
+static struct free_block* free_blocks;
+static sljit_uw allocated_size;
+static sljit_uw total_size;
+
+static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
+{
+ free_block->header.size = 0;
+ free_block->size = size;
+
+ free_block->next = free_blocks;
+ free_block->prev = 0;
+ if (free_blocks)
+ free_blocks->prev = free_block;
+ free_blocks = free_block;
+}
+
+static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
+{
+ if (free_block->next)
+ free_block->next->prev = free_block->prev;
+
+ if (free_block->prev)
+ free_block->prev->next = free_block->next;
+ else {
+ SLJIT_ASSERT(free_blocks == free_block);
+ free_blocks = free_block->next;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+ struct block_header *header;
+ struct block_header *next_header;
+ struct free_block *free_block;
+ sljit_uw chunk_size;
+
+ allocator_grab_lock();
+ if (size < sizeof(struct free_block))
+ size = sizeof(struct free_block);
+ size = ALIGN_SIZE(size);
+
+ free_block = free_blocks;
+ while (free_block) {
+ if (free_block->size >= size) {
+ chunk_size = free_block->size;
+ if (chunk_size > size + 64) {
+ /* We just cut a block from the end of the free block. */
+ chunk_size -= size;
+ free_block->size = chunk_size;
+ header = AS_BLOCK_HEADER(free_block, chunk_size);
+ header->prev_size = chunk_size;
+ AS_BLOCK_HEADER(header, size)->prev_size = size;
+ }
+ else {
+ sljit_remove_free_block(free_block);
+ header = (struct block_header*)free_block;
+ size = chunk_size;
+ }
+ allocated_size += size;
+ header->size = size;
+ allocator_release_lock();
+ return MEM_START(header);
+ }
+ free_block = free_block->next;
+ }
+
+ chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
+ header = (struct block_header*)alloc_chunk(chunk_size);
+ PTR_FAIL_IF(!header);
+
+ chunk_size -= sizeof(struct block_header);
+ total_size += chunk_size;
+
+ header->prev_size = 0;
+ if (chunk_size > size + 64) {
+ /* Cut the allocated space into a free and a used block. */
+ allocated_size += size;
+ header->size = size;
+ chunk_size -= size;
+
+ free_block = AS_FREE_BLOCK(header, size);
+ free_block->header.prev_size = size;
+ sljit_insert_free_block(free_block, chunk_size);
+ next_header = AS_BLOCK_HEADER(free_block, chunk_size);
+ }
+ else {
+ /* All space belongs to this allocation. */
+ allocated_size += chunk_size;
+ header->size = chunk_size;
+ next_header = AS_BLOCK_HEADER(header, chunk_size);
+ }
+ next_header->size = 1;
+ next_header->prev_size = chunk_size;
+ allocator_release_lock();
+ return MEM_START(header);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ struct block_header *header;
+ struct free_block* free_block;
+
+ allocator_grab_lock();
+ header = AS_BLOCK_HEADER(ptr, -(sljit_w)sizeof(struct block_header));
+ allocated_size -= header->size;
+
+ /* Connecting free blocks together if possible. */
+
+ /* If header->prev_size == 0, free_block will equal to header.
+ In this case, free_block->header.size will be > 0. */
+ free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size);
+ if (SLJIT_UNLIKELY(!free_block->header.size)) {
+ free_block->size += header->size;
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ header->prev_size = free_block->size;
+ }
+ else {
+ free_block = (struct free_block*)header;
+ sljit_insert_free_block(free_block, header->size);
+ }
+
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ if (SLJIT_UNLIKELY(!header->size)) {
+ free_block->size += ((struct free_block*)header)->size;
+ sljit_remove_free_block((struct free_block*)header);
+ header = AS_BLOCK_HEADER(free_block, free_block->size);
+ header->prev_size = free_block->size;
+ }
+
+ /* The whole chunk is free. */
+ if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
+ /* If this block is freed, we still have (allocated_size / 2) free space. */
+ if (total_size - free_block->size > (allocated_size * 3 / 2)) {
+ total_size -= free_block->size;
+ sljit_remove_free_block(free_block);
+ free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ }
+ }
+
+ allocator_release_lock();
+}
diff --git a/src/3rdparty/pcre/sljit/sljitLir.c b/src/3rdparty/pcre/sljit/sljitLir.c
new file mode 100644
index 00000000000..c1fa5e4af93
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitLir.c
@@ -0,0 +1,1594 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "sljitLir.h"
+
+#define CHECK_ERROR() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return compiler->error; \
+ } while (0)
+
+#define CHECK_ERROR_PTR() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return NULL; \
+ } while (0)
+
+#define CHECK_ERROR_VOID() \
+ do { \
+ if (SLJIT_UNLIKELY(compiler->error)) \
+ return; \
+ } while (0)
+
+#define FAIL_IF(expr) \
+ do { \
+ if (SLJIT_UNLIKELY(expr)) \
+ return compiler->error; \
+ } while (0)
+
+#define PTR_FAIL_IF(expr) \
+ do { \
+ if (SLJIT_UNLIKELY(expr)) \
+ return NULL; \
+ } while (0)
+
+#define FAIL_IF_NULL(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_ALLOC_FAILED; \
+ return SLJIT_ERR_ALLOC_FAILED; \
+ } \
+ } while (0)
+
+#define PTR_FAIL_IF_NULL(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_ALLOC_FAILED; \
+ return NULL; \
+ } \
+ } while (0)
+
+#define PTR_FAIL_WITH_EXEC_IF(ptr) \
+ do { \
+ if (SLJIT_UNLIKELY(!(ptr))) { \
+ compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
+ return NULL; \
+ } \
+ } while (0)
+
+#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#define GET_OPCODE(op) \
+ ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+
+#define GET_FLAGS(op) \
+ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))
+
+#define GET_ALL_FLAGS(op) \
+ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+
+#define BUF_SIZE 4096
+
+#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
+#define ABUF_SIZE 2048
+#else
+#define ABUF_SIZE 4096
+#endif
+
+/* Jump flags. */
+#define JUMP_LABEL 0x1
+#define JUMP_ADDR 0x2
+/* SLJIT_REWRITABLE_JUMP is 0x1000. */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #define PATCH_MB 0x4
+ #define PATCH_MW 0x8
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #define PATCH_MD 0x10
+#endif
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ #define IS_BL 0x4
+ #define PATCH_B 0x8
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ #define CPOOL_SIZE 512
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ #define IS_CONDITIONAL 0x04
+ #define IS_BL 0x08
+ /* cannot be encoded as branch */
+ #define B_TYPE0 0x00
+ /* conditional + imm8 */
+ #define B_TYPE1 0x10
+ /* conditional + imm20 */
+ #define B_TYPE2 0x20
+ /* IT + imm24 */
+ #define B_TYPE3 0x30
+ /* imm11 */
+ #define B_TYPE4 0x40
+ /* imm24 */
+ #define B_TYPE5 0x50
+ /* BL + imm24 */
+ #define BL_TYPE6 0x60
+ /* 0xf00 cc code for branches */
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ #define UNCOND_B 0x04
+ #define PATCH_B 0x08
+ #define ABSOLUTE_B 0x10
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #define IS_MOVABLE 0x04
+ #define IS_JAL 0x08
+ #define IS_BIT26_COND 0x10
+ #define IS_BIT16_COND 0x20
+
+ #define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
+
+ #define PATCH_B 0x40
+ #define PATCH_J 0x80
+
+ /* instruction types */
+ #define UNMOVABLE_INS 0
+ /* 1 - 31 last destination register */
+ #define FCSR_FCC 32
+ /* no destination (i.e: store) */
+ #define MOVABLE_INS 33
+#endif
+
+#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
+
+/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
+#include "sljitUtils.c"
+
+#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+#include "sljitExecAllocator.c"
+#endif
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) && !(defined SLJIT_SSE2 && SLJIT_SSE2)
+#error SLJIT_SSE2_AUTO cannot be enabled without SLJIT_SSE2
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Public functions */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || ((defined SLJIT_SSE2 && SLJIT_SSE2) && ((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)))
+#define SLJIT_NEEDS_COMPILER_INIT 1
+static int compiler_initialized = 0;
+/* A thread safe initialization. */
+static void init_compiler(void);
+#endif
+
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
+{
+ struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler));
+ if (!compiler)
+ return NULL;
+ SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
+
+ SLJIT_COMPILE_ASSERT(
+ sizeof(sljit_b) == 1 && sizeof(sljit_ub) == 1
+ && sizeof(sljit_h) == 2 && sizeof(sljit_uh) == 2
+ && sizeof(sljit_i) == 4 && sizeof(sljit_ui) == 4
+ && ((sizeof(sljit_w) == 4 && sizeof(sljit_uw) == 4) || (sizeof(sljit_w) == 8 && sizeof(sljit_uw) == 8)),
+ invalid_integer_types);
+
+ /* Only the non-zero members must be set. */
+ compiler->error = SLJIT_SUCCESS;
+
+ compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
+ compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
+
+ if (!compiler->buf || !compiler->abuf) {
+ if (compiler->buf)
+ SLJIT_FREE(compiler->buf);
+ if (compiler->abuf)
+ SLJIT_FREE(compiler->abuf);
+ SLJIT_FREE(compiler);
+ return NULL;
+ }
+
+ compiler->buf->next = NULL;
+ compiler->buf->used_size = 0;
+ compiler->abuf->next = NULL;
+ compiler->abuf->used_size = 0;
+
+ compiler->temporaries = -1;
+ compiler->saveds = -1;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->args = -1;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_ub));
+ if (!compiler->cpool) {
+ SLJIT_FREE(compiler->buf);
+ SLJIT_FREE(compiler->abuf);
+ SLJIT_FREE(compiler);
+ return NULL;
+ }
+ compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE);
+ compiler->cpool_diff = 0xffffffff;
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ compiler->delay_slot = UNMOVABLE_INS;
+#endif
+
+#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
+ if (!compiler_initialized) {
+ init_compiler();
+ compiler_initialized = 1;
+ }
+#endif
+
+ return compiler;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ struct sljit_memory_fragment *curr;
+
+ buf = compiler->buf;
+ while (buf) {
+ curr = buf;
+ buf = buf->next;
+ SLJIT_FREE(curr);
+ }
+
+ buf = compiler->abuf;
+ while (buf) {
+ curr = buf;
+ buf = buf->next;
+ SLJIT_FREE(curr);
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_FREE(compiler->cpool);
+#endif
+ SLJIT_FREE(compiler);
+}
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ /* Remove thumb mode flag. */
+ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
+}
+#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ /* Resolve indirection. */
+ code = (void*)(*(sljit_uw*)code);
+ SLJIT_FREE_EXEC(code);
+}
+#else
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ SLJIT_FREE_EXEC(code);
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
+{
+ if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
+ jump->flags &= ~JUMP_ADDR;
+ jump->flags |= JUMP_LABEL;
+ jump->u.label = label;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
+{
+ if (SLJIT_LIKELY(!!jump)) {
+ SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP);
+
+ jump->flags &= ~JUMP_LABEL;
+ jump->flags |= JUMP_ADDR;
+ jump->u.target = target;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Private functions */
+/* --------------------------------------------------------------------- */
+
+static void* ensure_buf(struct sljit_compiler *compiler, int size)
+{
+ sljit_ub *ret;
+ struct sljit_memory_fragment *new_frag;
+
+ if (compiler->buf->used_size + size <= (int)(BUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) {
+ ret = compiler->buf->memory + compiler->buf->used_size;
+ compiler->buf->used_size += size;
+ return ret;
+ }
+ new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE);
+ PTR_FAIL_IF_NULL(new_frag);
+ new_frag->next = compiler->buf;
+ compiler->buf = new_frag;
+ new_frag->used_size = size;
+ return new_frag->memory;
+}
+
+static void* ensure_abuf(struct sljit_compiler *compiler, int size)
+{
+ sljit_ub *ret;
+ struct sljit_memory_fragment *new_frag;
+
+ if (compiler->abuf->used_size + size <= (int)(ABUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) {
+ ret = compiler->abuf->memory + compiler->abuf->used_size;
+ compiler->abuf->used_size += size;
+ return ret;
+ }
+ new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE);
+ PTR_FAIL_IF_NULL(new_frag);
+ new_frag->next = compiler->abuf;
+ compiler->abuf = new_frag;
+ new_frag->used_size = size;
+ return new_frag->memory;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size)
+{
+ CHECK_ERROR_PTR();
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ if (size <= 0 || size > 128)
+ return NULL;
+ size = (size + 7) & ~7;
+#else
+ if (size <= 0 || size > 64)
+ return NULL;
+ size = (size + 3) & ~3;
+#endif
+ return ensure_abuf(compiler, size);
+}
+
+static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf = compiler->buf;
+ struct sljit_memory_fragment *prev = NULL;
+ struct sljit_memory_fragment *tmp;
+
+ do {
+ tmp = buf->next;
+ buf->next = prev;
+ prev = buf;
+ buf = tmp;
+ } while (buf != NULL);
+
+ compiler->buf = prev;
+}
+
+static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
+{
+ label->next = NULL;
+ label->size = compiler->size;
+ if (compiler->last_label)
+ compiler->last_label->next = label;
+ else
+ compiler->labels = label;
+ compiler->last_label = label;
+}
+
+static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, int flags)
+{
+ jump->next = NULL;
+ jump->flags = flags;
+ if (compiler->last_jump)
+ compiler->last_jump->next = jump;
+ else
+ compiler->jumps = jump;
+ compiler->last_jump = jump;
+}
+
+static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
+{
+ const_->next = NULL;
+ const_->addr = compiler->size;
+ if (compiler->last_const)
+ compiler->last_const->next = const_;
+ else
+ compiler->consts = const_;
+ compiler->last_const = const_;
+}
+
+#define ADDRESSING_DEPENDS_ON(exp, reg) \
+ (((exp) & SLJIT_MEM) && (((exp) & 0xf) == reg || (((exp) >> 4) & 0xf) == reg))
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+#define FUNCTION_CHECK_OP() \
+ SLJIT_ASSERT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \
+ switch (GET_OPCODE(op)) { \
+ case SLJIT_NOT: \
+ case SLJIT_CLZ: \
+ case SLJIT_AND: \
+ case SLJIT_OR: \
+ case SLJIT_XOR: \
+ case SLJIT_SHL: \
+ case SLJIT_LSHR: \
+ case SLJIT_ASHR: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_NEG: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_MUL: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
+ break; \
+ case SLJIT_FCMP: \
+ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \
+ break; \
+ case SLJIT_ADD: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \
+ break; \
+ case SLJIT_SUB: \
+ break; \
+ case SLJIT_ADDC: \
+ case SLJIT_SUBC: \
+ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \
+ break; \
+ default: \
+ /* Nothing allowed */ \
+ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
+ break; \
+ }
+
+#define FUNCTION_CHECK_IS_REG(r) \
+ ((r) == SLJIT_UNUSED || (r) == SLJIT_LOCALS_REG || \
+ ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG3 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
+ ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG3 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) \
+
+#define FUNCTION_CHECK_SRC(p, i) \
+ SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \
+ if (((p) >= SLJIT_TEMPORARY_REG1 && (p) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
+ ((p) >= SLJIT_SAVED_REG1 && (p) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds) || \
+ (p) == SLJIT_LOCALS_REG) \
+ SLJIT_ASSERT(i == 0); \
+ else if ((p) == SLJIT_IMM) \
+ ; \
+ else if ((p) & SLJIT_MEM) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
+ if ((p) & 0xf0) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
+ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
+ } else \
+ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
+ SLJIT_ASSERT(((p) >> 9) == 0); \
+ } \
+ else \
+ SLJIT_ASSERT_STOP();
+
+#define FUNCTION_CHECK_DST(p, i) \
+ SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \
+ if (((p) >= SLJIT_TEMPORARY_REG1 && (p) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \
+ ((p) >= SLJIT_SAVED_REG1 && (p) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds) || \
+ (p) == SLJIT_UNUSED) \
+ SLJIT_ASSERT(i == 0); \
+ else if ((p) & SLJIT_MEM) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
+ if ((p) & 0xf0) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
+ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
+ } else \
+ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
+ SLJIT_ASSERT(((p) >> 9) == 0); \
+ } \
+ else \
+ SLJIT_ASSERT_STOP();
+
+#define FUNCTION_FCHECK(p, i) \
+ if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG4) \
+ SLJIT_ASSERT(i == 0); \
+ else if ((p) & SLJIT_MEM) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \
+ if ((p) & 0xf0) { \
+ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG(((p) >> 4) & 0xf)); \
+ SLJIT_ASSERT(((p) & 0xf0) != (SLJIT_LOCALS_REG << 4) && !(i & ~0x3)); \
+ } else \
+ SLJIT_ASSERT((((p) >> 4) & 0xf) == 0); \
+ SLJIT_ASSERT(((p) >> 9) == 0); \
+ } \
+ else \
+ SLJIT_ASSERT_STOP();
+
+#define FUNCTION_CHECK_OP1() \
+ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \
+ SLJIT_ASSERT(!GET_ALL_FLAGS(op)); \
+ } \
+ if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \
+ SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \
+ SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \
+ if ((src & SLJIT_MEM) && (src & 0xf)) \
+ SLJIT_ASSERT((dst & 0xf) != (src & 0xf) && ((dst >> 4) & 0xf) != (src & 0xf)); \
+ }
+
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
+{
+ compiler->verbose = verbose;
+}
+
+static char* reg_names[] = {
+ (char*)"", (char*)"t1", (char*)"t2", (char*)"t3",
+ (char*)"te1", (char*)"te2", (char*)"s1", (char*)"s2",
+ (char*)"s3", (char*)"se1", (char*)"se2", (char*)"lcr"
+};
+
+static char* freg_names[] = {
+ (char*)"", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", (char*)"float_r4"
+};
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#ifdef _WIN64
+ #define SLJIT_PRINT_D "I64"
+#else
+ #define SLJIT_PRINT_D "l"
+#endif
+#else
+ #define SLJIT_PRINT_D ""
+#endif
+
+#define sljit_verbose_param(p, i) \
+ if ((p) & SLJIT_IMM) \
+ fprintf(compiler->verbose, "#%"SLJIT_PRINT_D"d", (i)); \
+ else if ((p) & SLJIT_MEM) { \
+ if ((p) & 0xf) { \
+ if (i) { \
+ if (((p) >> 4) & 0xf) \
+ fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
+ else \
+ fprintf(compiler->verbose, "[%s + #%"SLJIT_PRINT_D"d]", reg_names[(p) & 0xF], (i)); \
+ } \
+ else { \
+ if (((p) >> 4) & 0xf) \
+ fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
+ else \
+ fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
+ } \
+ } \
+ else \
+ fprintf(compiler->verbose, "[#%"SLJIT_PRINT_D"d]", (i)); \
+ } else \
+ fprintf(compiler->verbose, "%s", reg_names[p]);
+#define sljit_verbose_fparam(p, i) \
+ if ((p) & SLJIT_MEM) { \
+ if ((p) & 0xf) { \
+ if (i) { \
+ if (((p) >> 4) & 0xf) \
+ fprintf(compiler->verbose, "[%s + %s * %d]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF], 1 << (i)); \
+ else \
+ fprintf(compiler->verbose, "[%s + #%"SLJIT_PRINT_D"d]", reg_names[(p) & 0xF], (i)); \
+ } \
+ else { \
+ if (((p) >> 4) & 0xF) \
+ fprintf(compiler->verbose, "[%s + %s]", reg_names[(p) & 0xF], reg_names[((p) >> 4)& 0xF]); \
+ else \
+ fprintf(compiler->verbose, "[%s]", reg_names[(p) & 0xF]); \
+ } \
+ } \
+ else \
+ fprintf(compiler->verbose, "[#%"SLJIT_PRINT_D"d]", (i)); \
+ } else \
+ fprintf(compiler->verbose, "%s", freg_names[p]);
+
+static SLJIT_CONST char* op_names[] = {
+ /* op0 */
+ (char*)"breakpoint", (char*)"nop",
+ (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv",
+ /* op1 */
+ (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh",
+ (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"movu",
+ (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", (char*)"movu.sh",
+ (char*)"movu.ui", (char*)"movu.si", (char*)"not", (char*)"neg",
+ (char*)"clz",
+ /* op2 */
+ (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc",
+ (char*)"mul", (char*)"and", (char*)"or", (char*)"xor",
+ (char*)"shl", (char*)"lshr", (char*)"ashr",
+ /* fop1 */
+ (char*)"fcmp", (char*)"fmov", (char*)"fneg", (char*)"fabs",
+ /* fop2 */
+ (char*)"fadd", (char*)"fsub", (char*)"fmul", (char*)"fdiv"
+};
+
+static char* jump_names[] = {
+ (char*)"c_equal", (char*)"c_not_equal",
+ (char*)"c_less", (char*)"c_greater_equal",
+ (char*)"c_greater", (char*)"c_less_equal",
+ (char*)"c_sig_less", (char*)"c_sig_greater_equal",
+ (char*)"c_sig_greater", (char*)"c_sig_less_equal",
+ (char*)"c_overflow", (char*)"c_not_overflow",
+ (char*)"c_mul_overflow", (char*)"c_mul_not_overflow",
+ (char*)"c_float_equal", (char*)"c_float_not_equal",
+ (char*)"c_float_less", (char*)"c_float_greater_equal",
+ (char*)"c_float_greater", (char*)"c_float_less_equal",
+ (char*)"c_float_nan", (char*)"c_float_not_nan",
+ (char*)"jump", (char*)"fast_call",
+ (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
+};
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Arch dependent */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compiler)
+{
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ struct sljit_jump *jump;
+#endif
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+
+ SLJIT_ASSERT(compiler->size > 0);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ jump = compiler->jumps;
+ while (jump) {
+ /* All jumps have target. */
+ SLJIT_ASSERT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
+ jump = jump->next;
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+
+ SLJIT_ASSERT(args >= 0 && args <= 3);
+ SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
+ SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
+ SLJIT_ASSERT(args <= saveds);
+ SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+
+ SLJIT_ASSERT(args >= 0 && args <= 3);
+ SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
+ SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
+ SLJIT_ASSERT(args <= saveds);
+ SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " fake_enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (op != SLJIT_UNUSED) {
+ SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_SI);
+ FUNCTION_CHECK_SRC(src, srcw);
+ }
+ else
+ SLJIT_ASSERT(src == 0 && srcw == 0);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ if (op == SLJIT_UNUSED)
+ fprintf(compiler->verbose, " return\n");
+ else {
+ fprintf(compiler->verbose, " return %s ", op_names[op]);
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+
+ SLJIT_ASSERT(args >= 0 && args <= 3);
+ SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS);
+ SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS);
+ SLJIT_ASSERT(args <= saveds);
+ SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ FUNCTION_CHECK_DST(dst, dstw);
+ compiler->temporaries = -1;
+ compiler->saveds = -1;
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fast_enter ");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, " args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size);
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fast_return ");
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+
+ SLJIT_ASSERT((op >= SLJIT_BREAKPOINT && op <= SLJIT_SMUL)
+ || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIV && (op & ~SLJIT_INT_OP) <= SLJIT_SDIV));
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)]);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CLZ);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_CHECK_SRC(src, srcw);
+ FUNCTION_CHECK_DST(dst, dstw);
+ FUNCTION_CHECK_OP1();
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
+ !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ASHR);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)],
+ !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_get_register_index(int reg)
+{
+ SLJIT_UNUSED_ARG(reg);
+ SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS);
+}
+
+static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(instruction);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT(instruction);
+}
+
+static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(sljit_is_fpu_available());
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FCMP && GET_OPCODE(op) <= SLJIT_FABS);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_FCHECK(src, srcw);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s%s%s ", op_names[GET_OPCODE(op)],
+ !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S");
+ sljit_verbose_fparam(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+ SLJIT_ASSERT(sljit_is_fpu_available());
+ SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FADD && GET_OPCODE(op) <= SLJIT_FDIV);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_OP();
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+ FUNCTION_FCHECK(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s ", op_names[GET_OPCODE(op)]);
+ sljit_verbose_fparam(dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, "label:\n");
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ return;
+ }
+#endif
+
+ SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
+ SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose))
+ fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+ SLJIT_ASSERT(!(type & ~(0xff | SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)));
+ SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
+ sljit_verbose_param(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+
+ SLJIT_ASSERT(sljit_is_fpu_available());
+ SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
+ SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_NOT_NAN);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_FCHECK(src1, src1w);
+ FUNCTION_FCHECK(src2, src2w);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " fcmp%s <%s> ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]);
+ sljit_verbose_fparam(src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_fparam(src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+
+ SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]);
+ sljit_verbose_param(src, srcw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(type);
+
+ SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP);
+ SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_OR);
+ SLJIT_ASSERT(GET_ALL_FLAGS(op) == 0 || GET_ALL_FLAGS(op) == SLJIT_SET_E || GET_ALL_FLAGS(op) == SLJIT_KEEP_FLAGS);
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " cond_set%s%s <%s> ", !(op & SLJIT_SET_E) ? "" : "E",
+ !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]);
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", <%s>\n", jump_names[type]);
+ }
+#endif
+}
+
+static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ /* If debug and verbose are disabled, all arguments are unused. */
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(init_value);
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ FUNCTION_CHECK_DST(dst, dstw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " const ");
+ sljit_verbose_param(dst, dstw);
+ fprintf(compiler->verbose, ", #%"SLJIT_PRINT_D"d\n", init_value);
+ }
+#endif
+}
+
+static SLJIT_INLINE int emit_mov_before_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ /* Return if don't need to do anything. */
+ if (op == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+ if (src == SLJIT_RETURN_REG && op == SLJIT_MOV)
+ return SLJIT_SUCCESS;
+#else
+ if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI))
+ return SLJIT_SUCCESS;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
+}
+
+/* CPU description section */
+
+#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
+#define SLJIT_CPUINFO_PART1 " 32bit ("
+#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#define SLJIT_CPUINFO_PART1 " 64bit ("
+#else
+#error "Internal error: CPU type info missing"
+#endif
+
+#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#define SLJIT_CPUINFO_PART2 "little endian + "
+#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
+#define SLJIT_CPUINFO_PART2 "big endian + "
+#else
+#error "Internal error: CPU type info missing"
+#endif
+
+#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
+#define SLJIT_CPUINFO_PART3 "unaligned)"
+#else
+#define SLJIT_CPUINFO_PART3 "aligned)"
+#endif
+
+#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ #include "sljitNativeX86_common.c"
+#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #include "sljitNativeX86_common.c"
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ #include "sljitNativeARM_v5.c"
+#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ #include "sljitNativeARM_v5.c"
+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ #include "sljitNativeARM_Thumb2.c"
+#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ #include "sljitNativePPC_common.c"
+#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ #include "sljitNativePPC_common.c"
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #include "sljitNativeMIPS_common.c"
+#endif
+
+#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* Default compare for most architectures. */
+ int flags, tmp_src, condition;
+ sljit_w tmp_srcw;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
+
+ condition = type & 0xff;
+ if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
+ /* Immediate is prefered as second argument by most architectures. */
+ switch (condition) {
+ case SLJIT_C_LESS:
+ condition = SLJIT_C_GREATER;
+ break;
+ case SLJIT_C_GREATER_EQUAL:
+ condition = SLJIT_C_LESS_EQUAL;
+ break;
+ case SLJIT_C_GREATER:
+ condition = SLJIT_C_LESS;
+ break;
+ case SLJIT_C_LESS_EQUAL:
+ condition = SLJIT_C_GREATER_EQUAL;
+ break;
+ case SLJIT_C_SIG_LESS:
+ condition = SLJIT_C_SIG_GREATER;
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ condition = SLJIT_C_SIG_LESS_EQUAL;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ condition = SLJIT_C_SIG_LESS;
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ condition = SLJIT_C_SIG_GREATER_EQUAL;
+ break;
+ }
+ type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP));
+ tmp_src = src1;
+ src1 = src2;
+ src2 = tmp_src;
+ tmp_srcw = src1w;
+ src1w = src2w;
+ src2w = tmp_srcw;
+ }
+
+ if (condition <= SLJIT_C_NOT_ZERO)
+ flags = SLJIT_SET_E;
+ else if (condition <= SLJIT_C_LESS_EQUAL)
+ flags = SLJIT_SET_U;
+ else
+ flags = SLJIT_SET_S;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP),
+ SLJIT_UNUSED, 0, src1, src1w, src2, src2w));
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int flags, condition;
+
+ check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
+
+ condition = type & 0xff;
+ if (condition <= SLJIT_C_FLOAT_NOT_EQUAL)
+ flags = SLJIT_SET_E;
+ else
+ flags = SLJIT_SET_S;
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ sljit_emit_fop1(compiler, SLJIT_FCMP | flags, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP));
+}
+
+#endif
+
+#else /* SLJIT_CONFIG_UNSUPPORTED */
+
+/* Empty function bodies for those machines, which are not (yet) supported. */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "unsupported";
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void)
+{
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(verbose);
+ SLJIT_ASSERT_STOP();
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+{
+ SLJIT_UNUSED_ARG(code);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(args);
+ SLJIT_UNUSED_ARG(temporaries);
+ SLJIT_UNUSED_ARG(saveds);
+ SLJIT_UNUSED_ARG(local_size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ SLJIT_ASSERT_STOP();
+ return reg;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(instruction);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ SLJIT_ASSERT_STOP();
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src1);
+ SLJIT_UNUSED_ARG(src1w);
+ SLJIT_UNUSED_ARG(src2);
+ SLJIT_UNUSED_ARG(src2w);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
+{
+ SLJIT_UNUSED_ARG(jump);
+ SLJIT_UNUSED_ARG(label);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
+{
+ SLJIT_UNUSED_ARG(jump);
+ SLJIT_UNUSED_ARG(target);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_UNUSED_ARG(src);
+ SLJIT_UNUSED_ARG(srcw);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(op);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(type);
+ SLJIT_ASSERT_STOP();
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w initval)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ SLJIT_UNUSED_ARG(initval);
+ SLJIT_ASSERT_STOP();
+ return NULL;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(new_addr);
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(new_constant);
+ SLJIT_ASSERT_STOP();
+}
+
+#endif
diff --git a/src/3rdparty/pcre/sljit/sljitLir.h b/src/3rdparty/pcre/sljit/sljitLir.h
new file mode 100644
index 00000000000..0cb1c1e589b
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitLir.h
@@ -0,0 +1,853 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SLJIT_LIR_H_
+#define _SLJIT_LIR_H_
+
+/*
+ ------------------------------------------------------------------------
+ Stack-Less JIT compiler for multiple architectures (x86, ARM, PowerPC)
+ ------------------------------------------------------------------------
+
+ Short description
+ Advantages:
+ - The execution can be continued from any LIR instruction
+ In other words, jump into and out of the code is safe
+ - Both target of (conditional) jump and call instructions
+ and constants can be dynamically modified during runtime
+ - although it is not suggested to do it frequently
+ - very effective to cache an important value once
+ - A fixed stack space can be allocated for local variables
+ - The compiler is thread-safe
+ Disadvantages:
+ - Limited number of registers (only 6+4 integer registers, max 3+2
+ temporary, max 3+2 saved and 4 floating point registers)
+ In practice:
+ - This approach is very effective for interpreters
+ - One of the saved registers typically points to a stack interface
+ - It can jump to any exception handler anytime (even for another
+ function. It is safe for SLJIT.)
+ - Fast paths can be modified during runtime reflecting the changes
+ of the fastest execution path of the dynamic language
+ - SLJIT supports complex memory addressing modes
+ - mainly position independent code
+ - Optimizations (perhaps later)
+ - Only for basic blocks (when no labels inserted between LIR instructions)
+
+ For valgrind users:
+ - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
+*/
+
+#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
+#include "sljitConfig.h"
+#endif
+
+/* The following header file defines useful macros for fine tuning
+sljit based code generators. They are listed in the begining
+of sljitConfigInternal.h */
+
+#include "sljitConfigInternal.h"
+
+/* --------------------------------------------------------------------- */
+/* Error codes */
+/* --------------------------------------------------------------------- */
+
+/* Indicates no error. */
+#define SLJIT_SUCCESS 0
+/* After the call of sljit_generate_code(), the error code of the compiler
+ is set to this value to avoid future sljit calls (in debug mode at least).
+ The complier should be freed after sljit_generate_code(). */
+#define SLJIT_ERR_COMPILED 1
+/* Cannot allocate non executable memory. */
+#define SLJIT_ERR_ALLOC_FAILED 2
+/* Cannot allocate executable memory.
+ Only for sljit_generate_code() */
+#define SLJIT_ERR_EX_ALLOC_FAILED 3
+/* return value for SLJIT_CONFIG_UNSUPPORTED empty architecture. */
+#define SLJIT_ERR_UNSUPPORTED 4
+
+/* --------------------------------------------------------------------- */
+/* Registers */
+/* --------------------------------------------------------------------- */
+
+#define SLJIT_UNUSED 0
+
+/* Temporary (scratch) registers may not preserve their values across function calls. */
+#define SLJIT_TEMPORARY_REG1 1
+#define SLJIT_TEMPORARY_REG2 2
+#define SLJIT_TEMPORARY_REG3 3
+/* Note: Extra Registers cannot be used for memory addressing. */
+/* Note: on x86-32, these registers are emulated (using stack loads & stores). */
+#define SLJIT_TEMPORARY_EREG1 4
+#define SLJIT_TEMPORARY_EREG2 5
+
+/* Saved registers whose preserve their values across function calls. */
+#define SLJIT_SAVED_REG1 6
+#define SLJIT_SAVED_REG2 7
+#define SLJIT_SAVED_REG3 8
+/* Note: Extra Registers cannot be used for memory addressing. */
+/* Note: on x86-32, these registers are emulated (using stack loads & stores). */
+#define SLJIT_SAVED_EREG1 9
+#define SLJIT_SAVED_EREG2 10
+
+/* Read-only register (cannot be the destination of an operation). */
+/* Note: SLJIT_MEM2( ... , SLJIT_LOCALS_REG) is not supported (x86 limitation). */
+/* Note: SLJIT_LOCALS_REG is not necessary the real stack pointer. See sljit_emit_enter. */
+#define SLJIT_LOCALS_REG 11
+
+/* Number of registers. */
+#define SLJIT_NO_TMP_REGISTERS 5
+#define SLJIT_NO_GEN_REGISTERS 5
+#define SLJIT_NO_REGISTERS 11
+
+/* Return with machine word. */
+
+#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1
+
+/* x86 prefers specific registers for special purposes. In case of shift
+ by register it supports only SLJIT_TEMPORARY_REG3 for shift argument
+ (which is the src2 argument of sljit_emit_op2). If another register is
+ used, sljit must exchange data between registers which cause a minor
+ slowdown. Other architectures has no such limitation. */
+
+#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3
+
+/* --------------------------------------------------------------------- */
+/* Floating point registers */
+/* --------------------------------------------------------------------- */
+
+/* Note: SLJIT_UNUSED as destination is not valid for floating point
+ operations, since they cannot be used for setting flags. */
+
+/* Floating point operations are performed on double precision values. */
+
+#define SLJIT_FLOAT_REG1 1
+#define SLJIT_FLOAT_REG2 2
+#define SLJIT_FLOAT_REG3 3
+#define SLJIT_FLOAT_REG4 4
+
+/* --------------------------------------------------------------------- */
+/* Main structures and functions */
+/* --------------------------------------------------------------------- */
+
+struct sljit_memory_fragment {
+ struct sljit_memory_fragment *next;
+ sljit_uw used_size;
+ sljit_ub memory[1];
+};
+
+struct sljit_label {
+ struct sljit_label *next;
+ sljit_uw addr;
+ /* The maximum size difference. */
+ sljit_uw size;
+};
+
+struct sljit_jump {
+ struct sljit_jump *next;
+ sljit_uw addr;
+ sljit_w flags;
+ union {
+ sljit_uw target;
+ struct sljit_label* label;
+ } u;
+};
+
+struct sljit_const {
+ struct sljit_const *next;
+ sljit_uw addr;
+};
+
+struct sljit_compiler {
+ int error;
+
+ struct sljit_label *labels;
+ struct sljit_jump *jumps;
+ struct sljit_const *consts;
+ struct sljit_label *last_label;
+ struct sljit_jump *last_jump;
+ struct sljit_const *last_const;
+
+ struct sljit_memory_fragment *buf;
+ struct sljit_memory_fragment *abuf;
+
+ /* Used local registers. */
+ int temporaries;
+ /* Used saved registers. */
+ int saveds;
+ /* Local stack size. */
+ int local_size;
+ /* Code size. */
+ sljit_uw size;
+ /* For statistical purposes. */
+ sljit_uw executable_size;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ int args;
+ int temporaries_start;
+ int saveds_start;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int mode32;
+#ifdef _WIN64
+ int has_locals;
+#endif
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int flags_saved;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ /* Constant pool handling. */
+ sljit_uw *cpool;
+ sljit_ub *cpool_unique;
+ sljit_uw cpool_diff;
+ sljit_uw cpool_fill;
+ /* Other members. */
+ /* Contains pointer, "ldr pc, [...]" pairs. */
+ sljit_uw patches;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ /* Temporary fields. */
+ sljit_uw shift_imm;
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ int has_locals;
+ sljit_w imm;
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ int has_locals;
+ int delay_slot;
+ int cache_arg;
+ sljit_w cache_argw;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ FILE* verbose;
+#endif
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ int skip_checks;
+#endif
+};
+
+/* --------------------------------------------------------------------- */
+/* Main functions */
+/* --------------------------------------------------------------------- */
+
+/* Creates an sljit compiler.
+ Returns NULL if failed. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
+/* Free everything except the codes. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
+
+static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
+
+/*
+ Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
+ and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler,
+ and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned.
+ Excellent for allocating small blocks during the compiling, and no need to worry
+ about freeing them. The size is enough to contain at most 16 pointers.
+ If the size is outside of the range, the function will return with NULL,
+ but this return value does not indicate that there is no more memory (does
+ not set the compiler to out-of-memory status).
+*/
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size);
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+/* Passing NULL disables verbose. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
+
+/*
+ After the code generation we can retrieve the allocated executable memory size,
+ although this area may not be fully filled with instructions depending on some
+ optimizations. This function is useful only for statistical purposes.
+
+ Before a successful code generation, this function returns with 0.
+*/
+static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
+
+/* Instruction generation. Returns with error code. */
+
+/*
+ The executable code is basically a function call from the viewpoint of
+ the C language. The function calls must obey to the ABI (Application
+ Binary Interface) of the platform, which specify the purpose of machine
+ registers and stack handling among other things. The sljit_emit_enter
+ function emits the necessary instructions for setting up a new context
+ for the executable code and moves function arguments to the saved
+ registers. The number of arguments are specified in the "args"
+ parameter and the first argument goes to SLJIT_SAVED_REG1, the second
+ goes to SLJIT_SAVED_REG2 and so on. The number of temporary and
+ saved registers are passed in "temporaries" and "saveds" arguments
+ respectively. Since the saved registers contains the arguments,
+ "args" must be less or equal than "saveds". The sljit_emit_enter
+ is also capable of allocating a stack space for local variables. The
+ "local_size" argument contains the size in bytes of this local area
+ and its staring address is stored in SLJIT_LOCALS_REG. However
+ the SLJIT_LOCALS_REG is not necessary the machine stack pointer.
+ The memory bytes between SLJIT_LOCALS_REG (inclusive) and
+ SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
+ until the function returns. The stack space is uninitialized.
+
+ Note: every call of sljit_emit_enter and sljit_set_context overwrites
+ the previous context. */
+
+#define SLJIT_MAX_LOCAL_SIZE 65536
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler,
+ int args, int temporaries, int saveds, int local_size);
+
+/* The machine code has a context (which contains the local stack space size,
+ number of used registers, etc.) which initialized by sljit_emit_enter. Several
+ functions (like sljit_emit_return) requres this context to be able to generate
+ the appropriate code. However, some code fragments (like inline cache) may have
+ no normal entry point so their context is unknown for the compiler. Using the
+ function below we can specify thir context.
+
+ Note: every call of sljit_emit_enter and sljit_set_context overwrites
+ the previous context. */
+
+/* Note: multiple calls of this function overwrites the previous call. */
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
+ int args, int temporaries, int saveds, int local_size);
+
+/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
+ function does not return with anything or any opcode between SLJIT_MOV and
+ SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op
+ is SLJIT_UNUSED, otherwise see below the description about source and
+ destination arguments. */
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op,
+ int src, sljit_w srcw);
+
+/* Really fast calling method for utility functions inside sljit (see SLJIT_FAST_CALL).
+ All registers and even the stack frame is passed to the callee. The return address is
+ preserved in dst/dstw by sljit_emit_fast_enter, and sljit_emit_fast_return can
+ use this as a return value later. */
+
+/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine instructions
+ are needed. Excellent for small uility functions, where saving registers and setting up
+ a new stack frame would cost too much performance. However, it is still possible to return
+ to the address of the caller (or anywhere else). */
+
+/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
+
+/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
+ since many architectures do clever branch prediction on call / return instruction pairs. */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size);
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw);
+
+/*
+ Source and destination values for arithmetical instructions
+ imm - a simple immediate value (cannot be used as a destination)
+ reg - any of the registers (immediate argument must be 0)
+ [imm] - absolute immediate memory address
+ [reg+imm] - indirect memory address
+ [reg+(reg<addr; }
+static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
+static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
+
+/* Only the address is required to rewrite the code. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant);
+
+/* --------------------------------------------------------------------- */
+/* Miscellaneous utility functions */
+/* --------------------------------------------------------------------- */
+
+#define SLJIT_MAJOR_VERSION 0
+#define SLJIT_MINOR_VERSION 87
+
+/* Get the human readable name of the platfrom.
+ Can be useful for debugging on platforms like ARM, where ARM and
+ Thumb2 functions can be mixed. */
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
+
+/* Portble helper function to get an offset of a member. */
+#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10)
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+/* This global lock is useful to compile common functions. */
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void);
+#endif
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+
+/* The sljit_stack is a utiliy feature of sljit, which allocates a
+ writable memory region between base (inclusive) and limit (exclusive).
+ Both base and limit is a pointer, and base is always <= than limit.
+ This feature uses the "address space reserve" feature
+ of modern operating systems. Basically we don't need to allocate a
+ huge memory block in one step for the worst case, we can start with
+ a smaller chunk and extend it later. Since the address space is
+ reserved, the data never copied to other regions, thus it is safe
+ to store pointers here. */
+
+/* Note: The base field is aligned to PAGE_SIZE bytes (usually 4k or more).
+ Note: stack growing should not happen in small steps: 4k, 16k or even
+ bigger growth is better.
+ Note: this structure may not be supported by all operating systems.
+ Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
+ is not defined. */
+
+struct sljit_stack {
+ /* User data, anything can be stored here.
+ Starting with the same value as base. */
+ sljit_uw top;
+ /* These members are read only. */
+ sljit_uw base;
+ sljit_uw limit;
+ sljit_uw max_limit;
+};
+
+/* Returns NULL if unsuccessful.
+ Note: limit and max_limit contains the size for stack allocation
+ Note: the top field is initialized to base. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit);
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack);
+
+/* Can be used to increase (allocate) or decrease (free) the memory area.
+ Returns with a non-zero value if unsuccessful. If new_limit is greater than
+ max_limit, it will fail. It is very easy to implement a stack data structure,
+ since the growth ratio can be added to the current limit, and sljit_stack_resize
+ will do all the necessary checks. The fields of the stack are not changed if
+ sljit_stack_resize fails. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
+
+#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
+
+#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+
+/* Get the entry address of a given function. */
+#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)func_name)
+
+#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
+
+/* All JIT related code should be placed in the same context (library, binary, etc.). */
+
+#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name)
+
+/* For powerpc64, the function pointers point to a context descriptor. */
+struct sljit_function_context {
+ sljit_w addr;
+ sljit_w r2;
+ sljit_w r11;
+};
+
+/* Fill the context arguments using the addr and the function.
+ If func_ptr is NULL, it will not be set to the address of context
+ If addr is NULL, the function address also comes from the func pointer. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func);
+
+#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
+
+#endif /* _SLJIT_LIR_H_ */
diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c b/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
new file mode 100644
index 00000000000..a51536b4a74
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
@@ -0,0 +1,1913 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "ARM-Thumb2" SLJIT_CPUINFO;
+}
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define TMP_PC (SLJIT_NO_REGISTERS + 4)
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
+ 0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15
+};
+
+#define COPY_BITS(src, from, to, bits) \
+ ((from >= to ? (src >> (from - to)) : (src << (to - from))) & (((1 << bits) - 1) << to))
+
+/* Thumb16 encodings. */
+#define RD3(rd) (reg_map[rd])
+#define RN3(rn) (reg_map[rn] << 3)
+#define RM3(rm) (reg_map[rm] << 6)
+#define RDN3(rdn) (reg_map[rdn] << 8)
+#define IMM3(imm) (imm << 6)
+#define IMM8(imm) (imm)
+
+/* Thumb16 helpers. */
+#define SET_REGS44(rd, rn) \
+ ((reg_map[rn] << 3) | (reg_map[rd] & 0x7) | ((reg_map[rd] & 0x8) << 4))
+#define IS_2_LO_REGS(reg1, reg2) \
+ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7)
+#define IS_3_LO_REGS(reg1, reg2, reg3) \
+ (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7)
+
+/* Thumb32 encodings. */
+#define RD4(rd) (reg_map[rd] << 8)
+#define RN4(rn) (reg_map[rn] << 16)
+#define RM4(rm) (reg_map[rm])
+#define RT4(rt) (reg_map[rt] << 12)
+#define DD4(dd) ((dd) << 12)
+#define DN4(dn) ((dn) << 16)
+#define DM4(dm) (dm)
+#define IMM5(imm) \
+ (COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6))
+#define IMM12(imm) \
+ (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))
+
+typedef sljit_ui sljit_ins;
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+/* dot '.' changed to _
+ I immediate form (possibly followed by number of immediate bits). */
+#define ADCI 0xf1400000
+#define ADCS 0x4140
+#define ADC_W 0xeb400000
+#define ADD 0x4400
+#define ADDS 0x1800
+#define ADDSI3 0x1c00
+#define ADDSI8 0x3000
+#define ADD_W 0xeb000000
+#define ADDWI 0xf2000000
+#define ADD_SP 0xb000
+#define ADD_W 0xeb000000
+#define ADD_WI 0xf1000000
+#define ANDI 0xf0000000
+#define ANDS 0x4000
+#define AND_W 0xea000000
+#define ASRS 0x4100
+#define ASRSI 0x1000
+#define ASR_W 0xfa40f000
+#define ASR_WI 0xea4f0020
+#define BICI 0xf0200000
+#define BKPT 0xbe00
+#define BLX 0x4780
+#define BX 0x4700
+#define CLZ 0xfab0f080
+#define CMPI 0x2800
+#define CMP_W 0xebb00f00
+#define EORI 0xf0800000
+#define EORS 0x4040
+#define EOR_W 0xea800000
+#define IT 0xbf00
+#define LSLS 0x4080
+#define LSLSI 0x0000
+#define LSL_W 0xfa00f000
+#define LSL_WI 0xea4f0000
+#define LSRS 0x40c0
+#define LSRSI 0x0800
+#define LSR_W 0xfa20f000
+#define LSR_WI 0xea4f0010
+#define MOV 0x4600
+#define MOVS 0x0000
+#define MOVSI 0x2000
+#define MOVT 0xf2c00000
+#define MOVW 0xf2400000
+#define MOV_W 0xea4f0000
+#define MOV_WI 0xf04f0000
+#define MUL 0xfb00f000
+#define MVNS 0x43c0
+#define MVN_W 0xea6f0000
+#define MVN_WI 0xf06f0000
+#define NOP 0xbf00
+#define ORNI 0xf0600000
+#define ORRI 0xf0400000
+#define ORRS 0x4300
+#define ORR_W 0xea400000
+#define POP 0xbd00
+#define POP_W 0xe8bd0000
+#define PUSH 0xb500
+#define PUSH_W 0xe92d0000
+#define RSB_WI 0xf1c00000
+#define RSBSI 0x4240
+#define SBCI 0xf1600000
+#define SBCS 0x4180
+#define SBC_W 0xeb600000
+#define SMULL 0xfb800000
+#define STR_SP 0x9000
+#define SUBS 0x1a00
+#define SUBSI3 0x1e00
+#define SUBSI8 0x3800
+#define SUB_W 0xeba00000
+#define SUBWI 0xf2a00000
+#define SUB_SP 0xb080
+#define SUB_WI 0xf1a00000
+#define SXTB 0xb240
+#define SXTB_W 0xfa4ff080
+#define SXTH 0xb200
+#define SXTH_W 0xfa0ff080
+#define TST 0x4200
+#define UMULL 0xfba00000
+#define UXTB 0xb2c0
+#define UXTB_W 0xfa5ff080
+#define UXTH 0xb280
+#define UXTH_W 0xfa1ff080
+#define VABS_F64 0xeeb00bc0
+#define VADD_F64 0xee300b00
+#define VCMP_F64 0xeeb40b40
+#define VDIV_F64 0xee800b00
+#define VMOV_F64 0xeeb00b40
+#define VMRS 0xeef1fa10
+#define VMUL_F64 0xee200b00
+#define VNEG_F64 0xeeb10b40
+#define VSTR 0xed000b00
+#define VSUB_F64 0xee300b40
+
+static int push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
+{
+ sljit_uh *ptr;
+ SLJIT_ASSERT(!(inst & 0xffff0000));
+
+ ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh));
+ FAIL_IF(!ptr);
+ *ptr = inst;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
+{
+ sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr++ = inst >> 16;
+ *ptr = inst;
+ compiler->size += 2;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_imm32_const(struct sljit_compiler *compiler, int dst, sljit_uw imm)
+{
+ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
+ COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+ return push_inst32(compiler, MOVT | RD4(dst) |
+ COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+}
+
+static SLJIT_INLINE void modify_imm32_const(sljit_uh* inst, sljit_uw new_imm)
+{
+ int dst = inst[1] & 0x0f00;
+ SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
+ inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1);
+ inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff);
+ inst[2] = (MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1);
+ inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
+}
+
+static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code)
+{
+ sljit_w diff;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+ if (jump->flags & JUMP_ADDR) {
+ /* Branch to ARM code is not optimized yet. */
+ if (!(jump->u.target & 0x1))
+ return 0;
+ diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)) >> 1;
+ }
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)) >> 1;
+ }
+
+ if (jump->flags & IS_CONDITIONAL) {
+ SLJIT_ASSERT(!(jump->flags & IS_BL));
+ if (diff <= 127 && diff >= -128) {
+ jump->flags |= B_TYPE1;
+ return 5;
+ }
+ if (diff <= 524287 && diff >= -524288) {
+ jump->flags |= B_TYPE2;
+ return 4;
+ }
+ /* +1 comes from the prefix IT instruction. */
+ diff--;
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= B_TYPE3;
+ return 3;
+ }
+ }
+ else if (jump->flags & IS_BL) {
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= BL_TYPE6;
+ return 3;
+ }
+ }
+ else {
+ if (diff <= 1023 && diff >= -1024) {
+ jump->flags |= B_TYPE4;
+ return 4;
+ }
+ if (diff <= 8388607 && diff >= -8388608) {
+ jump->flags |= B_TYPE5;
+ return 3;
+ }
+ }
+
+ return 0;
+}
+
+static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush)
+{
+ sljit_uh* inst = (sljit_uh*)addr;
+ modify_imm32_const(inst, new_addr);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 3);
+ }
+}
+
+static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
+{
+ int type = (jump->flags >> 4) & 0xf;
+ sljit_w diff;
+ sljit_uh *jump_inst;
+ int s, j1, j2;
+
+ if (SLJIT_UNLIKELY(type == 0)) {
+ inline_set_jump_addr(jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+ return;
+ }
+
+ if (jump->flags & JUMP_ADDR) {
+ SLJIT_ASSERT(jump->u.target & 0x1);
+ diff = ((sljit_w)jump->u.target - (sljit_w)(jump->addr + 4)) >> 1;
+ }
+ else
+ diff = ((sljit_w)(jump->u.label->addr) - (sljit_w)(jump->addr + 4)) >> 1;
+ jump_inst = (sljit_uh*)jump->addr;
+
+ switch (type) {
+ case 1:
+ /* Encoding T1 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_CONDITIONAL));
+ jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff);
+ return;
+ case 2:
+ /* Encoding T3 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_CONDITIONAL));
+ jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1);
+ jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff);
+ return;
+ case 3:
+ SLJIT_ASSERT(jump->flags & IS_CONDITIONAL);
+ *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8;
+ diff--;
+ type = 5;
+ break;
+ case 4:
+ /* Encoding T2 of 'B' instruction */
+ SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_CONDITIONAL));
+ jump_inst[0] = 0xe000 | (diff & 0x7ff);
+ return;
+ }
+
+ SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608);
+
+ /* Really complex instruction form for branches. */
+ s = (diff >> 23) & 0x1;
+ j1 = (~(diff >> 21) ^ s) & 0x1;
+ j2 = (~(diff >> 22) ^ s) & 0x1;
+ jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10);
+ jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff);
+
+ /* The others have a common form. */
+ if (type == 5) /* Encoding T4 of 'B' instruction */
+ jump_inst[1] |= 0x9000;
+ else if (type == 6) /* Encoding T1 of 'BL' instruction */
+ jump_inst[1] |= 0xd000;
+ else
+ SLJIT_ASSERT_STOP();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_uh *code;
+ sljit_uh *code_ptr;
+ sljit_uh *buf_ptr;
+ sljit_uh *buf_end;
+ sljit_uw half_count;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ half_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ do {
+ buf_ptr = (sljit_uh*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 1);
+ do {
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= half_count);
+ SLJIT_ASSERT(!jump || jump->addr >= half_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= half_count);
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)code_ptr) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == half_count) {
+ jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_CONDITIONAL) ? 10 : 8);
+ code_ptr -= detect_jump_type(jump, code_ptr, code);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == half_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ half_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)code_ptr) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ set_jump_instruction(jump);
+ jump = jump->next;
+ }
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size * sizeof(sljit_uh);
+ /* Set thumb mode flag. */
+ return (void*)((sljit_uw)code | 0x1);
+}
+
+#define INVALID_IMM 0x80000000
+static sljit_uw get_imm(sljit_uw imm)
+{
+ /* Thumb immediate form. */
+ int counter;
+
+ if (imm <= 0xff)
+ return imm;
+
+ if ((imm & 0xffff) == (imm >> 16)) {
+ /* Some special cases. */
+ if (!(imm & 0xff00))
+ return (1 << 12) | (imm & 0xff);
+ if (!(imm & 0xff))
+ return (2 << 12) | ((imm >> 8) & 0xff);
+ if ((imm & 0xff00) == ((imm & 0xff) << 8))
+ return (3 << 12) | (imm & 0xff);
+ }
+
+ /* Assembly optimization: count leading zeroes? */
+ counter = 8;
+ if (!(imm & 0xffff0000)) {
+ counter += 16;
+ imm <<= 16;
+ }
+ if (!(imm & 0xff000000)) {
+ counter += 8;
+ imm <<= 8;
+ }
+ if (!(imm & 0xf0000000)) {
+ counter += 4;
+ imm <<= 4;
+ }
+ if (!(imm & 0xc0000000)) {
+ counter += 2;
+ imm <<= 2;
+ }
+ if (!(imm & 0x80000000)) {
+ counter += 1;
+ imm <<= 1;
+ }
+ /* Since imm >= 128, this must be true. */
+ SLJIT_ASSERT(counter <= 31);
+
+ if (imm & 0x00ffffff)
+ return INVALID_IMM; /* Cannot be encoded. */
+
+ return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);
+}
+
+static int load_immediate(struct sljit_compiler *compiler, int dst, sljit_uw imm)
+{
+ sljit_uw tmp;
+
+ if (imm >= 0x10000) {
+ tmp = get_imm(imm);
+ if (tmp != INVALID_IMM)
+ return push_inst32(compiler, MOV_WI | RD4(dst) | tmp);
+ tmp = get_imm(~imm);
+ if (tmp != INVALID_IMM)
+ return push_inst32(compiler, MVN_WI | RD4(dst) | tmp);
+ }
+
+ /* set low 16 bits, set hi 16 bits to 0. */
+ FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
+ COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
+
+ /* set hi 16 bit if needed. */
+ if (imm >= 0x10000)
+ return push_inst32(compiler, MOVT | RD4(dst) |
+ COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
+ return SLJIT_SUCCESS;
+}
+
+#define ARG1_IMM 0x0010000
+#define ARG2_IMM 0x0020000
+#define KEEP_FLAGS 0x0040000
+#define SET_MULOV 0x0080000
+/* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */
+#define SET_FLAGS 0x0100000
+#define UNUSED_RETURN 0x0200000
+#define SLOW_DEST 0x0400000
+#define SLOW_SRC1 0x0800000
+#define SLOW_SRC2 0x1000000
+
+static int emit_op_imm(struct sljit_compiler *compiler, int flags, int dst, sljit_uw arg1, sljit_uw arg2)
+{
+ /* dst must be register, TMP_REG1
+ arg1 must be register, TMP_REG1, imm
+ arg2 must be register, TMP_REG2, imm */
+ int reg;
+ sljit_uw imm;
+
+ if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
+ /* Both are immediates. */
+ flags &= ~ARG1_IMM;
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+
+ if (flags & (ARG1_IMM | ARG2_IMM)) {
+ reg = (flags & ARG2_IMM) ? arg1 : arg2;
+ imm = (flags & ARG2_IMM) ? arg2 : arg1;
+
+ switch (flags & 0xffff) {
+ case SLJIT_MOV:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1);
+ return load_immediate(compiler, dst, imm);
+ case SLJIT_NOT:
+ if (!(flags & SET_FLAGS))
+ return load_immediate(compiler, dst, ~imm);
+ /* Since the flags should be set, we just fallback to the register mode.
+ Although I could do some clever things here, "NOT IMM" does not worth the efforts. */
+ break;
+ case SLJIT_CLZ:
+ /* No form with immediate operand. */
+ break;
+ case SLJIT_ADD:
+ 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 (reg == dst && imm <= 0xff)
+ return push_inst16(compiler, ADDSI8 | IMM8(imm) | RDN3(dst));
+ }
+ if (imm <= 0xfff && !(flags & SET_FLAGS))
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(imm));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_ADDC:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SUB:
+ if (flags & ARG2_IMM) {
+ 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 (imm <= 0xff) {
+ if (reg == dst)
+ return push_inst16(compiler, SUBSI8 | IMM8(imm) | RDN3(dst));
+ if (flags & UNUSED_RETURN)
+ return push_inst16(compiler, CMPI | IMM8(imm) | RDN3(reg));
+ }
+ }
+ if (imm <= 0xfff && !(flags & SET_FLAGS))
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(imm));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ }
+ else {
+ if (!(flags & KEEP_FLAGS) && imm == 0 && IS_2_LO_REGS(reg, dst))
+ return push_inst16(compiler, RSBSI | RD3(dst) | RN3(reg));
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, RSB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ }
+ break;
+ case SLJIT_SUBC:
+ if (flags & ARG2_IMM) {
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ }
+ break;
+ case SLJIT_MUL:
+ /* No form with immediate operand. */
+ break;
+ case SLJIT_AND:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ANDI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1));
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, BICI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_OR:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ORRI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ imm = get_imm(~((flags & ARG2_IMM) ? arg2 : arg1));
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_XOR:
+ imm = get_imm(imm);
+ if (imm != INVALID_IMM)
+ return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm);
+ break;
+ case SLJIT_SHL:
+ if (flags & ARG2_IMM) {
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ break;
+ case SLJIT_LSHR:
+ if (flags & ARG2_IMM) {
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ break;
+ case SLJIT_ASHR:
+ if (flags & ARG2_IMM) {
+ imm &= 0x1f;
+ if (imm == 0) {
+ if (!(flags & SET_FLAGS))
+ return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+ if (IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+ return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+ }
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
+ return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
+ return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
+ }
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (flags & ARG2_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, arg2));
+ arg2 = TMP_REG2;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, arg1));
+ arg1 = TMP_REG1;
+ }
+ }
+
+ /* Both arguments are registers. */
+ switch (flags & 0xffff) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_UI:
+ case SLJIT_MOVU_SI:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
+ case SLJIT_MOV_UB:
+ case SLJIT_MOVU_UB:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_SB:
+ case SLJIT_MOVU_SB:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_UH:
+ case SLJIT_MOVU_UH:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
+ case SLJIT_MOV_SH:
+ case SLJIT_MOVU_SH:
+ SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
+ if (IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2));
+ case SLJIT_NOT:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2));
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(arg1 == TMP_REG1);
+ FAIL_IF(push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)));
+ if (flags & SET_FLAGS) {
+ if (reg_map[dst] <= 7)
+ return push_inst16(compiler, CMPI | RDN3(dst));
+ return push_inst32(compiler, ADD_WI | SET_FLAGS | RN4(dst) | RD4(dst));
+ }
+ return SLJIT_SUCCESS;
+ case SLJIT_ADD:
+ if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+ return push_inst16(compiler, ADDS | RD3(dst) | RN3(arg1) | RM3(arg2));
+ if (dst == arg1 && !(flags & SET_FLAGS))
+ return push_inst16(compiler, ADD | SET_REGS44(dst, arg2));
+ return push_inst32(compiler, ADD_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_ADDC:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ADCS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ADC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SUB:
+ if (!(flags & KEEP_FLAGS) && IS_3_LO_REGS(dst, arg1, arg2))
+ return push_inst16(compiler, SUBS | RD3(dst) | RN3(arg1) | RM3(arg2));
+ return push_inst32(compiler, SUB_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SUBC:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, SBCS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, SBC_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_MUL:
+ if (!(flags & SET_FLAGS))
+ return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));
+ SLJIT_ASSERT(reg_map[TMP_REG2] <= 7 && dst != TMP_REG2);
+ FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2)));
+ /* cmp TMP_REG2, dst asr #31. */
+ return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst));
+ case SLJIT_AND:
+ if (!(flags & KEEP_FLAGS)) {
+ if (dst == arg1 && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
+ if ((flags & UNUSED_RETURN) && IS_2_LO_REGS(arg1, arg2))
+ return push_inst16(compiler, TST | RD3(arg1) | RN3(arg2));
+ }
+ return push_inst32(compiler, AND_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_OR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ORRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ORR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_XOR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_SHL:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_LSHR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ case SLJIT_ASHR:
+ if (dst == arg1 && !(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, arg2))
+ return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
+ return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+#define STORE 0x01
+#define SIGNED 0x02
+
+#define WORD_SIZE 0x00
+#define BYTE_SIZE 0x04
+#define HALF_SIZE 0x08
+
+#define UPDATE 0x10
+#define ARG_TEST 0x20
+
+#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE)))
+#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift)))
+
+/*
+ 1st letter:
+ w = word
+ b = byte
+ h = half
+
+ 2nd letter:
+ s = signed
+ u = unsigned
+
+ 3rd letter:
+ l = load
+ s = store
+*/
+
+static SLJIT_CONST sljit_uw sljit_mem16[12] = {
+/* w u l */ 0x5800 /* ldr */,
+/* w u s */ 0x5000 /* str */,
+/* w s l */ 0x5800 /* ldr */,
+/* w s s */ 0x5000 /* str */,
+
+/* b u l */ 0x5c00 /* ldrb */,
+/* b u s */ 0x5400 /* strb */,
+/* b s l */ 0x5600 /* ldrsb */,
+/* b s s */ 0x5400 /* strb */,
+
+/* h u l */ 0x5a00 /* ldrh */,
+/* h u s */ 0x5200 /* strh */,
+/* h s l */ 0x5e00 /* ldrsh */,
+/* h s s */ 0x5200 /* strh */,
+};
+
+static SLJIT_CONST sljit_uw sljit_mem16_imm5[12] = {
+/* w u l */ 0x6800 /* ldr imm5 */,
+/* w u s */ 0x6000 /* str imm5 */,
+/* w s l */ 0x6800 /* ldr imm5 */,
+/* w s s */ 0x6000 /* str imm5 */,
+
+/* b u l */ 0x7800 /* ldrb imm5 */,
+/* b u s */ 0x7000 /* strb imm5 */,
+/* b s l */ 0x0000 /* not allowed */,
+/* b s s */ 0x7000 /* strb imm5 */,
+
+/* h u l */ 0x8800 /* ldrh imm5 */,
+/* h u s */ 0x8000 /* strh imm5 */,
+/* h s l */ 0x0000 /* not allowed */,
+/* h s s */ 0x8000 /* strh imm5 */,
+};
+
+#define MEM_IMM8 0xc00
+#define MEM_IMM12 0x800000
+static SLJIT_CONST sljit_uw sljit_mem32[12] = {
+/* w u l */ 0xf8500000 /* ldr.w */,
+/* w u s */ 0xf8400000 /* str.w */,
+/* w s l */ 0xf8500000 /* ldr.w */,
+/* w s s */ 0xf8400000 /* str.w */,
+
+/* b u l */ 0xf8100000 /* ldrb.w */,
+/* b u s */ 0xf8000000 /* strb.w */,
+/* b s l */ 0xf9100000 /* ldrsb.w */,
+/* b s s */ 0xf8000000 /* strb.w */,
+
+/* h u l */ 0xf8300000 /* ldrh.w */,
+/* h u s */ 0xf8200000 /* strsh.w */,
+/* h s l */ 0xf9300000 /* ldrsh.w */,
+/* h s s */ 0xf8200000 /* strsh.w */,
+};
+
+/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
+static int emit_set_delta(struct sljit_compiler *compiler, int dst, int reg, sljit_w value)
+{
+ if (value >= 0) {
+ if (value <= 0xfff)
+ return push_inst32(compiler, ADDWI | RD4(dst) | RN4(reg) | IMM12(value));
+ value = get_imm(value);
+ if (value != INVALID_IMM)
+ return push_inst32(compiler, ADD_WI | RD4(dst) | RN4(reg) | value);
+ }
+ else {
+ value = -value;
+ if (value <= 0xfff)
+ return push_inst32(compiler, SUBWI | RD4(dst) | RN4(reg) | IMM12(value));
+ value = get_imm(value);
+ if (value != INVALID_IMM)
+ return push_inst32(compiler, SUB_WI | RD4(dst) | RN4(reg) | value);
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw)
+{
+ int tmp;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (SLJIT_UNLIKELY(flags & UPDATE)) {
+ if ((arg & 0xf) && !(arg & 0xf0) && argw <= 0xff && argw >= -0xff) {
+ flags &= ~UPDATE;
+ arg &= 0xf;
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ if (argw >= 0)
+ argw |= 0x200;
+ else {
+ argw = -argw;
+ }
+ SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff);
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw));
+ return -1;
+ }
+ return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+ }
+
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ argw &= 0x3;
+ tmp = (arg >> 4) & 0xf;
+ arg &= 0xf;
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ if (!argw && IS_3_LO_REGS(reg, arg, tmp))
+ FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp)));
+ else
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4)));
+ return -1;
+ }
+
+ if (!(arg & 0xf) || argw > 0xfff || argw < -0xff)
+ return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+
+ arg &= 0xf;
+ if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags]) {
+ tmp = 3;
+ if (IS_WORD_SIZE(flags)) {
+ if (OFFSET_CHECK(0x1f, 2))
+ tmp = 2;
+ }
+ else if (flags & BYTE_SIZE)
+ {
+ if (OFFSET_CHECK(0x1f, 0))
+ tmp = 0;
+ }
+ else {
+ SLJIT_ASSERT(flags & HALF_SIZE);
+ if (OFFSET_CHECK(0x1f, 1))
+ tmp = 1;
+ }
+
+ if (tmp != 3) {
+ FAIL_IF(push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg) | (argw << (6 - tmp))));
+ return -1;
+ }
+ }
+
+ /* SP based immediate. */
+ if (SLJIT_UNLIKELY(arg == SLJIT_LOCALS_REG) && OFFSET_CHECK(0xff, 2) && IS_WORD_SIZE(flags) && reg_map[reg] <= 7) {
+ FAIL_IF(push_inst16(compiler, STR_SP | ((flags & STORE) ? 0 : 0x800) | RDN3(reg) | (argw >> 2)));
+ return -1;
+ }
+
+ if (argw >= 0)
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
+ else
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | -argw));
+ return -1;
+}
+
+/* see getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ /* Simple operation except for updates. */
+ if ((arg & 0xf0) || !(next_arg & SLJIT_MEM))
+ return 0;
+
+ if (!(arg & 0xf)) {
+ if ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff)
+ return 1;
+ return 0;
+ }
+
+ if (argw == next_argw)
+ return 1;
+
+ if (arg == next_arg && ((sljit_uw)(argw - next_argw) <= 0xfff || (sljit_uw)(next_argw - argw) <= 0xfff))
+ return 1;
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_r;
+ sljit_w tmp;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ tmp_r = (flags & STORE) ? TMP_REG3 : reg;
+
+ if (SLJIT_UNLIKELY(flags & UPDATE)) {
+ flags &= ~UPDATE;
+ /* Update only applies if a base register exists. */
+ if (arg & 0xf) {
+ /* There is no caching here. */
+ tmp = (arg & 0xf0) >> 4;
+ arg &= 0xf;
+
+ if (!tmp) {
+ if (!(argw & ~0xfff)) {
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg) | argw));
+ return push_inst32(compiler, ADDWI | RD4(arg) | RN4(arg) | IMM12(argw));
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM) {
+ if (argw == compiler->cache_argw) {
+ tmp = TMP_REG3;
+ argw = 0;
+ }
+ else if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ tmp = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ if (argw) {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ tmp = TMP_REG3;
+ argw = 0;
+ }
+ }
+
+ argw &= 0x3;
+ if (!argw && IS_3_LO_REGS(reg, arg, tmp)) {
+ FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp)));
+ return push_inst16(compiler, ADD | SET_REGS44(arg, tmp));
+ }
+ FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp) | (argw << 4)));
+ return push_inst32(compiler, ADD_W | RD4(arg) | RN4(arg) | RM4(tmp) | (argw << 6));
+ }
+ }
+
+ SLJIT_ASSERT(!(arg & 0xf0));
+
+ if (compiler->cache_arg == arg) {
+ if (!((argw - compiler->cache_argw) & ~0xfff))
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | (argw - compiler->cache_argw));
+ if (!((compiler->cache_argw - argw) & ~0xff))
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(TMP_REG3) | (compiler->cache_argw - argw));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, argw - compiler->cache_argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
+ }
+ }
+
+ next_arg = (arg & 0xf) && (arg == next_arg);
+ arg &= 0xf;
+ if (arg && compiler->cache_arg == SLJIT_MEM && compiler->cache_argw == argw)
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+
+ compiler->cache_argw = argw;
+ if (next_arg && emit_set_delta(compiler, TMP_REG3, arg, argw) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ compiler->cache_arg = SLJIT_MEM;
+
+ if (next_arg) {
+ FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, arg)));
+ compiler->cache_arg = SLJIT_MEM | arg;
+ arg = 0;
+ }
+ }
+
+ if (arg)
+ return push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(TMP_REG3));
+ return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
+}
+
+static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw)
+{
+ if (getput_arg_fast(compiler, flags, reg, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+ sljit_ins push;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ push = (1 << 4);
+ if (saveds >= 5)
+ push |= 1 << 11;
+ if (saveds >= 4)
+ push |= 1 << 10;
+ if (saveds >= 3)
+ push |= 1 << 8;
+ if (saveds >= 2)
+ push |= 1 << 7;
+ if (saveds >= 1)
+ push |= 1 << 6;
+ if (temporaries >= 5)
+ push |= 1 << 5;
+ FAIL_IF(saveds >= 3
+ ? push_inst32(compiler, PUSH_W | (1 << 14) | push)
+ : push_inst16(compiler, PUSH | push));
+
+ /* Stack must be aligned to 8 bytes: */
+ size = (3 + saveds) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+ if (local_size > 0) {
+ if (local_size <= (127 << 2))
+ FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2)));
+ else
+ FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, local_size));
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1)));
+ if (args >= 2)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2)));
+ if (args >= 3)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (3 + saveds) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ sljit_ins pop;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0) {
+ if (compiler->local_size <= (127 << 2))
+ FAIL_IF(push_inst16(compiler, ADD_SP | (compiler->local_size >> 2)));
+ else
+ FAIL_IF(emit_op_imm(compiler, SLJIT_ADD | ARG2_IMM, SLJIT_LOCALS_REG, SLJIT_LOCALS_REG, compiler->local_size));
+ }
+
+ pop = (1 << 4);
+ if (compiler->saveds >= 5)
+ pop |= 1 << 11;
+ if (compiler->saveds >= 4)
+ pop |= 1 << 10;
+ if (compiler->saveds >= 3)
+ pop |= 1 << 8;
+ if (compiler->saveds >= 2)
+ pop |= 1 << 7;
+ if (compiler->saveds >= 1)
+ pop |= 1 << 6;
+ if (compiler->temporaries >= 5)
+ pop |= 1 << 5;
+ return compiler->saveds >= 3
+ ? push_inst32(compiler, POP_W | (1 << 15) | pop)
+ : push_inst16(compiler, POP | pop);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__)
+extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator);
+extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator);
+#else
+#error "Software divmod functions are needed"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ push_inst16(compiler, BKPT);
+ break;
+ case SLJIT_NOP:
+ push_inst16(compiler, NOP);
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
+ | (reg_map[SLJIT_TEMPORARY_REG2] << 8)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 16)
+ | reg_map[SLJIT_TEMPORARY_REG2]);
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ if (compiler->temporaries >= 4) {
+ FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
+ FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
+ } else if (compiler->temporaries >= 3)
+ FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
+#if defined(__GNUC__)
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
+ (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
+#else
+#error "Software divmod functions are needed"
+#endif
+ if (compiler->temporaries >= 4) {
+ FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */));
+ return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */);
+ } else if (compiler->temporaries >= 3)
+ return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */);
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int op_type, dst_r, flags;
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ op_type = GET_OPCODE(op);
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1;
+
+ if (op_type >= SLJIT_MOV && op_type <= SLJIT_MOVU_SI) {
+ switch (op_type) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ flags = WORD_SIZE;
+ break;
+ case SLJIT_MOV_UB:
+ flags = BYTE_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned char)srcw;
+ break;
+ case SLJIT_MOV_SB:
+ flags = BYTE_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (signed char)srcw;
+ break;
+ case SLJIT_MOV_UH:
+ flags = HALF_SIZE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned short)srcw;
+ break;
+ case SLJIT_MOV_SH:
+ flags = HALF_SIZE | SIGNED;
+ if (src & SLJIT_IMM)
+ srcw = (signed short)srcw;
+ break;
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_UI:
+ case SLJIT_MOVU_SI:
+ flags = WORD_SIZE | UPDATE;
+ break;
+ case SLJIT_MOVU_UB:
+ flags = BYTE_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned char)srcw;
+ break;
+ case SLJIT_MOVU_SB:
+ flags = BYTE_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (signed char)srcw;
+ break;
+ case SLJIT_MOVU_UH:
+ flags = HALF_SIZE | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (unsigned short)srcw;
+ break;
+ case SLJIT_MOVU_SH:
+ flags = HALF_SIZE | SIGNED | UPDATE;
+ if (src & SLJIT_IMM)
+ srcw = (signed short)srcw;
+ break;
+ default:
+ SLJIT_ASSERT_STOP();
+ flags = 0;
+ break;
+ }
+
+ if (src & SLJIT_IMM)
+ FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
+ } else {
+ if (dst_r != TMP_REG1)
+ return emit_op_imm(compiler, op_type, dst_r, TMP_REG1, src);
+ dst_r = src;
+ }
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (op_type == SLJIT_NEG) {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, GET_FLAGS(op) | SLJIT_SUB, dst, dstw, SLJIT_IMM, 0, src, srcw);
+ }
+
+ flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+ if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw))
+ FAIL_IF(compiler->error);
+ else
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, dst, dstw));
+ src = TMP_REG2;
+ }
+
+ if (src & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ srcw = src;
+
+ emit_op_imm(compiler, flags | op_type, dst_r, TMP_REG1, srcw);
+
+ if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
+ return compiler->error;
+ else
+ return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_r, flags;
+
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1;
+ flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0);
+
+ if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG1, src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ }
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG1, src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src2, src2w, dst, dstw));
+
+ if (src1 & SLJIT_MEM)
+ src1 = TMP_REG1;
+ if (src2 & SLJIT_MEM)
+ src2 = TMP_REG2;
+
+ if (src1 & SLJIT_IMM)
+ flags |= ARG1_IMM;
+ else
+ src1w = src1;
+ if (src2 & SLJIT_IMM)
+ flags |= ARG2_IMM;
+ else
+ src2w = src2;
+
+ if (dst == SLJIT_UNUSED)
+ flags |= UNUSED_RETURN;
+
+ if (GET_OPCODE(op) == SLJIT_MUL && (op & SLJIT_SET_O))
+ flags |= SET_MULOV;
+
+ emit_op_imm(compiler, flags | GET_OPCODE(op), dst_r, src1w, src2w);
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, WORD_SIZE | STORE, dst_r, dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG1, dst, dstw, 0, 0);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 2 || size == 4);
+
+ if (size == 2)
+ return push_inst16(compiler, *(sljit_uh*)instruction);
+ return push_inst32(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ return 1;
+}
+
+static int emit_fop_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw)
+{
+ sljit_w tmp;
+ sljit_w inst = VSTR | ((flags & STORE) ? 0 : 0x00100000);
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ FAIL_IF(push_inst32(compiler, ADD_W | RD4(TMP_REG2) | RN4(arg & 0xf) | RM4((arg & 0xf0) >> 4) | ((argw & 0x3) << 6)));
+ arg = SLJIT_MEM | TMP_REG2;
+ argw = 0;
+ }
+
+ if (arg & 0xf) {
+ if (!(argw & ~0x3fc))
+ return push_inst32(compiler, inst | 0x800000 | RN4(arg & 0xf) | DD4(reg) | (argw >> 2));
+ if (!(-argw & ~0x3fc))
+ return push_inst32(compiler, inst | RN4(arg & 0xf) | DD4(reg) | (-argw >> 2));
+ }
+
+ SLJIT_ASSERT(!(arg & 0xf0));
+ if (compiler->cache_arg == arg) {
+ tmp = argw - compiler->cache_argw;
+ if (!(tmp & ~0x3fc))
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg) | (tmp >> 2));
+ if (!(-tmp & ~0x3fc))
+ return push_inst32(compiler, inst | RN4(TMP_REG3) | DD4(reg) | (-tmp >> 2));
+ if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) {
+ FAIL_IF(compiler->error);
+ compiler->cache_argw = argw;
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+ }
+ }
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ if (SLJIT_UNLIKELY(!(arg & 0xf)))
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ else if (emit_set_delta(compiler, TMP_REG3, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED)
+ FAIL_IF(compiler->error);
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ if (arg & 0xf)
+ FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG3, (arg & 0xf))));
+ }
+ return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
+ dst = TMP_FREG1;
+ }
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG2, src, srcw);
+ src = TMP_FREG2;
+ }
+ FAIL_IF(push_inst32(compiler, VCMP_F64 | DD4(dst) | DM4(src)));
+ return push_inst32(compiler, VMRS);
+ }
+
+ dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1;
+ if (src & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, dst_r, src, srcw);
+ src = dst_r;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_FMOV:
+ if (src != dst_r)
+ FAIL_IF(push_inst32(compiler, VMOV_F64 | DD4(dst_r) | DM4(src)));
+ break;
+ case SLJIT_FNEG:
+ FAIL_IF(push_inst32(compiler, VNEG_F64 | DD4(dst_r) | DM4(src)));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(push_inst32(compiler, VABS_F64 | DD4(dst_r) | DM4(src)));
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1;
+ if (src1 & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG1, src1, src1w);
+ src1 = TMP_FREG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ emit_fop_mem(compiler, 0, TMP_FREG2, src2, src2w);
+ src2 = TMP_FREG2;
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_FADD:
+ FAIL_IF(push_inst32(compiler, VADD_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(push_inst32(compiler, VSUB_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(push_inst32(compiler, VMUL_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(push_inst32(compiler, VDIV_F64 | DD4(dst_r) | DN4(src1) | DM4(src2)));
+ break;
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (3 + saveds) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3));
+ else if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw))
+ return compiler->error;
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3)));
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src)));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw))
+ FAIL_IF(compiler->error);
+ else {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ FAIL_IF(getput_arg(compiler, WORD_SIZE, TMP_REG2, src, srcw, 0, 0));
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, TMP_REG2)));
+ }
+ }
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
+ return push_inst16(compiler, BLX | RN3(TMP_REG3));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_EQUAL:
+ return 0x0;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_MUL_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return 0x1;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return 0x3;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return 0x2;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return 0x8;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return 0x9;
+
+ case SLJIT_C_SIG_LESS:
+ return 0xb;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return 0xa;
+
+ case SLJIT_C_SIG_GREATER:
+ return 0xc;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return 0xd;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_FLOAT_NAN:
+ return 0x6;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return 0x7;
+
+ default: /* SLJIT_JUMP */
+ return 0xe;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+ int cc;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In ARM, we don't need to touch the arguments. */
+ PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
+ if (type < SLJIT_JUMP) {
+ jump->flags |= IS_CONDITIONAL;
+ cc = get_cc(type);
+ jump->flags |= cc << 8;
+ PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ }
+
+ jump->addr = compiler->size;
+ if (type <= SLJIT_JUMP)
+ PTR_FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));
+ else {
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));
+ }
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+ FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
+ jump->addr = compiler->size;
+ FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)));
+ }
+ else {
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
+
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw));
+ if (type >= SLJIT_FAST_CALL)
+ return push_inst16(compiler, BLX | RN3(TMP_REG1));
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int dst_r;
+ sljit_uw cc;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ cc = get_cc(type);
+ if (GET_OPCODE(op) == SLJIT_OR && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ FAIL_IF(push_inst32(compiler, ORRI | RN4(dst) | RD4(dst) | 0x1));
+ if (op & SLJIT_SET_E) {
+ if (reg_map[dst] <= 7)
+ return push_inst16(compiler, ORRS | RD3(dst) | RN3(dst));
+ return push_inst32(compiler, ORR_W | SET_FLAGS | RD4(TMP_REG1) | RN4(dst) | RM4(dst));
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = TMP_REG2;
+ if (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && reg_map[dst] <= 7)
+ dst_r = dst;
+
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4));
+ FAIL_IF(push_inst16(compiler, MOVSI | 0x1 | RDN3(dst_r)));
+ FAIL_IF(push_inst16(compiler, MOVSI | 0x0 | RDN3(dst_r)));
+
+ if (dst_r == TMP_REG2) {
+ if (GET_OPCODE(op) == SLJIT_OR) {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG2, 0);
+ }
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw);
+ else
+ return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int dst_r;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1;
+ PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ inline_set_jump_addr(addr, new_addr, 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_uh* inst = (sljit_uh*)addr;
+ modify_imm32_const(inst, new_constant);
+ SLJIT_CACHE_FLUSH(inst, inst + 3);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c b/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
new file mode 100644
index 00000000000..e3a5873247e
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
@@ -0,0 +1,2424 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ return "ARMv7" SLJIT_CPUINFO;
+#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ return "ARMv5" SLJIT_CPUINFO;
+#else
+#error "Internal error: Unknown ARM architecture"
+#endif
+}
+
+/* Last register + 1. */
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define TMP_PC (SLJIT_NO_REGISTERS + 4)
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* In ARM instruction words.
+ Cache lines are usually 32 byte aligned. */
+#define CONST_POOL_ALIGNMENT 8
+#define CONST_POOL_EMPTY 0xffffffff
+
+#define ALIGN_INSTRUCTION(ptr) \
+ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1))
+#define MAX_DIFFERENCE(max_diff) \
+ (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1))
+
+/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
+ 0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15
+};
+
+#define RM(rm) (reg_map[rm])
+#define RD(rd) (reg_map[rd] << 12)
+#define RN(rn) (reg_map[rn] << 16)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+/* The instruction includes the AL condition.
+ INST_NAME - CONDITIONAL remove this flag. */
+#define COND_MASK 0xf0000000
+#define CONDITIONAL 0xe0000000
+#define PUSH_POOL 0xff000000
+
+/* DP - Data Processing instruction (use with EMIT_DATA_PROCESS_INS). */
+#define ADC_DP 0x5
+#define ADD_DP 0x4
+#define AND_DP 0x0
+#define B 0xea000000
+#define BIC_DP 0xe
+#define BL 0xeb000000
+#define BLX 0xe12fff30
+#define BX 0xe12fff10
+#define CLZ 0xe16f0f10
+#define CMP_DP 0xa
+#define BKPT 0xe1200070
+#define EOR_DP 0x1
+#define MOV_DP 0xd
+#define MUL 0xe0000090
+#define MVN_DP 0xf
+#define NOP 0xe1a00000
+#define ORR_DP 0xc
+#define PUSH 0xe92d0000
+#define POP 0xe8bd0000
+#define RSB_DP 0x3
+#define RSC_DP 0x7
+#define SBC_DP 0x6
+#define SMULL 0xe0c00090
+#define SUB_DP 0x2
+#define UMULL 0xe0800090
+#define VABS_F64 0xeeb00bc0
+#define VADD_F64 0xee300b00
+#define VCMP_F64 0xeeb40b40
+#define VDIV_F64 0xee800b00
+#define VMOV_F64 0xeeb00b40
+#define VMRS 0xeef1fa10
+#define VMUL_F64 0xee200b00
+#define VNEG_F64 0xeeb10b40
+#define VSTR 0xed000b00
+#define VSUB_F64 0xee300b40
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+/* Arm v7 specific instructions. */
+#define MOVW 0xe3000000
+#define MOVT 0xe3400000
+#define SXTB 0xe6af0070
+#define SXTH 0xe6bf0070
+#define UXTB 0xe6ef0070
+#define UXTH 0xe6ff0070
+#endif
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+static int push_cpool(struct sljit_compiler *compiler)
+{
+ /* Pushing the constant pool into the instruction stream. */
+ sljit_uw* inst;
+ sljit_uw* cpool_ptr;
+ sljit_uw* cpool_end;
+ int i;
+
+ /* The label could point the address after the constant pool. */
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1;
+
+ SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE);
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = 0xff000000 | compiler->cpool_fill;
+
+ for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) {
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = 0;
+ }
+
+ cpool_ptr = compiler->cpool;
+ cpool_end = cpool_ptr + compiler->cpool_fill;
+ while (cpool_ptr < cpool_end) {
+ inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!inst);
+ compiler->size++;
+ *inst = *cpool_ptr++;
+ }
+ compiler->cpool_diff = CONST_POOL_EMPTY;
+ compiler->cpool_fill = 0;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst(struct sljit_compiler *compiler, sljit_uw inst)
+{
+ sljit_uw* ptr;
+
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
+ FAIL_IF(push_cpool(compiler));
+
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
+{
+ sljit_uw* ptr;
+ sljit_uw cpool_index = CPOOL_SIZE;
+ sljit_uw* cpool_ptr;
+ sljit_uw* cpool_end;
+ sljit_ub* cpool_unique_ptr;
+
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)))
+ FAIL_IF(push_cpool(compiler));
+ else if (compiler->cpool_fill > 0) {
+ cpool_ptr = compiler->cpool;
+ cpool_end = cpool_ptr + compiler->cpool_fill;
+ cpool_unique_ptr = compiler->cpool_unique;
+ do {
+ if ((*cpool_ptr == literal) && !(*cpool_unique_ptr)) {
+ cpool_index = cpool_ptr - compiler->cpool;
+ break;
+ }
+ cpool_ptr++;
+ cpool_unique_ptr++;
+ } while (cpool_ptr < cpool_end);
+ }
+
+ if (cpool_index == CPOOL_SIZE) {
+ /* Must allocate a new entry in the literal pool. */
+ if (compiler->cpool_fill < CPOOL_SIZE) {
+ cpool_index = compiler->cpool_fill;
+ compiler->cpool_fill++;
+ }
+ else {
+ FAIL_IF(push_cpool(compiler));
+ cpool_index = 0;
+ compiler->cpool_fill = 1;
+ }
+ }
+
+ SLJIT_ASSERT((inst & 0xfff) == 0);
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst | cpool_index;
+
+ compiler->cpool[cpool_index] = literal;
+ compiler->cpool_unique[cpool_index] = 0;
+ if (compiler->cpool_diff == CONST_POOL_EMPTY)
+ compiler->cpool_diff = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+static int push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal)
+{
+ sljit_uw* ptr;
+ if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE))
+ FAIL_IF(push_cpool(compiler));
+
+ SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0);
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst | compiler->cpool_fill;
+
+ compiler->cpool[compiler->cpool_fill] = literal;
+ compiler->cpool_unique[compiler->cpool_fill] = 1;
+ compiler->cpool_fill++;
+ if (compiler->cpool_diff == CONST_POOL_EMPTY)
+ compiler->cpool_diff = compiler->size;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int prepare_blx(struct sljit_compiler *compiler)
+{
+ /* Place for at least two instruction (doesn't matter whether the first has a literal). */
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088)))
+ return push_cpool(compiler);
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_blx(struct sljit_compiler *compiler)
+{
+ /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */
+ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092));
+ return push_inst(compiler, BLX | RM(TMP_REG1));
+}
+
+static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ptr, sljit_uw* const_pool, sljit_uw cpool_size)
+{
+ sljit_uw diff;
+ sljit_uw ind;
+ sljit_uw counter = 0;
+ sljit_uw* clear_const_pool = const_pool;
+ sljit_uw* clear_const_pool_end = const_pool + cpool_size;
+
+ SLJIT_ASSERT(const_pool - code_ptr <= CONST_POOL_ALIGNMENT);
+ /* Set unused flag for all literals in the constant pool.
+ I.e.: unused literals can belong to branches, which can be encoded as B or BL.
+ We can "compress" the constant pool by discarding these literals. */
+ while (clear_const_pool < clear_const_pool_end)
+ *clear_const_pool++ = (sljit_uw)(-1);
+
+ while (last_pc_patch < code_ptr) {
+ /* Data transfer instruction with Rn == r15. */
+ if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) {
+ diff = const_pool - last_pc_patch;
+ ind = (*last_pc_patch) & 0xfff;
+
+ /* Must be a load instruction with immediate offset. */
+ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20)));
+ if ((int)const_pool[ind] < 0) {
+ const_pool[ind] = counter;
+ ind = counter;
+ counter++;
+ }
+ else
+ ind = const_pool[ind];
+
+ SLJIT_ASSERT(diff >= 1);
+ if (diff >= 2 || ind > 0) {
+ diff = (diff + ind - 2) << 2;
+ SLJIT_ASSERT(diff <= 0xfff);
+ *last_pc_patch = (*last_pc_patch & ~0xfff) | diff;
+ }
+ else
+ *last_pc_patch = (*last_pc_patch & ~(0xfff | (1 << 23))) | 0x004;
+ }
+ last_pc_patch++;
+ }
+ return counter;
+}
+
+/* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */
+struct future_patch {
+ struct future_patch* next;
+ int index;
+ int value;
+};
+
+static SLJIT_INLINE int resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr)
+{
+ int value;
+ struct future_patch *curr_patch, *prev_patch;
+
+ /* Using the values generated by patch_pc_relative_loads. */
+ if (!*first_patch)
+ value = (int)cpool_start_address[cpool_current_index];
+ else {
+ curr_patch = *first_patch;
+ prev_patch = 0;
+ while (1) {
+ if (!curr_patch) {
+ value = (int)cpool_start_address[cpool_current_index];
+ break;
+ }
+ if ((sljit_uw)curr_patch->index == cpool_current_index) {
+ value = curr_patch->value;
+ if (prev_patch)
+ prev_patch->next = curr_patch->next;
+ else
+ *first_patch = curr_patch->next;
+ SLJIT_FREE(curr_patch);
+ break;
+ }
+ prev_patch = curr_patch;
+ curr_patch = curr_patch->next;
+ }
+ }
+
+ if (value >= 0) {
+ if ((sljit_uw)value > cpool_current_index) {
+ curr_patch = (struct future_patch*)SLJIT_MALLOC(sizeof(struct future_patch));
+ if (!curr_patch) {
+ while (*first_patch) {
+ curr_patch = *first_patch;
+ *first_patch = (*first_patch)->next;
+ SLJIT_FREE(curr_patch);
+ }
+ return SLJIT_ERR_ALLOC_FAILED;
+ }
+ curr_patch->next = *first_patch;
+ curr_patch->index = value;
+ curr_patch->value = cpool_start_address[value];
+ *first_patch = curr_patch;
+ }
+ cpool_start_address[value] = *buf_ptr;
+ }
+ return SLJIT_SUCCESS;
+}
+
+#else
+
+static int push_inst(struct sljit_compiler *compiler, sljit_uw inst)
+{
+ sljit_uw* ptr;
+
+ ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw));
+ FAIL_IF(!ptr);
+ compiler->size++;
+ *ptr = inst;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_imm(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)));
+ return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff));
+}
+
+#endif
+
+static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code)
+{
+ sljit_w diff;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (jump->flags & IS_BL)
+ code_ptr--;
+
+ if (jump->flags & JUMP_ADDR)
+ diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2));
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2));
+ }
+
+ /* Branch to Thumb code has not been optimized yet. */
+ if (diff & 0x3)
+ return 0;
+
+ diff >>= 2;
+ if (jump->flags & IS_BL) {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ }
+ else {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ *code_ptr = (B - CONDITIONAL) | (*code_ptr & COND_MASK);
+ jump->flags |= PATCH_B;
+ }
+ }
+#else
+ if (jump->flags & JUMP_ADDR)
+ diff = ((sljit_w)jump->u.target - (sljit_w)code_ptr);
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr);
+ }
+
+ /* Branch to Thumb code has not been optimized yet. */
+ if (diff & 0x3)
+ return 0;
+
+ diff >>= 2;
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ code_ptr -= 2;
+ *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK);
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush)
+{
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw *ptr = (sljit_uw*)addr;
+ sljit_uw *inst = (sljit_uw*)ptr[0];
+ sljit_uw mov_pc = ptr[1];
+ int bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
+ sljit_w diff = (sljit_w)(((sljit_w)new_addr - (sljit_w)(inst + 2)) >> 2);
+
+ if (diff <= 0x7fffff && diff >= -0x800000) {
+ /* Turn to branch. */
+ if (!bl) {
+ inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ } else {
+ inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
+ inst[1] = NOP;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+ }
+ } else {
+ /* Get the position of the constant. */
+ if (mov_pc & (1 << 23))
+ ptr = inst + ((mov_pc & 0xfff) >> 2) + 2;
+ else
+ ptr = inst + 1;
+
+ if (*inst != mov_pc) {
+ inst[0] = mov_pc;
+ if (!bl) {
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ } else {
+ inst[1] = BLX | RM(TMP_REG1);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+ }
+ }
+ *ptr = new_addr;
+ }
+#else
+ sljit_uw *inst = (sljit_uw*)addr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+ inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
+ inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+#endif
+}
+
+static sljit_uw get_immediate(sljit_uw imm);
+
+static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_w new_constant, int flush)
+{
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw *ptr = (sljit_uw*)addr;
+ sljit_uw *inst = (sljit_uw*)ptr[0];
+ sljit_uw ldr_literal = ptr[1];
+ sljit_uw src2;
+
+ src2 = get_immediate(new_constant);
+ if (src2) {
+ *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ return;
+ }
+
+ src2 = get_immediate(~new_constant);
+ if (src2) {
+ *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ return;
+ }
+
+ if (ldr_literal & (1 << 23))
+ ptr = inst + ((ldr_literal & 0xfff) >> 2) + 2;
+ else
+ ptr = inst + 1;
+
+ if (*inst != ldr_literal) {
+ *inst = ldr_literal;
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ }
+ }
+ *ptr = new_constant;
+#else
+ sljit_uw *inst = (sljit_uw*)addr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+ inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
+ inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
+ if (flush) {
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ }
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_uw *code;
+ sljit_uw *code_ptr;
+ sljit_uw *buf_ptr;
+ sljit_uw *buf_end;
+ sljit_uw size;
+ sljit_uw word_count;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ sljit_uw cpool_size;
+ sljit_uw cpool_skip_alignment;
+ sljit_uw cpool_current_index;
+ sljit_uw *cpool_start_address;
+ sljit_uw *last_pc_patch;
+ struct future_patch *first_patch;
+#endif
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ /* Second code generation pass. */
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ size = compiler->size + (compiler->patches << 1);
+ if (compiler->cpool_fill > 0)
+ size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;
+#else
+ size = compiler->size;
+#endif
+ code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ cpool_size = 0;
+ cpool_skip_alignment = 0;
+ cpool_current_index = 0;
+ cpool_start_address = NULL;
+ first_patch = NULL;
+ last_pc_patch = code;
+#endif
+
+ code_ptr = code;
+ word_count = 0;
+
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+
+ if (label && label->size == 0) {
+ label->addr = (sljit_uw)code;
+ label->size = 0;
+ label = label->next;
+ }
+
+ do {
+ buf_ptr = (sljit_uw*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ word_count++;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (cpool_size > 0) {
+ if (cpool_skip_alignment > 0) {
+ buf_ptr++;
+ cpool_skip_alignment--;
+ }
+ else {
+ if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
+ SLJIT_FREE_EXEC(code);
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+ return NULL;
+ }
+ buf_ptr++;
+ if (++cpool_current_index >= cpool_size) {
+ SLJIT_ASSERT(!first_patch);
+ cpool_size = 0;
+ if (label && label->size == word_count) {
+ /* Points after the current instruction. */
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ }
+ }
+ }
+ else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
+#endif
+ *code_ptr = *buf_ptr++;
+ /* These structures are ordered by their address. */
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (detect_jump_type(jump, code_ptr, code))
+ code_ptr--;
+ jump->addr = (sljit_uw)code_ptr;
+#else
+ jump->addr = (sljit_uw)(code_ptr - 2);
+ if (detect_jump_type(jump, code_ptr, code))
+ code_ptr -= 2;
+#endif
+ jump = jump->next;
+ }
+ if (label && label->size == word_count) {
+ /* code_ptr can be affected above. */
+ label->addr = (sljit_uw)(code_ptr + 1);
+ label->size = (code_ptr + 1) - code;
+ label = label->next;
+ }
+ if (const_ && const_->addr == word_count) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ const_->addr = (sljit_uw)code_ptr;
+#else
+ const_->addr = (sljit_uw)(code_ptr - 1);
+#endif
+ const_ = const_->next;
+ }
+ code_ptr++;
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ }
+ else {
+ /* Fortunately, no need to shift. */
+ cpool_size = *buf_ptr++ & ~PUSH_POOL;
+ SLJIT_ASSERT(cpool_size > 0);
+ cpool_start_address = ALIGN_INSTRUCTION(code_ptr + 1);
+ cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size);
+ if (cpool_current_index > 0) {
+ /* Unconditional branch. */
+ *code_ptr = B | (((cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL);
+ code_ptr = cpool_start_address + cpool_current_index;
+ }
+ cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1;
+ cpool_current_index = 0;
+ last_pc_patch = code_ptr;
+ }
+#endif
+ } while (buf_ptr < buf_end);
+ buf = buf->next;
+ } while (buf);
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_ASSERT(cpool_size == 0);
+ if (compiler->cpool_fill > 0) {
+ cpool_start_address = ALIGN_INSTRUCTION(code_ptr);
+ cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill);
+ if (cpool_current_index > 0)
+ code_ptr = cpool_start_address + cpool_current_index;
+
+ buf_ptr = compiler->cpool;
+ buf_end = buf_ptr + compiler->cpool_fill;
+ cpool_current_index = 0;
+ while (buf_ptr < buf_end) {
+ if (SLJIT_UNLIKELY(resolve_const_pool_index(&first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
+ SLJIT_FREE_EXEC(code);
+ compiler->error = SLJIT_ERR_ALLOC_FAILED;
+ return NULL;
+ }
+ buf_ptr++;
+ cpool_current_index++;
+ }
+ SLJIT_ASSERT(!first_patch);
+ }
+#endif
+
+ jump = compiler->jumps;
+ while (jump) {
+ buf_ptr = (sljit_uw*)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ if (!(jump->flags & JUMP_ADDR)) {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ SLJIT_ASSERT(((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >= -0x02000000);
+ *buf_ptr |= (((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff;
+ }
+ else {
+ SLJIT_ASSERT(((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >= -0x02000000);
+ *buf_ptr |= (((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff;
+ }
+ }
+ else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ jump->addr = (sljit_uw)code_ptr;
+ code_ptr[0] = (sljit_uw)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ inline_set_jump_addr((sljit_uw)code_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+ code_ptr += 2;
+#else
+ inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+#endif
+ }
+ else {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (jump->flags & IS_BL)
+ buf_ptr--;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+#else
+ inline_set_jump_addr((sljit_uw)buf_ptr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0);
+#endif
+ }
+ jump = jump->next;
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ const_ = compiler->consts;
+ while (const_) {
+ buf_ptr = (sljit_uw*)const_->addr;
+ const_->addr = (sljit_uw)code_ptr;
+
+ code_ptr[0] = (sljit_uw)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ /* Set the value again (can be a simple constant). */
+ inline_set_const((sljit_uw)code_ptr, *buf_ptr, 0);
+ code_ptr += 2;
+
+ const_ = const_->next;
+ }
+#endif
+
+ SLJIT_ASSERT(code_ptr - code <= (int)size);
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = size * sizeof(sljit_uw);
+ return code;
+}
+
+/* emit_op inp_flags.
+ WRITE_BACK must be the first, since it is a flag. */
+#define WRITE_BACK 0x01
+#define ALLOW_IMM 0x02
+#define ALLOW_INV_IMM 0x04
+#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM)
+#define ARG_TEST 0x08
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x10
+#define HALF_DATA 0x20
+#define SIGNED_DATA 0x40
+#define LOAD_DATA 0x80
+
+#define EMIT_INSTRUCTION(inst) \
+ FAIL_IF(push_inst(compiler, (inst)))
+
+/* Condition: AL. */
+#define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \
+ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2))
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+ sljit_uw push;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ /* Push saved registers, temporary registers
+ stmdb sp!, {..., lr} */
+ push = PUSH | (1 << 14);
+ if (temporaries >= 5)
+ push |= 1 << 11;
+ if (temporaries >= 4)
+ push |= 1 << 10;
+ if (saveds >= 5)
+ push |= 1 << 8;
+ if (saveds >= 4)
+ push |= 1 << 7;
+ if (saveds >= 3)
+ push |= 1 << 6;
+ if (saveds >= 2)
+ push |= 1 << 5;
+ if (saveds >= 1)
+ push |= 1 << 4;
+ EMIT_INSTRUCTION(push);
+
+ /* Stack must be aligned to 8 bytes: */
+ size = (1 + saveds) * sizeof(sljit_uw);
+ if (temporaries >= 4)
+ size += (temporaries - 3) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+ if (local_size > 0)
+ FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size));
+
+ if (args >= 1)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1)));
+ if (args >= 2)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));
+ if (args >= 3)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (1 + saveds) * sizeof(sljit_uw);
+ if (temporaries >= 4)
+ size += (temporaries - 3) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ sljit_uw pop;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0)
+ FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
+
+ pop = POP | (1 << 15);
+ /* Push saved registers, temporary registers
+ ldmia sp!, {..., pc} */
+ if (compiler->temporaries >= 5)
+ pop |= 1 << 11;
+ if (compiler->temporaries >= 4)
+ pop |= 1 << 10;
+ if (compiler->saveds >= 5)
+ pop |= 1 << 8;
+ if (compiler->saveds >= 4)
+ pop |= 1 << 7;
+ if (compiler->saveds >= 3)
+ pop |= 1 << 6;
+ if (compiler->saveds >= 2)
+ pop |= 1 << 5;
+ if (compiler->saveds >= 1)
+ pop |= 1 << 4;
+
+ return push_inst(compiler, pop);
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* s/l - store/load (1 bit)
+ u/s - signed/unsigned (1 bit)
+ w/b/h/N - word/byte/half/NOT allowed (2 bit)
+ It contans 16 items, but not all are different. */
+
+static sljit_w data_transfer_insts[16] = {
+/* s u w */ 0xe5000000 /* str */,
+/* s u b */ 0xe5400000 /* strb */,
+/* s u h */ 0xe10000b0 /* strh */,
+/* s u N */ 0x00000000 /* not allowed */,
+/* s s w */ 0xe5000000 /* str */,
+/* s s b */ 0xe5400000 /* strb */,
+/* s s h */ 0xe10000b0 /* strh */,
+/* s s N */ 0x00000000 /* not allowed */,
+
+/* l u w */ 0xe5100000 /* ldr */,
+/* l u b */ 0xe5500000 /* ldrb */,
+/* l u h */ 0xe11000b0 /* ldrh */,
+/* l u N */ 0x00000000 /* not allowed */,
+/* l s w */ 0xe5100000 /* ldr */,
+/* l s b */ 0xe11000d0 /* ldrsb */,
+/* l s h */ 0xe11000f0 /* ldrsh */,
+/* l s N */ 0x00000000 /* not allowed */,
+};
+
+#define EMIT_DATA_TRANSFER(type, add, wb, target, base1, base2) \
+ (data_transfer_insts[(type) >> 4] | ((add) << 23) | ((wb) << 21) | (reg_map[target] << 12) | (reg_map[base1] << 16) | (base2))
+/* Normal ldr/str instruction.
+ Type2: ldrsb, ldrh, ldrsh */
+#define IS_TYPE1_TRANSFER(type) \
+ (data_transfer_insts[(type) >> 4] & 0x04000000)
+#define TYPE2_TRANSFER_IMM(imm) \
+ (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22))
+
+/* flags: */
+ /* Arguments are swapped. */
+#define ARGS_SWAPPED 0x01
+ /* Inverted immediate. */
+#define INV_IMM 0x02
+ /* Source and destination is register. */
+#define REG_DEST 0x04
+#define REG_SOURCE 0x08
+ /* One instruction is enough. */
+#define FAST_DEST 0x10
+ /* Multiple instructions are required. */
+#define SLOW_DEST 0x20
+/* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */
+#define SET_FLAGS (1 << 20)
+/* dst: reg
+ src1: reg
+ src2: reg or imm (if allowed)
+ SRC2_IMM must be (1 << 25) as it is also the value of I bit (can be used for optimization). */
+#define SRC2_IMM (1 << 25)
+
+#define EMIT_DATA_PROCESS_INS_AND_RETURN(opcode) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, (src2 & SRC2_IMM) ? src2 : RM(src2)))
+
+#define EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(opcode, dst, src1, src2) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(opcode, flags & SET_FLAGS, dst, src1, src2))
+
+#define EMIT_SHIFT_INS_AND_RETURN(opcode) \
+ SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); \
+ if (compiler->shift_imm != 0x20) { \
+ SLJIT_ASSERT(src1 == TMP_REG1); \
+ SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \
+ if (compiler->shift_imm != 0) \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \
+ } \
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1])));
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, int src2)
+{
+ sljit_w mul_inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP);
+
+ case SLJIT_ADDC:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ADC_DP);
+
+ case SLJIT_SUB:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ if (!(flags & ARGS_SWAPPED))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(SUB_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(RSB_DP);
+
+ case SLJIT_SUBC:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ if (!(flags & ARGS_SWAPPED))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(SBC_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(RSC_DP);
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ SLJIT_ASSERT(!(src2 & SRC2_IMM));
+ if (SLJIT_UNLIKELY(op & SLJIT_SET_O))
+ mul_inst = SMULL | (reg_map[TMP_REG3] << 16) | (reg_map[dst] << 12);
+ else
+ mul_inst = MUL | (reg_map[dst] << 16);
+
+ if (dst != src2)
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src1] << 8) | reg_map[src2]));
+ else if (dst != src1)
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[src1]));
+ else {
+ /* Rm and Rd must not be the same register. */
+ SLJIT_ASSERT(dst != TMP_REG1);
+ FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, reg_map[src2])));
+ FAIL_IF(push_inst(compiler, mul_inst | (reg_map[src2] << 8) | reg_map[TMP_REG1]));
+ }
+
+ if (!(op & SLJIT_SET_O))
+ return SLJIT_SUCCESS;
+
+ /* We need to use TMP_REG3. */
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ /* cmp TMP_REG2, dst asr #31. */
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(CMP_DP, SET_FLAGS, SLJIT_UNUSED, TMP_REG3, RM(dst) | 0xfc0));
+
+ case SLJIT_AND:
+ if (!(flags & INV_IMM))
+ EMIT_DATA_PROCESS_INS_AND_RETURN(AND_DP);
+ EMIT_DATA_PROCESS_INS_AND_RETURN(BIC_DP);
+
+ case SLJIT_OR:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(ORR_DP);
+
+ case SLJIT_XOR:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ EMIT_DATA_PROCESS_INS_AND_RETURN(EOR_DP);
+
+ case SLJIT_SHL:
+ EMIT_SHIFT_INS_AND_RETURN(0);
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT_INS_AND_RETURN(1);
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT_INS_AND_RETURN(2);
+
+ case SLJIT_MOV:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if (dst != src2) {
+ if (src2 & SRC2_IMM) {
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (op == SLJIT_MOV_UB)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]));
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst]));
+#else
+ return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2));
+#endif
+ }
+ else if (dst != src2) {
+ SLJIT_ASSERT(src2 & SRC2_IMM);
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
+ if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) {
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]));
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst]));
+#else
+ return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2));
+#endif
+ }
+ else if (dst != src2) {
+ SLJIT_ASSERT(src2 & SRC2_IMM);
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ if (src2 & SRC2_IMM) {
+ if (flags & INV_IMM)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2);
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2);
+ }
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(!(flags & INV_IMM));
+ SLJIT_ASSERT(!(src2 & SRC2_IMM));
+ FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2)));
+ if (flags & SET_FLAGS)
+ EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM);
+ return SLJIT_SUCCESS;
+ }
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+#undef EMIT_DATA_PROCESS_INS_AND_RETURN
+#undef EMIT_FULL_DATA_PROCESS_INS_AND_RETURN
+#undef EMIT_SHIFT_INS_AND_RETURN
+
+/* Tests whether the immediate can be stored in the 12 bit imm field.
+ Returns with 0 if not possible. */
+static sljit_uw get_immediate(sljit_uw imm)
+{
+ int rol;
+
+ if (imm <= 0xff)
+ return SRC2_IMM | imm;
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol = 8;
+ }
+ else {
+ imm = (imm << 24) | (imm >> 8);
+ rol = 0;
+ }
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol += 4;
+ }
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ return SRC2_IMM | (imm >> 24) | (rol << 8);
+ else
+ return 0;
+}
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+static int generate_int(struct sljit_compiler *compiler, int reg, sljit_uw imm, int positive)
+{
+ sljit_uw mask;
+ sljit_uw imm1;
+ sljit_uw imm2;
+ int rol;
+
+ /* Step1: Search a zero byte (8 continous zero bit). */
+ mask = 0xff000000;
+ rol = 8;
+ while(1) {
+ if (!(imm & mask)) {
+ /* Rol imm by rol. */
+ imm = (imm << rol) | (imm >> (32 - rol));
+ /* Calculate arm rol. */
+ rol = 4 + (rol >> 1);
+ break;
+ }
+ rol += 2;
+ mask >>= 2;
+ if (mask & 0x3) {
+ /* rol by 8. */
+ imm = (imm << 8) | (imm >> 24);
+ mask = 0xff00;
+ rol = 24;
+ while (1) {
+ if (!(imm & mask)) {
+ /* Rol imm by rol. */
+ imm = (imm << rol) | (imm >> (32 - rol));
+ /* Calculate arm rol. */
+ rol = (rol >> 1) - 8;
+ break;
+ }
+ rol += 2;
+ mask >>= 2;
+ if (mask & 0x3)
+ return 0;
+ }
+ break;
+ }
+ }
+
+ /* The low 8 bit must be zero. */
+ SLJIT_ASSERT(!(imm & 0xff));
+
+ if (!(imm & 0xff000000)) {
+ imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
+ imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
+ }
+ else if (imm & 0xc0000000) {
+ imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm <<= 8;
+ rol += 4;
+
+ if (!(imm & 0xff000000)) {
+ imm <<= 8;
+ rol += 4;
+ }
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ else
+ return 0;
+ }
+ else {
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
+ imm <<= 8;
+ rol += 4;
+
+ if (!(imm & 0xf0000000)) {
+ imm <<= 4;
+ rol += 2;
+ }
+
+ if (!(imm & 0xc0000000)) {
+ imm <<= 2;
+ rol += 1;
+ }
+
+ if (!(imm & 0x00ffffff))
+ imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8);
+ else
+ return 0;
+ }
+
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? MOV_DP : MVN_DP, 0, reg, SLJIT_UNUSED, imm1));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(positive ? ORR_DP : BIC_DP, 0, reg, reg, imm2));
+ return 1;
+}
+#endif
+
+static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_uw imm)
+{
+ sljit_uw tmp;
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff));
+#endif
+
+ /* Create imm by 1 inst. */
+ tmp = get_immediate(imm);
+ if (tmp) {
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp));
+ return SLJIT_SUCCESS;
+ }
+
+ tmp = get_immediate(~imm);
+ if (tmp) {
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp));
+ return SLJIT_SUCCESS;
+ }
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ /* Create imm by 2 inst. */
+ FAIL_IF(generate_int(compiler, reg, imm, 1));
+ FAIL_IF(generate_int(compiler, reg, ~imm, 0));
+
+ /* Load integer. */
+ return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), imm);
+#else
+ return emit_imm(compiler, reg, imm);
+#endif
+}
+
+/* Can perform an operation using at most 1 instruction. */
+static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw)
+{
+ sljit_uw imm;
+
+ if (arg & SLJIT_IMM) {
+ imm = get_immediate(argw);
+ if (imm) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm));
+ return -1;
+ }
+ imm = get_immediate(~argw);
+ if (imm) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, imm));
+ return -1;
+ }
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+ }
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads/stores. */
+ if (arg & 0xf) {
+ if (!(arg & 0xf0)) {
+ if (IS_TYPE1_TRANSFER(inp_flags)) {
+ if (argw >= 0 && argw <= 0xfff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, argw));
+ return -1;
+ }
+ if (argw < 0 && argw >= -0xfff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, -argw));
+ return -1;
+ }
+ }
+ else {
+ if (argw >= 0 && argw <= 0xff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw)));
+ return -1;
+ }
+ if (argw < 0 && argw >= -0xff) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ argw = -argw;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 0, inp_flags & WRITE_BACK, reg, arg & 0xf, TYPE2_TRANSFER_IMM(argw)));
+ return -1;
+ }
+ }
+ }
+ else if ((argw & 0x3) == 0 || IS_TYPE1_TRANSFER(inp_flags)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf,
+ RM((arg >> 4) & 0xf) | (IS_TYPE1_TRANSFER(inp_flags) ? SRC2_IMM : 0) | ((argw & 0x3) << 7)));
+ return -1;
+ }
+ }
+
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ /* Immediate caching is not supported as it would be an operation on constant arguments. */
+ if (arg & SLJIT_IMM)
+ return 0;
+
+ /* Always a simple operation. */
+ if (arg & 0xf0)
+ return 0;
+
+ if (!(arg & 0xf)) {
+ /* Immediate access. */
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
+ return 1;
+ return 0;
+ }
+
+ if (argw <= 0xfffff && argw >= -0xfffff)
+ return 0;
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM))
+ return 1;
+
+ if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= 0xfff || (sljit_uw)next_argw - (sljit_uw)argw <= 0xfff))
+ return 1;
+
+ return 0;
+}
+
+#define GETPUT_ARG_DATA_TRANSFER(add, wb, target, base, imm) \
+ if (max_delta & 0xf00) \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, imm))); \
+ else \
+ FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, add, wb, target, base, TYPE2_TRANSFER_IMM(imm))));
+
+#define TEST_WRITE_BACK() \
+ if (inp_flags & WRITE_BACK) { \
+ tmp_r = arg & 0xf; \
+ if (reg == tmp_r) { \
+ /* This can only happen for stores */ \
+ /* since ldr reg, [reg, ...]! has no meaning */ \
+ SLJIT_ASSERT(!(inp_flags & LOAD_DATA)); \
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(reg))); \
+ reg = TMP_REG3; \
+ } \
+ }
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_r;
+ sljit_w max_delta;
+ sljit_w sign;
+
+ if (arg & SLJIT_IMM) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ return load_immediate(compiler, reg, argw);
+ }
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
+ max_delta = IS_TYPE1_TRANSFER(inp_flags) ? 0xfff : 0xff;
+
+ if ((arg & 0xf) == SLJIT_UNUSED) {
+ /* Write back is not used. */
+ if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta)) {
+ if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) {
+ sign = 1;
+ argw = argw - compiler->cache_argw;
+ }
+ else {
+ sign = 0;
+ argw = compiler->cache_argw - argw;
+ }
+
+ if (max_delta & 0xf00) {
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, argw));
+ }
+ else {
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, TYPE2_TRANSFER_IMM(argw)));
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* With write back, we can create some sophisticated loads, but
+ it is hard to decide whether we should convert downward (0s) or upward (1s). */
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, tmp_r, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ /* Extended imm addressing for [reg+imm] format. */
+ sign = (max_delta << 8) | 0xff;
+ if (!(arg & 0xf0) && argw <= sign && argw >= -sign) {
+ TEST_WRITE_BACK();
+ if (argw >= 0) {
+ sign = 1;
+ }
+ else {
+ sign = 0;
+ argw = -argw;
+ }
+
+ /* Optimization: add is 0x4, sub is 0x2. Sign is 1 for add and 0 for sub. */
+ if (max_delta & 0xf00)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 12) | 0xa00));
+ else
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 8) | 0xc00));
+
+ argw &= max_delta;
+ GETPUT_ARG_DATA_TRANSFER(sign, inp_flags & WRITE_BACK, reg, tmp_r, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ if (arg & 0xf0) {
+ SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00));
+ if (inp_flags & WRITE_BACK)
+ tmp_r = arg & 0xf;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7)));
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, 0, reg, tmp_r, TYPE2_TRANSFER_IMM(0)));
+ return SLJIT_SUCCESS;
+ }
+
+ if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ argw = argw - compiler->cache_argw;
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ if (compiler->cache_arg == arg && ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ argw = compiler->cache_argw - argw;
+ GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, argw);
+ return SLJIT_SUCCESS;
+ }
+
+ if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
+ TEST_WRITE_BACK();
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ return SLJIT_SUCCESS;
+ }
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+
+ TEST_WRITE_BACK();
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, RM(TMP_REG3) | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ return SLJIT_SUCCESS;
+ }
+
+ if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf]));
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if ((arg & 0xf) == tmp_r) {
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & 0xf, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0)));
+ return SLJIT_SUCCESS;
+}
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+
+ /* We prefers register and simple consts. */
+ int dst_r;
+ int src1_r;
+ int src2_r = 0;
+ int sugg_src2_r = TMP_REG2;
+ int flags = GET_FLAGS(op) ? SET_FLAGS : 0;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ /* Destination check. */
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ sugg_src2_r = dst_r;
+ }
+ else if (dst == SLJIT_UNUSED) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ dst_r = TMP_REG2;
+ }
+ else {
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
+ flags |= FAST_DEST;
+ dst_r = TMP_REG2;
+ }
+ else {
+ flags |= SLOW_DEST;
+ dst_r = 0;
+ }
+ }
+
+ /* Source 1. */
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3)
+ src1_r = src1;
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) {
+ flags |= ARGS_SWAPPED;
+ src1_r = src2;
+ src2 = src1;
+ src2w = src1w;
+ }
+ else {
+ if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) {
+ /* The second check will generate a hit. */
+ src2_r = get_immediate(src1w);
+ if (src2_r) {
+ flags |= ARGS_SWAPPED;
+ src1 = src2;
+ src1w = src2w;
+ }
+ if (inp_flags & ALLOW_INV_IMM) {
+ src2_r = get_immediate(~src1w);
+ if (src2_r) {
+ flags |= ARGS_SWAPPED | INV_IMM;
+ src1 = src2;
+ src1w = src2w;
+ }
+ }
+ }
+
+ src1_r = 0;
+ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1_r = TMP_REG1;
+ }
+ }
+
+ /* Source 2. */
+ if (src2_r == 0) {
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) {
+ src2_r = src2;
+ flags |= REG_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ dst_r = src2_r;
+ }
+ else do { /* do { } while(0) is used because of breaks. */
+ if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) {
+ src2_r = get_immediate(src2w);
+ if (src2_r)
+ break;
+ if (inp_flags & ALLOW_INV_IMM) {
+ src2_r = get_immediate(~src2w);
+ if (src2_r) {
+ flags |= INV_IMM;
+ break;
+ }
+ }
+ }
+
+ /* src2_r is 0. */
+ if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2_r = sugg_src2_r;
+ }
+ } while (0);
+ }
+
+ /* src1_r, src2_r and dst_r can be zero (=unprocessed) or non-zero.
+ If they are zero, they must not be registers. */
+ if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ SLJIT_ASSERT(!(flags & ARGS_SWAPPED));
+ flags |= ARGS_SWAPPED;
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ src1_r = TMP_REG1;
+ src2_r = TMP_REG2;
+ }
+ else if (src1_r == 0 && src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ src1_r = TMP_REG1;
+ }
+ else if (src1_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1_r = TMP_REG1;
+ }
+ else if (src2_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+ src2_r = sugg_src2_r;
+ }
+
+ if (dst_r == 0)
+ dst_r = TMP_REG2;
+
+ if (src1_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
+ src1_r = TMP_REG1;
+ }
+
+ if (src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+ src2_r = sugg_src2_r;
+ }
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (flags & (FAST_DEST | SLOW_DEST)) {
+ if (flags & FAST_DEST)
+ FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw));
+ else
+ FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__)
+extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator);
+extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator);
+#else
+#error "Software divmod functions are needed"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ EMIT_INSTRUCTION(BKPT);
+ break;
+ case SLJIT_NOP:
+ EMIT_INSTRUCTION(NOP);
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+ return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
+ | (reg_map[SLJIT_TEMPORARY_REG2] << 16)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 8)
+ | reg_map[SLJIT_TEMPORARY_REG2]);
+#else
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL)
+ | (reg_map[SLJIT_TEMPORARY_REG2] << 16)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 12)
+ | (reg_map[SLJIT_TEMPORARY_REG1] << 8)
+ | reg_map[TMP_REG1]);
+#endif
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ if (compiler->temporaries >= 3)
+ EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */);
+#if defined(__GNUC__)
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
+ (op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
+#else
+#error "Software divmod functions are needed"
+#endif
+ if (compiler->temporaries >= 3)
+ return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */);
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOV_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOV_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOV_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_MOVU:
+ case SLJIT_MOVU_UI:
+ case SLJIT_MOVU_SI:
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOVU_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOVU_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOVU_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, SLJIT_SUB | GET_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+ if (src2 & SLJIT_IMM) {
+ compiler->shift_imm = src2w & 0x1f;
+ return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w);
+ }
+ else {
+ compiler->shift_imm = 0x20;
+ return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w);
+ }
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 4);
+
+ return push_inst(compiler, *(sljit_uw*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+
+/* 0 - no fpu
+ 1 - vfp */
+static int arm_fpu_type = -1;
+
+static void init_compiler()
+{
+ if (arm_fpu_type != -1)
+ return;
+
+ /* TODO: Only the OS can help to determine the correct fpu type. */
+ arm_fpu_type = 1;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ if (arm_fpu_type == -1)
+ init_compiler();
+ return arm_fpu_type;
+}
+
+#else
+
+#define arm_fpu_type 1
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+#endif
+
+#define EMIT_FPU_DATA_TRANSFER(add, load, base, freg, offs) \
+ (VSTR | ((add) << 23) | ((load) << 20) | (reg_map[base] << 16) | (freg << 12) | (offs))
+#define EMIT_FPU_OPERATION(opcode, dst, src1, src2) \
+ ((opcode) | ((dst) << 12) | (src1) | ((src2) << 16))
+
+static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if ((arg & 0xf) && !(arg & 0xf0) && (argw & 0x3) == 0) {
+ if (argw >= 0 && argw <= 0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, arg & 0xf, fpu_reg, argw >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (argw < 0 && argw >= -0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, arg & 0xf, fpu_reg, (-argw) >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (argw >= 0 && argw <= 0x3ffff) {
+ SLJIT_ASSERT(get_immediate(argw & 0x3fc00));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00)));
+ argw &= 0x3ff;
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, argw >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (argw < 0 && argw >= -0x3ffff) {
+ argw = -argw;
+ SLJIT_ASSERT(get_immediate(argw & 0x3fc00));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00)));
+ argw &= 0x3ff;
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG1, fpu_reg, argw >> 2));
+ return SLJIT_SUCCESS;
+ }
+ }
+
+ if (arg & 0xf0) {
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7)));
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, 0));
+ return SLJIT_SUCCESS;
+ }
+
+ if (compiler->cache_arg == arg && ((argw - compiler->cache_argw) & 0x3) == 0) {
+ if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= 0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, (argw - compiler->cache_argw) >> 2));
+ return SLJIT_SUCCESS;
+ }
+ if (((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= 0x3ff) {
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG3, fpu_reg, (compiler->cache_argw - argw) >> 2));
+ return SLJIT_SUCCESS;
+ }
+ }
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ if (arg & 0xf) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, arg & 0xf, reg_map[TMP_REG1]));
+ }
+ else
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, 0));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_freg;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));
+ dst = TMP_FREG1;
+ }
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));
+ src = TMP_FREG2;
+ }
+ EMIT_INSTRUCTION(VCMP_F64 | (dst << 12) | src);
+ EMIT_INSTRUCTION(VMRS);
+ return SLJIT_SUCCESS;
+ }
+
+ dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, dst_freg, 1, src, srcw));
+ src = dst_freg;
+ }
+
+ switch (op) {
+ case SLJIT_FMOV:
+ if (src != dst_freg && dst_freg != TMP_FREG1)
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F64, dst_freg, src, 0));
+ break;
+ case SLJIT_FNEG:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F64, dst_freg, src, 0));
+ break;
+ case SLJIT_FABS:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F64, dst_freg, src, 0));
+ break;
+ }
+
+ if (dst_freg == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_freg;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src2 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F64, dst_freg, src2, src1));
+ break;
+
+ case SLJIT_FSUB:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F64, dst_freg, src2, src1));
+ break;
+
+ case SLJIT_FMUL:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F64, dst_freg, src2, src1));
+ break;
+
+ case SLJIT_FDIV:
+ EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F64, dst_freg, src2, src1));
+ break;
+ }
+
+ if (dst_freg == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ size = (1 + saveds) * sizeof(sljit_uw);
+ if (temporaries >= 4)
+ size += (temporaries - 3) * sizeof(sljit_uw);
+ local_size += size;
+ local_size = (local_size + 7) & ~7;
+ local_size -= size;
+ compiler->local_size = local_size;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3)));
+ else if (dst & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw))
+ return compiler->error;
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3)));
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src)));
+ else if (src & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw))
+ FAIL_IF(compiler->error);
+ else {
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ FAIL_IF(getput_arg(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw, 0, 0));
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(TMP_REG2)));
+ }
+ }
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG3, srcw));
+ return push_inst(compiler, BLX | RM(TMP_REG3));
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+static sljit_uw get_cc(int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_EQUAL:
+ return 0x00000000;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_MUL_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return 0x10000000;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return 0x30000000;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return 0x20000000;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return 0x80000000;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return 0x90000000;
+
+ case SLJIT_C_SIG_LESS:
+ return 0xb0000000;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return 0xa0000000;
+
+ case SLJIT_C_SIG_GREATER:
+ return 0xc0000000;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return 0xd0000000;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_FLOAT_NAN:
+ return 0x60000000;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return 0x70000000;
+
+ default: /* SLJIT_JUMP */
+ return 0xe0000000;
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In ARM, we don't need to touch the arguments. */
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (type >= SLJIT_FAST_CALL)
+ PTR_FAIL_IF(prepare_blx(compiler));
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0,
+ type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0));
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+ jump->addr = compiler->size;
+ compiler->patches++;
+ }
+
+ if (type >= SLJIT_FAST_CALL) {
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(emit_blx(compiler));
+ }
+
+ if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
+ jump->addr = compiler->size;
+#else
+ if (type >= SLJIT_FAST_CALL)
+ jump->flags |= IS_BL;
+ PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+ PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type)));
+ jump->addr = compiler->size;
+#endif
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ /* In ARM, we don't need to touch the arguments. */
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
+ jump->u.target = srcw;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ if (type >= SLJIT_FAST_CALL)
+ FAIL_IF(prepare_blx(compiler));
+ FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));
+ if (type >= SLJIT_FAST_CALL)
+ FAIL_IF(emit_blx(compiler));
+#else
+ FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+ FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));
+#endif
+ jump->addr = compiler->size;
+ }
+ else {
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src));
+
+ SLJIT_ASSERT(src & SLJIT_MEM);
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int reg;
+ sljit_uw cc;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ cc = get_cc(type);
+ if (GET_OPCODE(op) == SLJIT_OR) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ORR_DP, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc);
+ if (op & SLJIT_SET_E)
+ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst)));
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 0));
+ EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc);
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return emit_op(compiler, op, ALLOW_IMM, dst, dstw, TMP_REG1, 0, dst, dstw);
+ }
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 0));
+ EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc);
+
+ if (reg == TMP_REG2)
+ return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int reg;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value));
+ compiler->patches++;
+#else
+ PTR_FAIL_IF(emit_imm(compiler, reg, init_value));
+#endif
+ set_const(const_, compiler);
+
+ if (reg == TMP_REG2 && dst != SLJIT_UNUSED)
+ if (emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0))
+ return NULL;
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ inline_set_jump_addr(addr, new_addr, 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ inline_set_const(addr, new_constant, 1);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c b/src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c
new file mode 100644
index 00000000000..c0cc8b58bb7
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeMIPS_32.c
@@ -0,0 +1,405 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* mips 32-bit arch dependent functions. */
+
+static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm)
+{
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ if (imm < 0 && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+ FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
+}
+
+#define EMIT_LOGICAL(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
+ }
+
+#define EMIT_SHIFT(op_imm, op_norm) \
+ if (flags & SRC2_IMM) { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
+ } \
+ else { \
+ if (op & SLJIT_SET_E) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+ if (CHECK_FLAGS(SLJIT_SET_E)) \
+ FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
+ }
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, sljit_w src2)
+{
+ int overflow_ra = 0;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src2 < 0)
+ FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ else {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ }
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+ if (src2 < 0)
+ FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG));
+ }
+ }
+ else {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src1 != dst)
+ overflow_ra = DR(src1);
+ else if (src2 != dst)
+ overflow_ra = DR(src2);
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+ }
+ }
+
+ /* a + b >= a | b (otherwise, the carry should be set to 1). */
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (op & SLJIT_SET_O)
+ return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ADDC:
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C) {
+ if (src2 >= 0)
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+ else {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
+ }
+ }
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
+ } else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
+
+ FAIL_IF(push_inst(compiler, ADDU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+ if (!(op & SLJIT_SET_C))
+ return SLJIT_SUCCESS;
+
+ /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
+ FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2));
+ FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
+ /* Set carry flag. */
+ return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
+
+ case SLJIT_SUB:
+ if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src2 < 0)
+ FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
+ if (src1 != dst)
+ overflow_ra = DR(src1);
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
+ if (src1 != dst)
+ overflow_ra = DR(src1);
+ else {
+ /* Rare ocasion. */
+ FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
+ overflow_ra = TMP_EREG2;
+ }
+ }
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (op & (SLJIT_SET_U | SLJIT_SET_C))
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+ if (op & SLJIT_SET_U)
+ FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
+ if (op & SLJIT_SET_S) {
+ FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
+ FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
+ }
+ /* dst may be the same as src1 or src2. */
+ if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (op & SLJIT_SET_O) {
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+ return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+ }
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SUBC:
+ if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+ src2 = TMP_REG2;
+ flags &= ~SRC2_IMM;
+ }
+
+ if (flags & SRC2_IMM) {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+ }
+ else {
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+ /* dst may be the same as src1 or src2. */
+ FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
+ }
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1));
+
+ FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+
+ if (op & SLJIT_SET_C)
+ FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG));
+
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MUL:
+ SLJIT_ASSERT(!(flags & SRC2_IMM));
+ if (!(op & SLJIT_SET_O)) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
+#endif
+ }
+ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
+ FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+ FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
+ return push_inst(compiler, SUBU | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+
+ case SLJIT_AND:
+ EMIT_LOGICAL(ANDI, AND);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_OR:
+ EMIT_LOGICAL(ORI, OR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_XOR:
+ EMIT_LOGICAL(XORI, XOR);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_SHL:
+ EMIT_SHIFT(SLL, SLLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_LSHR:
+ EMIT_SHIFT(SRL, SRLV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_ASHR:
+ EMIT_SHIFT(SRA, SRAV);
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SB) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
+#endif
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SH) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
+#else
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
+#endif
+ }
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ if (op & SLJIT_SET_E)
+ FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+ if (CHECK_FLAGS(SLJIT_SET_E))
+ FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
+#else
+ if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
+ FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
+ return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
+ }
+ /* Nearly all instructions are unmovable in the following sequence. */
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ /* Check zero. */
+ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
+ /* Check sign bit. */
+ FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS));
+ /* Loop for searching the highest bit. */
+ FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS));
+ if (op & SLJIT_SET_E)
+ return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
+#endif
+ return SLJIT_SUCCESS;
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
+{
+ FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg)));
+ return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c b/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
new file mode 100644
index 00000000000..3c6ee663e15
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
@@ -0,0 +1,1829 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "MIPS" SLJIT_CPUINFO;
+}
+
+/* Latest MIPS architecture. */
+/* Detect SLJIT_MIPS_32_64 */
+
+/* Length of an instruction word
+ Both for mips-32 and mips-64 */
+typedef sljit_ui sljit_ins;
+
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define REAL_STACK_PTR (SLJIT_NO_REGISTERS + 4)
+
+/* For position independent code, t9 must contain the function address. */
+#define PIC_ADDR_REG TMP_REG2
+
+/* TMP_EREG1 is used mainly for literal encoding on 64 bit. */
+#define TMP_EREG1 15
+#define TMP_EREG2 24
+/* Floating point status register. */
+#define FCSR_REG 31
+/* Return address register. */
+#define RETURN_ADDR_REG 31
+
+/* Flags are keept in volatile registers. */
+#define EQUAL_FLAG 7
+/* And carry flag as well. */
+#define ULESS_FLAG 10
+#define UGREATER_FLAG 11
+#define LESS_FLAG 12
+#define GREATER_FLAG 13
+#define OVERFLOW_FLAG 14
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+
+#define S(s) (reg_map[s] << 21)
+#define T(t) (reg_map[t] << 16)
+#define D(d) (reg_map[d] << 11)
+/* Absolute registers. */
+#define SA(s) ((s) << 21)
+#define TA(t) ((t) << 16)
+#define DA(d) ((d) << 11)
+#define FT(t) ((t) << (16 + 1))
+#define FS(s) ((s) << (11 + 1))
+#define FD(d) ((d) << (6 + 1))
+#define IMM(imm) ((imm) & 0xffff)
+#define SH_IMM(imm) ((imm & 0x1f) << 6)
+
+#define DR(dr) (reg_map[dr])
+#define HI(opcode) ((opcode) << 26)
+#define LO(opcode) (opcode)
+#define FMT_D (17 << 21)
+
+#define ABS_D (HI(17) | FMT_D | LO(5))
+#define ADD_D (HI(17) | FMT_D | LO(0))
+#define ADDU (HI(0) | LO(33))
+#define ADDIU (HI(9))
+#define AND (HI(0) | LO(36))
+#define ANDI (HI(12))
+#define B (HI(4))
+#define BAL (HI(1) | (17 << 16))
+#define BC1F (HI(17) | (8 << 21))
+#define BC1T (HI(17) | (8 << 21) | (1 << 16))
+#define BEQ (HI(4))
+#define BGEZ (HI(1) | (1 << 16))
+#define BGTZ (HI(7))
+#define BLEZ (HI(6))
+#define BLTZ (HI(1) | (0 << 16))
+#define BNE (HI(5))
+#define BREAK (HI(0) | LO(13))
+#define C_UN_D (HI(17) | FMT_D | LO(49))
+#define C_UEQ_D (HI(17) | FMT_D | LO(51))
+#define C_ULE_D (HI(17) | FMT_D | LO(55))
+#define C_ULT_D (HI(17) | FMT_D | LO(53))
+#define DIV (HI(0) | LO(26))
+#define DIVU (HI(0) | LO(27))
+#define DIV_D (HI(17) | FMT_D | LO(3))
+#define J (HI(2))
+#define JAL (HI(3))
+#define JALR (HI(0) | LO(9))
+#define JR (HI(0) | LO(8))
+#define LD (HI(55))
+#define LDC1 (HI(53))
+#define LUI (HI(15))
+#define LW (HI(35))
+#define NEG_D (HI(17) | FMT_D | LO(7))
+#define MFHI (HI(0) | LO(16))
+#define MFLO (HI(0) | LO(18))
+#define MOV_D (HI(17) | FMT_D | LO(6))
+#define CFC1 (HI(17) | (2 << 21))
+#define MOVN (HI(0) | LO(11))
+#define MOVZ (HI(0) | LO(10))
+#define MUL_D (HI(17) | FMT_D | LO(2))
+#define MULT (HI(0) | LO(24))
+#define MULTU (HI(0) | LO(25))
+#define NOP (HI(0) | LO(0))
+#define NOR (HI(0) | LO(39))
+#define OR (HI(0) | LO(37))
+#define ORI (HI(13))
+#define SD (HI(63))
+#define SDC1 (HI(61))
+#define SLT (HI(0) | LO(42))
+#define SLTI (HI(10))
+#define SLTIU (HI(11))
+#define SLTU (HI(0) | LO(43))
+#define SLL (HI(0) | LO(0))
+#define SLLV (HI(0) | LO(4))
+#define SRL (HI(0) | LO(2))
+#define SRLV (HI(0) | LO(6))
+#define SRA (HI(0) | LO(3))
+#define SRAV (HI(0) | LO(7))
+#define SUB_D (HI(17) | FMT_D | LO(1))
+#define SUBU (HI(0) | LO(35))
+#define SW (HI(43))
+#define XOR (HI(0) | LO(38))
+#define XORI (HI(14))
+
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+#define CLZ (HI(28) | LO(32))
+#define MUL (HI(28) | LO(2))
+#define SEB (HI(31) | (16 << 6) | LO(32))
+#define SEH (HI(31) | (24 << 6) | LO(32))
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define ADDU_W ADDU
+#define ADDIU_W ADDIU
+#define SLL_W SLL
+#define SUBU_W SUBU
+#else
+#define ADDU_W DADDU
+#define ADDIU_W DADDIU
+#define SLL_W DSLL
+#define SUBU_W DSUBU
+#endif
+
+#define SIMM_MAX (0x7fff)
+#define SIMM_MIN (-0x8000)
+#define UIMM_MAX (0xffff)
+
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
+ 0, 2, 5, 6, 3, 8, 17, 18, 19, 20, 21, 16, 4, 25, 9, 29
+};
+
+/* dest_reg is the absolute name of the register
+ Useful for reordering instructions in the delay slot. */
+static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot)
+{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ compiler->delay_slot = delay_slot;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE sljit_ins invert_branch(int flags)
+{
+ return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
+}
+
+static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+{
+ sljit_w diff;
+ sljit_uw target_addr;
+ sljit_ins *inst;
+ sljit_ins saved_inst;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return code_ptr;
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size);
+ }
+ inst = (sljit_ins*)jump->addr;
+ if (jump->flags & IS_COND)
+ inst--;
+
+ /* B instructions. */
+ if (jump->flags & IS_MOVABLE) {
+ diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2;
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ inst[0] = inst[-1];
+ inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+ saved_inst = inst[0];
+ inst[0] = inst[-1];
+ inst[-1] = saved_inst ^ invert_branch(jump->flags);
+ jump->addr -= 2 * sizeof(sljit_ins);
+ return inst;
+ }
+ }
+
+ diff = ((sljit_w)target_addr - (sljit_w)(inst + 1)) >> 2;
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
+ jump->flags |= PATCH_B;
+
+ if (!(jump->flags & IS_COND)) {
+ inst[0] = (jump->flags & IS_JAL) ? BAL : B;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+ inst[0] = inst[0] ^ invert_branch(jump->flags);
+ inst[1] = NOP;
+ jump->addr -= sizeof(sljit_ins);
+ return inst + 1;
+ }
+
+ if (jump->flags & IS_COND) {
+ if ((target_addr & ~0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (inst[0] & 0xffff0000) | 3;
+ inst[1] = NOP;
+ inst[2] = J;
+ inst[3] = NOP;
+ jump->addr += sizeof(sljit_ins);
+ return inst + 3;
+ }
+ return code_ptr;
+ }
+
+ /* J instuctions. */
+ if (jump->flags & IS_MOVABLE) {
+ if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = inst[-1];
+ inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
+ jump->addr -= sizeof(sljit_ins);
+ return inst;
+ }
+ }
+
+ if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) {
+ jump->flags |= PATCH_J;
+ inst[0] = (jump->flags & IS_JAL) ? JAL : J;
+ inst[1] = NOP;
+ return inst + 1;
+ }
+
+ return code_ptr;
+}
+
+#ifdef __GNUC__
+static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
+{
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+}
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 6);
+#endif
+ code_ptr = optimize_jump(jump, code_ptr, code);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size);
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins*)jump->addr;
+
+ if (jump->flags & PATCH_B) {
+ addr = (sljit_w)(addr - (jump->addr + sizeof(sljit_ins))) >> 2;
+ SLJIT_ASSERT((sljit_w)addr <= SIMM_MAX && (sljit_w)addr >= SIMM_MIN);
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff);
+ break;
+ }
+ if (jump->flags & PATCH_J) {
+ SLJIT_ASSERT((addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff));
+ buf_ptr[0] |= (addr >> 2) & 0x03ffffff;
+ break;
+ }
+
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+#else
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size * sizeof(sljit_ins);
+#ifndef __GNUC__
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+#else
+ /* GCC workaround for invalid code generation with -O2. */
+ sljit_cache_flush(code, code_ptr);
+#endif
+ return code;
+}
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x01
+#define HALF_DATA 0x02
+#define INT_DATA 0x03
+#define SIGNED_DATA 0x04
+#define LOAD_DATA 0x08
+
+#define MEM_MASK 0x0f
+
+#define WRITE_BACK 0x00010
+#define ARG_TEST 0x00020
+#define CUMULATIVE_OP 0x00040
+#define LOGICAL_OP 0x00080
+#define IMM_OP 0x00100
+#define SRC2_IMM 0x00200
+
+#define UNUSED_DEST 0x00400
+#define REG_DEST 0x00800
+#define REG1_SOURCE 0x01000
+#define REG2_SOURCE 0x02000
+#define SLOW_SRC1 0x04000
+#define SLOW_SRC2 0x08000
+#define SLOW_DEST 0x10000
+
+/* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */
+#define CHECK_FLAGS(list) \
+ (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#include "sljitNativeMIPS_32.c"
+#else
+#include "sljitNativeMIPS_64.c"
+#endif
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define STACK_STORE SW
+#define STACK_LOAD LW
+#else
+#define STACK_STORE SD
+#define STACK_LOAD LD
+#endif
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ sljit_ins base;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+ local_size += (saveds + 2 + 4) * sizeof(sljit_w);
+ local_size = (local_size + 15) & ~0xf;
+ compiler->local_size = local_size;
+
+ if (local_size <= SIMM_MAX) {
+ /* Frequent case. */
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(REAL_STACK_PTR) | IMM(-local_size), DR(REAL_STACK_PTR)));
+ base = S(REAL_STACK_PTR);
+ }
+ else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(REAL_STACK_PTR) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ FAIL_IF(push_inst(compiler, SUBU_W | S(REAL_STACK_PTR) | T(TMP_REG1) | D(REAL_STACK_PTR), DR(REAL_STACK_PTR)));
+ base = S(TMP_REG2);
+ local_size = 0;
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS));
+ if (saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), MOVABLE_INS));
+
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(SLJIT_LOCALS_REG) | IMM(4 * sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(5) | TA(0) | D(SLJIT_SAVED_REG2), DR(SLJIT_SAVED_REG2)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(6) | TA(0) | D(SLJIT_SAVED_REG3), DR(SLJIT_SAVED_REG3)));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+ local_size += (saveds + 2 + 4) * sizeof(sljit_w);
+ compiler->local_size = (local_size + 15) & ~0xf;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ int local_size;
+ sljit_ins base;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ local_size = compiler->local_size;
+ if (local_size <= SIMM_MAX)
+ base = S(REAL_STACK_PTR);
+ else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(REAL_STACK_PTR) | T(TMP_REG1) | D(TMP_REG1), DR(TMP_REG1)));
+ base = S(TMP_REG1);
+ local_size = 0;
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG));
+ if (compiler->saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 7 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2)));
+ if (compiler->saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1)));
+ if (compiler->saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3)));
+ if (compiler->saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2)));
+ if (compiler->saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1)));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_LOCALS_REG) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_LOCALS_REG)));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ if (compiler->local_size <= SIMM_MAX)
+ return push_inst(compiler, ADDIU_W | S(REAL_STACK_PTR) | T(REAL_STACK_PTR) | IMM(compiler->local_size), UNMOVABLE_INS);
+ else
+ return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(REAL_STACK_PTR), UNMOVABLE_INS);
+}
+
+#undef STACK_STORE
+#undef STACK_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define ARCH_DEPEND(a, b) a
+#else
+#define ARCH_DEPEND(a, b) b
+#endif
+
+static SLJIT_CONST sljit_ins data_transfer_insts[16] = {
+/* s u w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */),
+/* s u b */ HI(40) /* sb */,
+/* s u h */ HI(41) /* sh*/,
+/* s u i */ HI(43) /* sw */,
+
+/* s s w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */),
+/* s s b */ HI(40) /* sb */,
+/* s s h */ HI(41) /* sh*/,
+/* s s i */ HI(43) /* sw */,
+
+/* l u w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */),
+/* l u b */ HI(36) /* lbu */,
+/* l u h */ HI(37) /* lhu */,
+/* l u i */ ARCH_DEPEND(HI(35) /* lw */, HI(39) /* lwu */),
+
+/* l s w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */),
+/* l s b */ HI(32) /* lb */,
+/* l s h */ HI(33) /* lh */,
+/* l s i */ HI(35) /* lw */,
+};
+
+/* reg_ar is an absoulute register! */
+
+/* Can perform an operation using at most 1 instruction. */
+static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ /* Works for both absoulte and relative addresses. */
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
+ return 1;
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) | TA(reg_ar) | IMM(argw), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS));
+ return -1;
+ }
+ return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those
+ operators always uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ if (!(next_arg & SLJIT_MEM))
+ return 0;
+
+ /* Simple operation except for updates. */
+ if (arg & 0xf0) {
+ argw &= 0x3;
+ next_argw &= 0x3;
+ if (argw && argw == next_argw && (arg == next_arg || (arg & 0xf0) == (next_arg & 0xf0)))
+ return 1;
+ return 0;
+ }
+
+ if (arg == next_arg) {
+ if (((sljit_uw)(next_argw - argw) <= SIMM_MAX && (sljit_uw)(next_argw - argw) >= SIMM_MIN))
+ return 1;
+ return 0;
+ }
+
+ return 0;
+}
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_ar;
+ int base;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(next_arg & SLJIT_MEM)) {
+ next_arg = 0;
+ next_argw = 0;
+ }
+
+ tmp_ar = (flags & LOAD_DATA) ? reg_ar : DR(TMP_REG3);
+ base = arg & 0xf;
+
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ argw &= 0x3;
+ if ((flags & WRITE_BACK) && reg_ar == DR(base)) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ reg_ar = DR(TMP_REG1);
+ }
+
+ /* Using the cache. */
+ if (argw == compiler->cache_argw) {
+ if (!(flags & WRITE_BACK)) {
+ if (arg == compiler->cache_arg)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ }
+ else {
+ if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) {
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ }
+ }
+
+ if (SLJIT_UNLIKELY(argw)) {
+ compiler->cache_arg = SLJIT_MEM | (arg & 0xf0);
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, SLL_W | T((arg >> 4) & 0xf) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
+ }
+
+ if (!(flags & WRITE_BACK)) {
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
+ tmp_ar = DR(TMP_REG3);
+ }
+ else
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
+ /* Update only applies if a base register exists. */
+ if (reg_ar == DR(base)) {
+ SLJIT_ASSERT(!(flags & LOAD_DATA) && DR(TMP_REG1) != reg_ar);
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar) | IMM(argw), MOVABLE_INS));
+ if (argw)
+ return push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base));
+ return SLJIT_SUCCESS;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(reg_ar) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
+ reg_ar = DR(TMP_REG1);
+ }
+
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (argw)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)));
+ }
+ else {
+ if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ }
+ else {
+ compiler->cache_arg = SLJIT_MEM;
+ compiler->cache_argw = argw;
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
+ }
+ }
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw) {
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ compiler->cache_argw = argw;
+ }
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
+ if (argw != compiler->cache_argw)
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
+ }
+ else {
+ compiler->cache_arg = SLJIT_MEM;
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ }
+ compiler->cache_argw = argw;
+
+ if (!base)
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+
+ if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
+ compiler->cache_arg = arg;
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+ }
+
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS);
+}
+
+static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw)
+{
+ if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
+ return compiler->error;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
+}
+
+static int emit_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ int dst_r = TMP_REG2;
+ int src1_r;
+ sljit_w src2_r = 0;
+ int sugg_src2_r = TMP_REG2;
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)
+ sugg_src2_r = dst_r;
+ }
+ else if (dst == SLJIT_UNUSED) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ if (GET_FLAGS(op))
+ flags |= UNUSED_DEST;
+ }
+ else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
+ flags |= SLOW_DEST;
+
+ if (flags & IMM_OP) {
+ if ((src2 & SLJIT_IMM) && src2w) {
+ if ((!(flags & LOGICAL_OP) && (src2w <= SIMM_MAX && src2w >= SIMM_MIN))
+ || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src2w;
+ }
+ }
+ if ((src1 & SLJIT_IMM) && src1w && (flags & CUMULATIVE_OP) && !(flags & SRC2_IMM)) {
+ if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN))
+ || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) {
+ flags |= SRC2_IMM;
+ src2_r = src1w;
+
+ /* And swap arguments. */
+ src1 = src2;
+ src1w = src2w;
+ src2 = SLJIT_IMM;
+ /* src2w = src2_r unneeded. */
+ }
+ }
+ }
+
+ /* Source 1. */
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ }
+ else if (src1 & SLJIT_IMM) {
+ if (src1w) {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC1;
+ src1_r = TMP_REG1;
+ }
+
+ /* Source 2. */
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+ if (!(flags & SRC2_IMM)) {
+ if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) {
+ FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
+ src2_r = sugg_src2_r;
+ }
+ else
+ src2_r = 0;
+ }
+ }
+ else {
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
+ FAIL_IF(compiler->error);
+ else
+ flags |= SLOW_SRC2;
+ src2_r = sugg_src2_r;
+ }
+
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
+ SLJIT_ASSERT(src2_r == TMP_REG2);
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
+ }
+ }
+ else if (flags & SLOW_SRC1)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ else if (flags & SLOW_SRC2)
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (dst & SLJIT_MEM) {
+ if (!(flags & SLOW_DEST)) {
+ getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
+ return compiler->error;
+ }
+ return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ op = GET_OPCODE(op);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ return push_inst(compiler, BREAK, UNMOVABLE_INS);
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1)));
+ return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2));
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+#if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+#endif
+ FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS));
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1)));
+ return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #define inp_flags 0
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOV_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOV_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOV_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_MOVU:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOVU_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOVU_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOVU_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), inp_flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
+
+ case SLJIT_CLZ:
+ return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #undef inp_flags
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #define inp_flags 0
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ case SLJIT_SUBC:
+ return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+ return emit_op(compiler, op, inp_flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x1f;
+#else
+ if (src2 & SLJIT_IMM)
+ src2w &= 0x3f;
+#endif
+ return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ #undef inp_flags
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 4);
+
+ return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+#if (defined SLJIT_QEMU && SLJIT_QEMU)
+ /* Qemu says fir is 0 by default. */
+ return 1;
+#elif defined(__GNUC__)
+ sljit_w fir;
+ asm ("cfc1 %0, $0" : "=r"(fir));
+ return (fir >> 22) & 0x1;
+#else
+#error "FIR check is not implemented for this architecture"
+#endif
+}
+
+static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)
+{
+ int hi_reg;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (!(arg & 0xf0)) {
+ /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(arg & 0xf) | FT(fpu_reg) | IMM(argw), MOVABLE_INS);
+ }
+
+ if (arg & 0xf0) {
+ argw &= 0x3;
+ hi_reg = (arg >> 4) & 0xf;
+ if (argw) {
+ FAIL_IF(push_inst(compiler, SLL_W | T(hi_reg) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));
+ hi_reg = TMP_REG1;
+ }
+ FAIL_IF(push_inst(compiler, ADDU_W | S(hi_reg) | T(arg & 0xf) | D(TMP_REG1), DR(TMP_REG1)));
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG1) | FT(fpu_reg) | IMM(0), MOVABLE_INS);
+ }
+
+ /* Use cache. */
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(argw - compiler->cache_argw), MOVABLE_INS);
+
+ /* Put value to cache. */
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
+ if (arg & 0xf)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(arg & 0xf) | D(TMP_REG3), DR(TMP_REG3)));
+ return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(0), MOVABLE_INS);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));
+ dst = TMP_FREG1;
+ }
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));
+ src = TMP_FREG2;
+ }
+
+ /* src and dst are swapped. */
+ if (op & SLJIT_SET_E) {
+ FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG));
+ }
+ if (op & SLJIT_SET_S) {
+ /* Mixing the instructions for the two checks. */
+ FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS));
+ FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG));
+ FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG));
+ FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG));
+ FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG));
+ }
+ return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC);
+ }
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw));
+ src = dst_fr;
+ }
+
+ switch (op) {
+ case SLJIT_FMOV:
+ if (src != dst_fr && dst_fr != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, MOV_D | FS(src) | FD(dst_fr), MOVABLE_INS));
+ break;
+ case SLJIT_FNEG:
+ FAIL_IF(push_inst(compiler, NEG_D | FS(src) | FD(dst_fr), MOVABLE_INS));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(push_inst(compiler, ABS_D | FS(src) | FD(dst_fr), MOVABLE_INS));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src2 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(push_inst(compiler, ADD_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+
+ case SLJIT_FSUB:
+ FAIL_IF(push_inst(compiler, SUB_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+
+ case SLJIT_FMUL:
+ FAIL_IF(push_inst(compiler, MUL_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+
+ case SLJIT_FDIV:
+ FAIL_IF(push_inst(compiler, DIV_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+ local_size += (saveds + 2 + 4) * sizeof(sljit_w);
+ compiler->local_size = (local_size + 15) & ~0xf;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst));
+ else if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ compiler->delay_slot = UNMOVABLE_INS;
+ return label;
+}
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#define JUMP_LENGTH 4
+#else
+#define JUMP_LENGTH 7
+#endif
+
+#define BR_Z(src) \
+ inst = BEQ | SA(src) | TA(0) | JUMP_LENGTH; \
+ flags = IS_BIT26_COND; \
+ delay_check = src;
+
+#define BR_NZ(src) \
+ inst = BNE | SA(src) | TA(0) | JUMP_LENGTH; \
+ flags = IS_BIT26_COND; \
+ delay_check = src;
+
+#define BR_T() \
+ inst = BC1T | JUMP_LENGTH; \
+ flags = IS_BIT16_COND; \
+ delay_check = FCSR_FCC;
+
+#define BR_F() \
+ inst = BC1F | JUMP_LENGTH; \
+ flags = IS_BIT16_COND; \
+ delay_check = FCSR_FCC;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ int flags = 0;
+ int delay_check = UNMOVABLE_INS;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ BR_NZ(EQUAL_FLAG);
+ break;
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_FLOAT_EQUAL:
+ BR_Z(EQUAL_FLAG);
+ break;
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ BR_Z(ULESS_FLAG);
+ break;
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ BR_NZ(ULESS_FLAG);
+ break;
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ BR_Z(UGREATER_FLAG);
+ break;
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ BR_NZ(UGREATER_FLAG);
+ break;
+ case SLJIT_C_SIG_LESS:
+ BR_Z(LESS_FLAG);
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ BR_NZ(LESS_FLAG);
+ break;
+ case SLJIT_C_SIG_GREATER:
+ BR_Z(GREATER_FLAG);
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ BR_NZ(GREATER_FLAG);
+ break;
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ BR_Z(OVERFLOW_FLAG);
+ break;
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ BR_NZ(OVERFLOW_FLAG);
+ break;
+ case SLJIT_C_FLOAT_NAN:
+ BR_F();
+ break;
+ case SLJIT_C_FLOAT_NOT_NAN:
+ BR_T();
+ break;
+ default:
+ /* Not conditional branch. */
+ inst = 0;
+ break;
+ }
+
+ jump->flags |= flags;
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
+ jump->flags |= IS_MOVABLE;
+
+ if (inst)
+ PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ if (type <= SLJIT_JUMP) {
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ } else {
+ SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+ /* Cannot be optimized out if type is >= CALL0. */
+ jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
+ PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ /* A NOP if type < CALL1. */
+ PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS));
+ }
+ return jump;
+}
+
+#define RESOLVE_IMM1() \
+ if (src1 & SLJIT_IMM) { \
+ if (src1w) { \
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
+ src1 = TMP_REG1; \
+ } \
+ else \
+ src1 = 0; \
+ }
+
+#define RESOLVE_IMM2() \
+ if (src2 & SLJIT_IMM) { \
+ if (src2w) { \
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
+ src2 = TMP_REG2; \
+ } \
+ else \
+ src2 = 0; \
+ }
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ struct sljit_jump *jump;
+ int flags;
+ sljit_ins inst;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA;
+ if (src1 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, DR(TMP_REG1), src1, src1w))
+ PTR_FAIL_IF(compiler->error);
+ else
+ PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
+ src1 = TMP_REG1;
+ }
+ if (src2 & SLJIT_MEM) {
+ if (getput_arg_fast(compiler, flags, DR(TMP_REG2), src2, src2w))
+ PTR_FAIL_IF(compiler->error);
+ else
+ PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
+ src2 = TMP_REG2;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type <= SLJIT_C_NOT_EQUAL) {
+ RESOLVE_IMM1();
+ RESOLVE_IMM2();
+ jump->flags |= IS_BIT26_COND;
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
+ jump->flags |= IS_MOVABLE;
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+ else if (type >= SLJIT_C_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) {
+ inst = NOP;
+ if ((src1 & SLJIT_IMM) && (src1w == 0)) {
+ RESOLVE_IMM2();
+ switch (type) {
+ case SLJIT_C_SIG_LESS:
+ inst = BLEZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ inst = BGTZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ inst = BGEZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ inst = BLTZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ }
+ src1 = src2;
+ }
+ else {
+ RESOLVE_IMM1();
+ switch (type) {
+ case SLJIT_C_SIG_LESS:
+ inst = BGEZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ inst = BLTZ;
+ jump->flags |= IS_BIT16_COND;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ inst = BLEZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ case SLJIT_C_SIG_LESS_EQUAL:
+ inst = BGTZ;
+ jump->flags |= IS_BIT26_COND;
+ break;
+ }
+ }
+ PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+ else {
+ if (type == SLJIT_C_LESS || type == SLJIT_C_GREATER_EQUAL || type == SLJIT_C_SIG_LESS || type == SLJIT_C_SIG_GREATER_EQUAL) {
+ RESOLVE_IMM1();
+ if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
+ else {
+ RESOLVE_IMM2();
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
+ }
+ type = (type == SLJIT_C_LESS || type == SLJIT_C_SIG_LESS) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL;
+ }
+ else {
+ RESOLVE_IMM2();
+ if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
+ else {
+ RESOLVE_IMM1();
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_C_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
+ }
+ type = (type == SLJIT_C_GREATER || type == SLJIT_C_SIG_GREATER) ? SLJIT_C_NOT_EQUAL : SLJIT_C_EQUAL;
+ }
+
+ jump->flags |= IS_BIT26_COND;
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_C_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | JUMP_LENGTH, UNMOVABLE_INS));
+ }
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return jump;
+}
+
+#undef RESOLVE_IMM1
+#undef RESOLVE_IMM2
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ struct sljit_jump *jump;
+ sljit_ins inst;
+ int if_true;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+ if (src2 > SLJIT_FLOAT_REG4) {
+ PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ jump->flags |= IS_BIT16_COND;
+ type &= 0xff;
+
+ switch (type) {
+ case SLJIT_C_FLOAT_EQUAL:
+ inst = C_UEQ_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ inst = C_UEQ_D;
+ if_true = 0;
+ break;
+ case SLJIT_C_FLOAT_LESS:
+ inst = C_ULT_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ inst = C_ULT_D;
+ if_true = 0;
+ break;
+ case SLJIT_C_FLOAT_GREATER:
+ inst = C_ULE_D;
+ if_true = 0;
+ break;
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ inst = C_ULE_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_NAN:
+ inst = C_UN_D;
+ if_true = 1;
+ break;
+ case SLJIT_C_FLOAT_NOT_NAN:
+ default: /* Make compilers happy. */
+ inst = C_UN_D;
+ if_true = 0;
+ break;
+ }
+
+ PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS));
+ /* Intentionally the other opcode. */
+ PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS));
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return jump;
+}
+
+#undef JUMP_LENGTH
+#undef BR_Z
+#undef BR_NZ
+#undef BR_T
+#undef BR_F
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ int src_r = TMP_REG2;
+ struct sljit_jump *jump = NULL;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
+ if (DR(src) != 4)
+ src_r = src;
+ else
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ }
+
+ if (type >= SLJIT_CALL0) {
+ SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+ if (src & (SLJIT_IMM | SLJIT_MEM)) {
+ if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
+ else {
+ SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ }
+ FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ /* We need an extra instruction in any case. */
+ return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS);
+ }
+
+ /* Register input. */
+ if (type >= SLJIT_CALL1)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4));
+ FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+ return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS);
+ }
+
+ if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
+ jump->u.target = srcw;
+
+ if (compiler->delay_slot != UNMOVABLE_INS)
+ jump->flags |= IS_MOVABLE;
+
+ FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ }
+ else if (src & SLJIT_MEM)
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+
+ FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS));
+ if (jump)
+ jump->addr = compiler->size;
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int sugg_dst_ar, dst_ar;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ sugg_dst_ar = DR((op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2);
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_NOT_EQUAL:
+ FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ break;
+ case SLJIT_C_LESS:
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_LESS:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ dst_ar = ULESS_FLAG;
+ break;
+ case SLJIT_C_GREATER:
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_GREATER:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ dst_ar = UGREATER_FLAG;
+ break;
+ case SLJIT_C_SIG_LESS:
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ dst_ar = LESS_FLAG;
+ break;
+ case SLJIT_C_SIG_GREATER:
+ case SLJIT_C_SIG_LESS_EQUAL:
+ dst_ar = GREATER_FLAG;
+ break;
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_NOT_OVERFLOW:
+ dst_ar = OVERFLOW_FLAG;
+ break;
+ case SLJIT_C_MUL_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ FAIL_IF(push_inst(compiler, SLTIU | SA(OVERFLOW_FLAG) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ type ^= 0x1; /* Flip type bit for the XORI below. */
+ break;
+ case SLJIT_C_FLOAT_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ dst_ar = EQUAL_FLAG;
+ break;
+
+ case SLJIT_C_FLOAT_NAN:
+ case SLJIT_C_FLOAT_NOT_NAN:
+ FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar));
+ FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar));
+ FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ dst_ar = sugg_dst_ar;
+ break;
+ }
+
+ if (type & 0x1) {
+ FAIL_IF(push_inst(compiler, XORI | SA(dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar));
+ dst_ar = sugg_dst_ar;
+ }
+
+ if (GET_OPCODE(op) == SLJIT_OR) {
+ if (DR(TMP_REG2) != dst_ar)
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+ return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0);
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw);
+
+ if (sugg_dst_ar != dst_ar)
+ return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int reg;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_32.c b/src/3rdparty/pcre/sljit/sljitNativePPC_32.c
new file mode 100644
index 00000000000..82d0508ac17
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_32.c
@@ -0,0 +1,262 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ppc 32-bit arch dependent functions. */
+
+static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm));
+
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
+}
+
+#define INS_CLEAR_LEFT(dst, src, from) \
+ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, int src2)
+{
+ switch (op) {
+ case SLJIT_ADD:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM4) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+ return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
+ return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_ADDC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_SUB:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & (ALT_FORM2 | ALT_FORM3)) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2)
+ FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
+ if (flags & ALT_FORM3)
+ return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm);
+ return SLJIT_SUCCESS;
+ }
+ if (flags & (ALT_FORM4 | ALT_FORM5)) {
+ if (flags & ALT_FORM4)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+ if (flags & ALT_FORM5)
+ FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
+ return SLJIT_SUCCESS;
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+ if (flags & ALT_FORM6)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+ return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_SUBC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_MUL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
+ }
+ return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_AND:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
+ }
+ return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_OR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_XOR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_SHL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
+ }
+ return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_LSHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
+ }
+ return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_ASHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
+ }
+ return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_MOV:
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
+ }
+ else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SH)
+ return push_inst(compiler, EXTSH | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
+
+ case SLJIT_NEG:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
+{
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_64.c b/src/3rdparty/pcre/sljit/sljitNativePPC_64.c
new file mode 100644
index 00000000000..cc2ae37eb9b
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_64.c
@@ -0,0 +1,428 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ppc 64-bit arch dependent functions. */
+
+#ifdef __GNUC__
+#define ASM_SLJIT_CLZ(src, dst) \
+ asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
+#else
+#error "Must implement count leading zeroes"
+#endif
+
+#define RLDI(dst, src, sh, mb, type) \
+ (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
+
+#define PUSH_RLDICR(reg, shift) \
+ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
+
+static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ sljit_uw tmp;
+ sljit_uw shift;
+ sljit_uw tmp2;
+ sljit_uw shift2;
+
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
+
+ if (!(imm & ~0xffff))
+ return push_inst(compiler, ORI | S(ZERO_REG) | A(reg) | IMM(imm));
+
+ if (imm <= SLJIT_W(0x7fffffff) && imm >= SLJIT_W(-0x80000000)) {
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
+ }
+
+ /* Count leading zeroes. */
+ tmp = (imm >= 0) ? imm : ~imm;
+ ASM_SLJIT_CLZ(tmp, shift);
+ SLJIT_ASSERT(shift > 0);
+ shift--;
+ tmp = (imm << shift);
+
+ if ((tmp & ~0xffff000000000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ shift += 15;
+ return PUSH_RLDICR(reg, shift);
+ }
+
+ if ((tmp & ~0xffffffff00000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp >> 32)));
+ shift += 31;
+ return PUSH_RLDICR(reg, shift);
+ }
+
+ /* Cut out the 16 bit from immediate. */
+ shift += 15;
+ tmp2 = imm & ((1ul << (63 - shift)) - 1);
+
+ if (tmp2 <= 0xffff) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | tmp2);
+ }
+
+ if (tmp2 <= 0xffffffff) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | (tmp2 >> 16)));
+ return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(tmp2)) : SLJIT_SUCCESS;
+ }
+
+ ASM_SLJIT_CLZ(tmp2, shift2);
+ tmp2 <<= shift2;
+
+ if ((tmp2 & ~0xffff000000000000ul) == 0) {
+ FAIL_IF(push_inst(compiler, ADDI | D(reg) | A(0) | IMM(tmp >> 48)));
+ shift2 += 15;
+ shift += (63 - shift2);
+ FAIL_IF(PUSH_RLDICR(reg, shift));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | (tmp2 >> 48)));
+ return PUSH_RLDICR(reg, shift2);
+ }
+
+ /* The general version. */
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(imm >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm >> 32)));
+ FAIL_IF(PUSH_RLDICR(reg, 31));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(imm >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm));
+}
+
+/* Simplified mnemonics: clrldi. */
+#define INS_CLEAR_LEFT(dst, src, from) \
+ (RLDICL | S(src) | A(dst) | ((from) << 6) | (1 << 5))
+
+/* Sign extension for integer operations. */
+#define UN_EXTS() \
+ if ((flags & (ALT_SIGN_EXT | REG2_SOURCE)) == (ALT_SIGN_EXT | REG2_SOURCE)) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
+ src2 = TMP_REG2; \
+ }
+
+#define BIN_EXTS() \
+ if (flags & ALT_SIGN_EXT) { \
+ if (flags & REG1_SOURCE) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
+ src1 = TMP_REG1; \
+ } \
+ if (flags & REG2_SOURCE) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src2) | A(TMP_REG2))); \
+ src2 = TMP_REG2; \
+ } \
+ }
+
+#define BIN_IMM_EXTS() \
+ if ((flags & (ALT_SIGN_EXT | REG1_SOURCE)) == (ALT_SIGN_EXT | REG1_SOURCE)) { \
+ FAIL_IF(push_inst(compiler, EXTSW | S(src1) | A(TMP_REG1))); \
+ src1 = TMP_REG1; \
+ }
+
+static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
+ int dst, int src1, int src2)
+{
+ switch (op) {
+ case SLJIT_ADD:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ BIN_IMM_EXTS();
+ return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & ALT_FORM4) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+ return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
+ BIN_EXTS();
+ return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_ADDC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ BIN_EXTS();
+ return push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2));
+
+ case SLJIT_SUB:
+ if (flags & ALT_FORM1) {
+ /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
+ }
+ if (flags & (ALT_FORM2 | ALT_FORM3)) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2)
+ FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
+ if (flags & ALT_FORM3)
+ return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+ return SLJIT_SUCCESS;
+ }
+ if (flags & (ALT_FORM4 | ALT_FORM5)) {
+ if (flags & ALT_FORM4)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+ if (flags & ALT_FORM5)
+ return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
+ return SLJIT_SUCCESS;
+ }
+ if (!(flags & ALT_SET_FLAGS))
+ return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
+ BIN_EXTS();
+ if (flags & ALT_FORM6)
+ FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+ return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_SUBC:
+ if (flags & ALT_FORM1) {
+ FAIL_IF(push_inst(compiler, MFXER | S(0)));
+ FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
+ return push_inst(compiler, MTXER | S(0));
+ }
+ BIN_EXTS();
+ return push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_MUL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, MULLI | D(dst) | A(src1) | compiler->imm);
+ }
+ BIN_EXTS();
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, MULLW | OERC(flags) | D(dst) | A(src2) | B(src1));
+ return push_inst(compiler, MULLD | OERC(flags) | D(dst) | A(src2) | B(src1));
+
+ case SLJIT_AND:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ANDIS | S(src1) | A(dst) | compiler->imm);
+ }
+ return push_inst(compiler, AND | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_OR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, ORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, ORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, ORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, OR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_XOR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORI | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM2) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ return push_inst(compiler, XORIS | S(src1) | A(dst) | compiler->imm);
+ }
+ if (flags & ALT_FORM3) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(compiler->imm)));
+ return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(compiler->imm >> 16));
+ }
+ return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_SHL:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11) | ((31 - compiler->imm) << 1));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
+ }
+ }
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
+ return push_inst(compiler, SLD | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_LSHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, RLWINM | RC(flags) | S(src1) | A(dst) | (((32 - compiler->imm) & 0x1f) << 11) | (compiler->imm << 6) | (31 << 1));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
+ }
+ }
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
+ return push_inst(compiler, SRD | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_ASHR:
+ if (flags & ALT_FORM1) {
+ SLJIT_ASSERT(src2 == TMP_REG2);
+ if (flags & ALT_FORM2) {
+ compiler->imm &= 0x1f;
+ return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
+ }
+ else {
+ compiler->imm &= 0x3f;
+ return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
+ }
+ }
+ if (flags & ALT_FORM2)
+ return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
+ return push_inst(compiler, SRAD | RC(flags) | S(src1) | A(dst) | B(src2));
+
+ case SLJIT_MOV:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (dst != src2)
+ return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SI)
+ return push_inst(compiler, EXTSW | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UB:
+ case SLJIT_MOV_SB:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
+ }
+ else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
+ return push_inst(compiler, EXTSB | S(src2) | A(dst));
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_MOV_UH:
+ case SLJIT_MOV_SH:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (op == SLJIT_MOV_SH)
+ return push_inst(compiler, EXTSH | S(src2) | A(dst));
+ return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
+ }
+ else if (dst != src2)
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+
+ case SLJIT_NOT:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ UN_EXTS();
+ return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
+
+ case SLJIT_NEG:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ UN_EXTS();
+ return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
+
+ case SLJIT_CLZ:
+ SLJIT_ASSERT(src1 == TMP_REG1);
+ if (flags & ALT_FORM1)
+ return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
+ return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst));
+ }
+
+ SLJIT_ASSERT_STOP();
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
+{
+ FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
+ FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
+ FAIL_IF(PUSH_RLDICR(reg, 31));
+ FAIL_IF(push_inst(compiler, ORIS | S(reg) | A(reg) | IMM(init_value >> 16)));
+ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+ inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 5);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ sljit_ins *inst = (sljit_ins*)addr;
+
+ inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
+ inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
+ inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+ inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
+ SLJIT_CACHE_FLUSH(inst, inst + 5);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func)
+{
+ sljit_w* ptrs;
+ if (func_ptr)
+ *func_ptr = (void*)context;
+ ptrs = (sljit_w*)func;
+ context->addr = addr ? addr : ptrs[0];
+ context->r2 = ptrs[1];
+ context->r11 = ptrs[2];
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_common.c b/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
new file mode 100644
index 00000000000..f0f191de1f0
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
@@ -0,0 +1,1872 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "PowerPC" SLJIT_CPUINFO;
+}
+
+/* Length of an instruction word.
+ Both for ppc-32 and ppc-64. */
+typedef sljit_ui sljit_ins;
+
+static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
+{
+ while (from < to) {
+#ifdef __GNUC__
+ asm volatile ( "icbi 0, %0" : : "r"(from) );
+#else
+#error "Must implement icbi"
+#endif
+ from++;
+ }
+}
+
+#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+#define ZERO_REG (SLJIT_NO_REGISTERS + 4)
+#define REAL_STACK_PTR (SLJIT_NO_REGISTERS + 5)
+
+#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1)
+#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2)
+
+/* --------------------------------------------------------------------- */
+/* Instrucion forms */
+/* --------------------------------------------------------------------- */
+#define D(d) (reg_map[d] << 21)
+#define S(s) (reg_map[s] << 21)
+#define A(a) (reg_map[a] << 16)
+#define B(b) (reg_map[b] << 11)
+#define C(c) (reg_map[c] << 6)
+#define FD(fd) ((fd) << 21)
+#define FA(fa) ((fa) << 16)
+#define FB(fb) ((fb) << 11)
+#define FC(fc) ((fc) << 6)
+#define IMM(imm) ((imm) & 0xffff)
+#define CRD(d) ((d) << 21)
+
+/* Instruction bit sections.
+ OE and Rc flag (see ALT_SET_FLAGS). */
+#define OERC(flags) (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
+/* Rc flag (see ALT_SET_FLAGS). */
+#define RC(flags) ((flags & ALT_SET_FLAGS) >> 10)
+#define HI(opcode) ((opcode) << 26)
+#define LO(opcode) ((opcode) << 1)
+
+#define ADD (HI(31) | LO(266))
+#define ADDC (HI(31) | LO(10))
+#define ADDE (HI(31) | LO(138))
+#define ADDI (HI(14))
+#define ADDIC (HI(13))
+#define ADDIS (HI(15))
+#define ADDME (HI(31) | LO(234))
+#define AND (HI(31) | LO(28))
+#define ANDI (HI(28))
+#define ANDIS (HI(29))
+#define Bx (HI(18))
+#define BCx (HI(16))
+#define BCCTR (HI(19) | LO(528) | (3 << 11))
+#define BLR (HI(19) | LO(16) | (0x14 << 21))
+#define CNTLZD (HI(31) | LO(58))
+#define CNTLZW (HI(31) | LO(26))
+#define CMP (HI(31) | LO(0))
+#define CMPI (HI(11))
+#define CMPL (HI(31) | LO(32))
+#define CMPLI (HI(10))
+#define CROR (HI(19) | LO(449))
+#define DIVD (HI(31) | LO(489))
+#define DIVDU (HI(31) | LO(457))
+#define DIVW (HI(31) | LO(491))
+#define DIVWU (HI(31) | LO(459))
+#define EXTSB (HI(31) | LO(954))
+#define EXTSH (HI(31) | LO(922))
+#define EXTSW (HI(31) | LO(986))
+#define FABS (HI(63) | LO(264))
+#define FADD (HI(63) | LO(21))
+#define FCMPU (HI(63) | LO(0))
+#define FDIV (HI(63) | LO(18))
+#define FMR (HI(63) | LO(72))
+#define FMUL (HI(63) | LO(25))
+#define FNEG (HI(63) | LO(40))
+#define FSUB (HI(63) | LO(20))
+#define LD (HI(58) | 0)
+#define LFD (HI(50))
+#define LFDUX (HI(31) | LO(631))
+#define LFDX (HI(31) | LO(599))
+#define LWZ (HI(32))
+#define MFCR (HI(31) | LO(19))
+#define MFLR (HI(31) | LO(339) | 0x80000)
+#define MFXER (HI(31) | LO(339) | 0x10000)
+#define MTCTR (HI(31) | LO(467) | 0x90000)
+#define MTLR (HI(31) | LO(467) | 0x80000)
+#define MTXER (HI(31) | LO(467) | 0x10000)
+#define MULHD (HI(31) | LO(73))
+#define MULHDU (HI(31) | LO(9))
+#define MULHW (HI(31) | LO(75))
+#define MULHWU (HI(31) | LO(11))
+#define MULLD (HI(31) | LO(233))
+#define MULLI (HI(7))
+#define MULLW (HI(31) | LO(235))
+#define NEG (HI(31) | LO(104))
+#define NOP (HI(24))
+#define NOR (HI(31) | LO(124))
+#define OR (HI(31) | LO(444))
+#define ORI (HI(24))
+#define ORIS (HI(25))
+#define RLDICL (HI(30))
+#define RLWINM (HI(21))
+#define SLD (HI(31) | LO(27))
+#define SLW (HI(31) | LO(24))
+#define SRAD (HI(31) | LO(794))
+#define SRADI (HI(31) | LO(413 << 1))
+#define SRAW (HI(31) | LO(792))
+#define SRAWI (HI(31) | LO(824))
+#define SRD (HI(31) | LO(539))
+#define SRW (HI(31) | LO(536))
+#define STD (HI(62) | 0)
+#define STDU (HI(62) | 1)
+#define STDUX (HI(31) | LO(181))
+#define STFD (HI(54))
+#define STFDUX (HI(31) | LO(759))
+#define STFDX (HI(31) | LO(727))
+#define STW (HI(36))
+#define STWU (HI(37))
+#define STWUX (HI(31) | LO(183))
+#define SUBF (HI(31) | LO(40))
+#define SUBFC (HI(31) | LO(8))
+#define SUBFE (HI(31) | LO(136))
+#define SUBFIC (HI(8))
+#define XOR (HI(31) | LO(316))
+#define XORI (HI(26))
+#define XORIS (HI(27))
+
+#define SIMM_MAX (0x7fff)
+#define SIMM_MIN (-0x8000)
+#define UIMM_MAX (0xffff)
+
+/* SLJIT_LOCALS_REG is not the real stack register, since it must
+ point to the head of the stack chain. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = {
+ 0, 3, 4, 5, 6, 7, 29, 28, 27, 26, 25, 31, 8, 9, 10, 30, 1
+};
+
+static int push_inst(struct sljit_compiler *compiler, sljit_ins ins)
+{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ *ptr = ins;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
+{
+ sljit_w diff;
+ sljit_uw target_addr;
+
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
+ return 0;
+
+ if (jump->flags & JUMP_ADDR)
+ target_addr = jump->u.target;
+ else {
+ SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+ target_addr = (sljit_uw)(code + jump->u.label->size);
+ }
+ diff = ((sljit_w)target_addr - (sljit_w)(code_ptr)) & ~0x3l;
+
+ if (jump->flags & UNCOND_B) {
+ if (diff <= 0x01ffffff && diff >= -0x02000000) {
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ if (target_addr <= 0x03ffffff) {
+ jump->flags |= PATCH_B | ABSOLUTE_B;
+ return 1;
+ }
+ }
+ else {
+ if (diff <= 0x7fff && diff >= -0x8000) {
+ jump->flags |= PATCH_B;
+ return 1;
+ }
+ if (target_addr <= 0xffff) {
+ jump->flags |= PATCH_B | ABSOLUTE_B;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ins *code;
+ sljit_ins *code_ptr;
+ sljit_ins *buf_ptr;
+ sljit_ins *buf_end;
+ sljit_uw word_count;
+ sljit_uw addr;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
+#endif
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ word_count = 0;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = (sljit_ins*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 2);
+ do {
+ *code_ptr = *buf_ptr++;
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ jump->addr = (sljit_uw)(code_ptr - 3);
+#else
+ jump->addr = (sljit_uw)(code_ptr - 6);
+#endif
+ if (optimize_jump(jump, code_ptr, code)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ code_ptr[-3] = code_ptr[0];
+ code_ptr -= 3;
+#else
+ code_ptr[-6] = code_ptr[0];
+ code_ptr -= 6;
+#endif
+ }
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ code_ptr ++;
+ word_count ++;
+ } while (buf_ptr < buf_end);
+
+ buf = buf->next;
+ } while (buf);
+
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size - ((compiler->size & 0x1) ? 3 : 2));
+#else
+ SLJIT_ASSERT(code_ptr - code <= (int)compiler->size);
+#endif
+
+ jump = compiler->jumps;
+ while (jump) {
+ do {
+ addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ buf_ptr = (sljit_ins*)jump->addr;
+ if (jump->flags & PATCH_B) {
+ if (jump->flags & UNCOND_B) {
+ if (!(jump->flags & ABSOLUTE_B)) {
+ addr = addr - jump->addr;
+ SLJIT_ASSERT((sljit_w)addr <= 0x01ffffff && (sljit_w)addr >= -0x02000000);
+ *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
+ }
+ else {
+ SLJIT_ASSERT(addr <= 0x03ffffff);
+ *buf_ptr = Bx | (addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
+ }
+ }
+ else {
+ if (!(jump->flags & ABSOLUTE_B)) {
+ addr = addr - jump->addr;
+ SLJIT_ASSERT((sljit_w)addr <= 0x7fff && (sljit_w)addr >= -0x8000);
+ *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
+ }
+ else {
+ addr = addr & ~0x3l;
+ SLJIT_ASSERT(addr <= 0xffff);
+ *buf_ptr = BCx | (addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
+ }
+
+ }
+ break;
+ }
+ /* Set the fields of immediate loads. */
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+#else
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff);
+ buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff);
+ buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff);
+ buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff);
+#endif
+ } while (0);
+ jump = jump->next;
+ }
+
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size * sizeof(sljit_ins);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (((sljit_w)code_ptr) & 0x4)
+ code_ptr++;
+ sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_w)code, sljit_generate_code);
+ return code_ptr;
+#else
+ return code;
+#endif
+}
+
+/* inp_flags: */
+
+/* Creates an index in data_transfer_insts array. */
+#define WORD_DATA 0x00
+#define BYTE_DATA 0x01
+#define HALF_DATA 0x02
+#define INT_DATA 0x03
+#define SIGNED_DATA 0x04
+#define LOAD_DATA 0x08
+#define WRITE_BACK 0x10
+#define INDEXED 0x20
+
+#define MEM_MASK 0x3f
+
+/* Other inp_flags. */
+
+#define ARG_TEST 0x000100
+/* Integer opertion and set flags -> requires exts on 64 bit systems. */
+#define ALT_SIGN_EXT 0x000200
+/* This flag affects the RC() and OERC() macros. */
+#define ALT_SET_FLAGS 0x000400
+#define ALT_FORM1 0x010000
+#define ALT_FORM2 0x020000
+#define ALT_FORM3 0x040000
+#define ALT_FORM4 0x080000
+#define ALT_FORM5 0x100000
+#define ALT_FORM6 0x200000
+
+/* Source and destination is register. */
+#define REG_DEST 0x000001
+#define REG1_SOURCE 0x000002
+#define REG2_SOURCE 0x000004
+/* getput_arg_fast returned true. */
+#define FAST_DEST 0x000008
+/* Multiple instructions are required. */
+#define SLOW_DEST 0x000010
+/*
+ALT_SIGN_EXT 0x000200
+ALT_SET_FLAGS 0x000400
+ALT_FORM1 0x010000
+...
+ALT_FORM6 0x200000 */
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#include "sljitNativePPC_32.c"
+#else
+#include "sljitNativePPC_64.c"
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#define STACK_STORE STW
+#define STACK_LOAD LWZ
+#else
+#define STACK_STORE STD
+#define STACK_LOAD LD
+#endif
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->has_locals = local_size > 0;
+
+ FAIL_IF(push_inst(compiler, MFLR | D(0)));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM(-(int)(sizeof(sljit_w))) ));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(REAL_STACK_PTR) | IMM(-2 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(REAL_STACK_PTR) | IMM(-3 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(REAL_STACK_PTR) | IMM(-4 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(REAL_STACK_PTR) | IMM(-5 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(REAL_STACK_PTR) | IMM(-6 * (int)(sizeof(sljit_w))) ));
+ if (saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(REAL_STACK_PTR) | IMM(-7 * (int)(sizeof(sljit_w))) ));
+ FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(REAL_STACK_PTR) | IMM(sizeof(sljit_w)) ));
+
+ FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0));
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_TEMPORARY_REG1)));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_TEMPORARY_REG2)));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_TEMPORARY_REG3)));
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ compiler->local_size = (2 + saveds + 2) * sizeof(sljit_w) + local_size;
+#else
+ compiler->local_size = (2 + saveds + 7 + 8) * sizeof(sljit_w) + local_size;
+#endif
+ compiler->local_size = (compiler->local_size + 15) & ~0xf;
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, STWU | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | IMM(-compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
+ FAIL_IF(push_inst(compiler, STWUX | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | B(0)));
+ }
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM(2 * sizeof(sljit_w))));
+#else
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, STDU | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | IMM(-compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, -compiler->local_size));
+ FAIL_IF(push_inst(compiler, STDUX | S(REAL_STACK_PTR) | A(REAL_STACK_PTR) | B(0)));
+ }
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, ADDI | D(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM((7 + 8) * sizeof(sljit_w))));
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ compiler->local_size = (2 + saveds + 2) * sizeof(sljit_w) + local_size;
+#else
+ compiler->local_size = (2 + saveds + 7 + 8) * sizeof(sljit_w) + local_size;
+#endif
+ compiler->local_size = (compiler->local_size + 15) & ~0xf;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size <= SIMM_MAX)
+ FAIL_IF(push_inst(compiler, ADDI | D(REAL_STACK_PTR) | A(REAL_STACK_PTR) | IMM(compiler->local_size)));
+ else {
+ FAIL_IF(load_immediate(compiler, 0, compiler->local_size));
+ FAIL_IF(push_inst(compiler, ADD | D(REAL_STACK_PTR) | A(REAL_STACK_PTR) | B(0)));
+ }
+
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(REAL_STACK_PTR) | IMM(sizeof(sljit_w))));
+ if (compiler->saveds >= 5)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(REAL_STACK_PTR) | IMM(-7 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 4)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(REAL_STACK_PTR) | IMM(-6 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 3)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(REAL_STACK_PTR) | IMM(-5 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 2)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(REAL_STACK_PTR) | IMM(-4 * (int)(sizeof(sljit_w))) ));
+ if (compiler->saveds >= 1)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(REAL_STACK_PTR) | IMM(-3 * (int)(sizeof(sljit_w))) ));
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(REAL_STACK_PTR) | IMM(-2 * (int)(sizeof(sljit_w))) ));
+ if (compiler->has_locals)
+ FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_LOCALS_REG) | A(REAL_STACK_PTR) | IMM(-(int)(sizeof(sljit_w))) ));
+
+ FAIL_IF(push_inst(compiler, MTLR | S(0)));
+ FAIL_IF(push_inst(compiler, BLR));
+
+ return SLJIT_SUCCESS;
+}
+
+#undef STACK_STORE
+#undef STACK_LOAD
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* i/x - immediate/indexed form
+ n/w - no write-back / write-back (1 bit)
+ s/l - store/load (1 bit)
+ u/s - signed/unsigned (1 bit)
+ w/b/h/i - word/byte/half/int allowed (2 bit)
+ It contans 32 items, but not all are different. */
+
+/* 64 bit only: [reg+imm] must be aligned to 4 bytes. */
+#define ADDR_MODE2 0x10000
+/* 64-bit only: there is no lwau instruction. */
+#define UPDATE_REQ 0x20000
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+#define ARCH_DEPEND(a, b) a
+#define GET_INST_CODE(inst) (inst)
+#else
+#define ARCH_DEPEND(a, b) b
+#define GET_INST_CODE(index) ((inst) & ~(ADDR_MODE2 | UPDATE_REQ))
+#endif
+
+static SLJIT_CONST sljit_ins data_transfer_insts[64] = {
+
+/* No write-back. */
+
+/* i n s u w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */),
+/* i n s u b */ HI(38) /* stb */,
+/* i n s u h */ HI(44) /* sth*/,
+/* i n s u i */ HI(36) /* stw */,
+
+/* i n s s w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */),
+/* i n s s b */ HI(38) /* stb */,
+/* i n s s h */ HI(44) /* sth*/,
+/* i n s s i */ HI(36) /* stw */,
+
+/* i n l u w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */),
+/* i n l u b */ HI(34) /* lbz */,
+/* i n l u h */ HI(40) /* lhz */,
+/* i n l u i */ HI(32) /* lwz */,
+
+/* i n l s w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */),
+/* i n l s b */ HI(34) /* lbz */ /* EXTS_REQ */,
+/* i n l s h */ HI(42) /* lha */,
+/* i n l s i */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */),
+
+/* Write-back. */
+
+/* i w s u w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */),
+/* i w s u b */ HI(39) /* stbu */,
+/* i w s u h */ HI(45) /* sthu */,
+/* i w s u i */ HI(37) /* stwu */,
+
+/* i w s s w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */),
+/* i w s s b */ HI(39) /* stbu */,
+/* i w s s h */ HI(45) /* sthu */,
+/* i w s s i */ HI(37) /* stwu */,
+
+/* i w l u w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */),
+/* i w l u b */ HI(35) /* lbzu */,
+/* i w l u h */ HI(41) /* lhzu */,
+/* i w l u i */ HI(33) /* lwzu */,
+
+/* i w l s w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */),
+/* i w l s b */ HI(35) /* lbzu */ /* EXTS_REQ */,
+/* i w l s h */ HI(43) /* lhau */,
+/* i w l s i */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */),
+
+/* ---------- */
+/* Indexed */
+/* ---------- */
+
+/* No write-back. */
+
+/* x n s u w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* x n s u b */ HI(31) | LO(215) /* stbx */,
+/* x n s u h */ HI(31) | LO(407) /* sthx */,
+/* x n s u i */ HI(31) | LO(151) /* stwx */,
+
+/* x n s s w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */),
+/* x n s s b */ HI(31) | LO(215) /* stbx */,
+/* x n s s h */ HI(31) | LO(407) /* sthx */,
+/* x n s s i */ HI(31) | LO(151) /* stwx */,
+
+/* x n l u w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+/* x n l u b */ HI(31) | LO(87) /* lbzx */,
+/* x n l u h */ HI(31) | LO(279) /* lhzx */,
+/* x n l u i */ HI(31) | LO(23) /* lwzx */,
+
+/* x n l s w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */),
+/* x n l s b */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */,
+/* x n l s h */ HI(31) | LO(343) /* lhax */,
+/* x n l s i */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */),
+
+/* Write-back. */
+
+/* x w s u w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* x w s u b */ HI(31) | LO(247) /* stbux */,
+/* x w s u h */ HI(31) | LO(439) /* sthux */,
+/* x w s u i */ HI(31) | LO(183) /* stwux */,
+
+/* x w s s w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */),
+/* x w s s b */ HI(31) | LO(247) /* stbux */,
+/* x w s s h */ HI(31) | LO(439) /* sthux */,
+/* x w s s i */ HI(31) | LO(183) /* stwux */,
+
+/* x w l u w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+/* x w l u b */ HI(31) | LO(119) /* lbzux */,
+/* x w l u h */ HI(31) | LO(311) /* lhzux */,
+/* x w l u i */ HI(31) | LO(55) /* lwzux */,
+
+/* x w l s w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */),
+/* x w l s b */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */,
+/* x w l s h */ HI(31) | LO(375) /* lhaux */,
+/* x w l s i */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */)
+
+};
+
+#undef ARCH_DEPEND
+
+/* Simple cases, (no caching is required). */
+static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw)
+{
+ sljit_ins inst;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ int tmp_reg;
+#endif
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ if (!(arg & 0xf)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw));
+ return -1;
+ }
+#else
+ inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN &&
+ (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw));
+ return -1;
+ }
+#endif
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+ }
+
+ if (!(arg & 0xf0)) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw));
+ return -1;
+ }
+#else
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN && (!(inst & ADDR_MODE2) || (argw & 0x3) == 0)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+
+ if ((inp_flags & WRITE_BACK) && (inst & UPDATE_REQ)) {
+ tmp_reg = (inp_flags & LOAD_DATA) ? (arg & 0xf) : TMP_REG3;
+ if (push_inst(compiler, ADDI | D(tmp_reg) | A(arg & 0xf) | IMM(argw)))
+ return -1;
+ arg = tmp_reg | SLJIT_MEM;
+ argw = 0;
+ }
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw));
+ return -1;
+ }
+#endif
+ }
+ else if (!(argw & 0x3)) {
+ if (inp_flags & ARG_TEST)
+ return 1;
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B((arg >> 4) & 0xf));
+ return -1;
+ }
+ return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0;
+}
+
+/* See getput_arg below.
+ Note: can_cache is called only for binary operators. Those operator always
+ uses word arguments without write back. */
+static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+ SLJIT_ASSERT(next_arg & SLJIT_MEM);
+
+ if (!(arg & 0xf)) {
+ if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX))
+ return 1;
+ return 0;
+ }
+
+ if (arg & 0xf0)
+ return 0;
+
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
+ if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN))
+ return 1;
+ }
+
+ if (arg == next_arg && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX))
+ return 1;
+
+ return 0;
+}
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define ADJUST_CACHED_IMM(imm) \
+ if ((inst & ADDR_MODE2) && (imm & 0x3)) { \
+ /* Adjust cached value. Fortunately this is really a rare case */ \
+ compiler->cache_argw += imm & 0x3; \
+ FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG3) | A(TMP_REG3) | (imm & 0x3))); \
+ imm &= ~0x3; \
+ }
+#else
+#define ADJUST_CACHED_IMM(imm)
+#endif
+
+/* Emit the necessary instructions. See can_cache above. */
+static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw)
+{
+ int tmp_r;
+ sljit_ins inst;
+
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3;
+ if ((arg & 0xf) == tmp_r) {
+ /* Special case for "mov reg, [reg, ... ]".
+ Caching would not happen anyway. */
+ tmp_r = TMP_REG3;
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+ }
+
+ if (!(arg & 0xf)) {
+ inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK];
+ if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= SIMM_MAX || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= SIMM_MAX)) {
+ argw = argw - compiler->cache_argw;
+ ADJUST_CACHED_IMM(argw);
+ SLJIT_ASSERT(!(inst & UPDATE_REQ));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw));
+ }
+
+ if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+ tmp_r = TMP_REG3;
+ }
+
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(tmp_r));
+ }
+
+ if (SLJIT_UNLIKELY(arg & 0xf0)) {
+ argw &= 0x3;
+ /* Otherwise getput_arg_fast would capture it. */
+ SLJIT_ASSERT(argw);
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1)));
+#else
+ FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1)));
+#endif
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r));
+ }
+
+ inst = data_transfer_insts[inp_flags & MEM_MASK];
+
+ if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw <= SIMM_MAX || (sljit_uw)compiler->cache_argw - (sljit_uw)argw <= SIMM_MAX)) {
+ SLJIT_ASSERT(!(inp_flags & WRITE_BACK));
+ argw = argw - compiler->cache_argw;
+ ADJUST_CACHED_IMM(argw);
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw));
+ }
+
+ if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) {
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3));
+ }
+
+ if (argw == next_argw && (next_arg & SLJIT_MEM)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+
+ compiler->cache_arg = SLJIT_IMM;
+ compiler->cache_argw = argw;
+
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3));
+ }
+
+ if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) {
+ SLJIT_ASSERT(inp_flags & LOAD_DATA);
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ FAIL_IF(push_inst(compiler, ADD | D(TMP_REG3) | A(TMP_REG3) | B(arg & 0xf)));
+
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3));
+ }
+
+ /* Get the indexed version instead of the normal one. */
+ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK];
+ SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ)));
+ FAIL_IF(load_immediate(compiler, tmp_r, argw));
+ return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r));
+}
+
+static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* arg1 goes to TMP_REG1 or src reg
+ arg2 goes to TMP_REG2, imm or src reg
+ TMP_REG3 can be used for caching
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
+ int dst_r;
+ int src1_r;
+ int src2_r;
+ int sugg_src2_r = TMP_REG2;
+ int flags = inp_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ /* Destination check. */
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= ZERO_REG) {
+ dst_r = dst;
+ flags |= REG_DEST;
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ sugg_src2_r = dst_r;
+ }
+ else if (dst == SLJIT_UNUSED) {
+ if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
+ return SLJIT_SUCCESS;
+ dst_r = TMP_REG2;
+ }
+ else {
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) {
+ flags |= FAST_DEST;
+ dst_r = TMP_REG2;
+ }
+ else {
+ flags |= SLOW_DEST;
+ dst_r = 0;
+ }
+ }
+
+ /* Source 1. */
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= ZERO_REG) {
+ src1_r = src1;
+ flags |= REG1_SOURCE;
+ }
+ else if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if ((inp_flags & 0x3) == INT_DATA) {
+ if (inp_flags & SIGNED_DATA)
+ src1w = (signed int)src1w;
+ else
+ src1w = (unsigned int)src1w;
+ }
+#endif
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1_r = TMP_REG1;
+ }
+ else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) {
+ FAIL_IF(compiler->error);
+ src1_r = TMP_REG1;
+ }
+ else
+ src1_r = 0;
+
+ /* Source 2. */
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= ZERO_REG) {
+ src2_r = src2;
+ flags |= REG2_SOURCE;
+ if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
+ dst_r = src2_r;
+ }
+ else if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if ((inp_flags & 0x3) == INT_DATA) {
+ if (inp_flags & SIGNED_DATA)
+ src2w = (signed int)src2w;
+ else
+ src2w = (unsigned int)src2w;
+ }
+#endif
+ FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w));
+ src2_r = sugg_src2_r;
+ }
+ else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) {
+ FAIL_IF(compiler->error);
+ src2_r = sugg_src2_r;
+ }
+ else
+ src2_r = 0;
+
+ /* src1_r, src2_r and dst_r can be zero (=unprocessed).
+ All arguments are complex addressing modes, and it is a binary operator. */
+ if (src1_r == 0 && src2_r == 0 && dst_r == 0) {
+ if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ }
+ else {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
+ }
+ src1_r = TMP_REG1;
+ src2_r = TMP_REG2;
+ }
+ else if (src1_r == 0 && src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+ src1_r = TMP_REG1;
+ }
+ else if (src1_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1_r = TMP_REG1;
+ }
+ else if (src2_r == 0 && dst_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+ src2_r = sugg_src2_r;
+ }
+
+ if (dst_r == 0)
+ dst_r = TMP_REG2;
+
+ if (src1_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0));
+ src1_r = TMP_REG1;
+ }
+
+ if (src2_r == 0) {
+ FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0));
+ src2_r = sugg_src2_r;
+ }
+
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
+
+ if (flags & (FAST_DEST | SLOW_DEST)) {
+ if (flags & FAST_DEST)
+ FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw));
+ else
+ FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_BREAKPOINT:
+ case SLJIT_NOP:
+ return push_inst(compiler, NOP);
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1)));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2));
+#else
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2));
+#endif
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1)));
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP) {
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1));
+ }
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1));
+#else
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2)));
+ return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1));
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+ if ((src & SLJIT_IMM) && srcw == 0)
+ src = ZERO_REG;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP) {
+ inp_flags |= INT_DATA | SIGNED_DATA;
+ if (src & SLJIT_IMM)
+ srcw = (int)srcw;
+ }
+#endif
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG)));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOV_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOV_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOV_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOV_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_MOVU:
+ return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UI:
+ return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_SI:
+ return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_MOVU_UB:
+ return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw);
+
+ case SLJIT_MOVU_SB:
+ return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw);
+
+ case SLJIT_MOVU_UH:
+ return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw);
+
+ case SLJIT_MOVU_SH:
+ return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw);
+
+ case SLJIT_NOT:
+ return emit_op(compiler, SLJIT_NOT, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_NEG:
+ return emit_op(compiler, SLJIT_NEG, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+
+ case SLJIT_CLZ:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ return emit_op(compiler, SLJIT_CLZ, inp_flags | (!(op & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+ return emit_op(compiler, SLJIT_CLZ, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw);
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#define TEST_SL_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)
+
+#define TEST_UL_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff))
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_SH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= SLJIT_W(0x7fffffff) && (srcw) >= SLJIT_W(-0x80000000))
+#else
+#define TEST_SH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & 0xffff))
+#endif
+
+#define TEST_UH_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_ADD_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000))
+#else
+#define TEST_ADD_IMM(src, srcw) \
+ ((src) & SLJIT_IMM)
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_UI_IMM(src, srcw) \
+ (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
+#else
+#define TEST_UI_IMM(src, srcw) \
+ ((src) & SLJIT_IMM)
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0;
+
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ if ((src1 & SLJIT_IMM) && src1w == 0)
+ src1 = ZERO_REG;
+ if ((src2 & SLJIT_IMM) && src2w == 0)
+ src2 = ZERO_REG;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP) {
+ inp_flags |= INT_DATA | SIGNED_DATA;
+ if (src1 & SLJIT_IMM)
+ src1w = (src1w << 32) >> 32;
+ if (src2 & SLJIT_IMM)
+ src2w = (src2w << 32) >> 32;
+ if (GET_FLAGS(op))
+ inp_flags |= ALT_SIGN_EXT;
+ }
+#endif
+ if (op & SLJIT_SET_O)
+ FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG)));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src2, src2w)) {
+ compiler->imm = (src2w >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src1, src1w)) {
+ compiler->imm = (src1w >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ /* Range between -1 and -32768 is covered above. */
+ if (TEST_ADD_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_ADD_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, SLJIT_ADD, inp_flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_ADDC:
+ return emit_op(compiler, SLJIT_ADDC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUB:
+ if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
+ if (TEST_SL_IMM(src2, -src2w)) {
+ compiler->imm = (-src2w) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_SH_IMM(src2, -src2w)) {
+ compiler->imm = ((-src2w) >> 16) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ /* Range between -1 and -32768 is covered above. */
+ if (TEST_ADD_IMM(src2, -src2w)) {
+ compiler->imm = -src2w & 0xffffffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ }
+ if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) {
+ if (!(op & SLJIT_SET_U)) {
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) {
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
+ if (TEST_UL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
+ }
+ if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
+ compiler->imm = src2w;
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, SLJIT_SUB, inp_flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w);
+ }
+ if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) {
+ if (TEST_SL_IMM(src2, -src2w)) {
+ compiler->imm = (-src2w) & 0xffff;
+ return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ }
+ /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
+ return emit_op(compiler, SLJIT_SUB, inp_flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SUBC:
+ return emit_op(compiler, SLJIT_SUBC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_MUL:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP)
+ inp_flags |= ALT_FORM2;
+#endif
+ if (!GET_FLAGS(op)) {
+ if (TEST_SL_IMM(src2, src2w)) {
+ compiler->imm = src2w & 0xffff;
+ return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_SL_IMM(src1, src1w)) {
+ compiler->imm = src1w & 0xffff;
+ return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, SLJIT_MUL, inp_flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* Commutative unsigned operations. */
+ if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) {
+ if (TEST_UL_IMM(src2, src2w)) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UL_IMM(src1, src1w)) {
+ compiler->imm = src1w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ if (TEST_UH_IMM(src2, src2w)) {
+ compiler->imm = (src2w >> 16) & 0xffff;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UH_IMM(src1, src1w)) {
+ compiler->imm = (src1w >> 16) & 0xffff;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) {
+ if (TEST_UI_IMM(src2, src2w)) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ if (TEST_UI_IMM(src1, src1w)) {
+ compiler->imm = src1w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0);
+ }
+ }
+ return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w);
+
+ case SLJIT_SHL:
+ case SLJIT_LSHR:
+ case SLJIT_ASHR:
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (op & SLJIT_INT_OP)
+ inp_flags |= ALT_FORM2;
+#endif
+ if (src2 & SLJIT_IMM) {
+ compiler->imm = src2w;
+ return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
+ }
+ return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size == 4);
+
+ return push_inst(compiler, *(sljit_ins*)instruction);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw)
+{
+ SLJIT_ASSERT(arg & SLJIT_MEM);
+
+ /* Fast loads and stores. */
+ if (!(arg & 0xf0)) {
+ /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */
+ if (argw <= SIMM_MAX && argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(arg & 0xf) | IMM(argw));
+ }
+
+ if (arg & 0xf0) {
+ argw &= 0x3;
+ if (argw) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(TMP_REG2) | (argw << 11) | ((31 - argw) << 1)));
+#else
+ FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, (arg >> 4) & 0xf, argw, 63 - argw, 1)));
+#endif
+ return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B(TMP_REG2));
+ }
+ return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B((arg >> 4) & 0xf));
+ }
+
+ /* Use cache. */
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
+ return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(TMP_REG3) | IMM(argw - compiler->cache_argw));
+
+ /* Put value to cache. */
+ compiler->cache_arg = arg;
+ compiler->cache_argw = argw;
+
+ FAIL_IF(load_immediate(compiler, TMP_REG3, argw));
+ if (!(arg & 0xf))
+ return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(0) | B(TMP_REG3));
+ return push_inst(compiler, (load ? LFDUX : STFDUX) | FD(fpu_reg) | A(TMP_REG3) | B(arg & 0xf));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ if (dst > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw));
+ dst = TMP_FREG1;
+ }
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw));
+ src = TMP_FREG2;
+ }
+ return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src));
+ }
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw));
+ src = dst_fr;
+ }
+
+ switch (op) {
+ case SLJIT_FMOV:
+ if (src != dst_fr && dst_fr != TMP_FREG1)
+ FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src)));
+ break;
+ case SLJIT_FNEG:
+ FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src)));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src)));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_fr;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+ compiler->cache_arg = 0;
+ compiler->cache_argw = 0;
+
+ dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst;
+
+ if (src2 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w));
+ src2 = TMP_FREG2;
+ }
+
+ if (src1 > SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w));
+ src1 = TMP_FREG1;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(push_inst(compiler, FADD | FD(dst_fr) | FA(src1) | FB(src2)));
+ break;
+
+ case SLJIT_FSUB:
+ FAIL_IF(push_inst(compiler, FSUB | FD(dst_fr) | FA(src1) | FB(src2)));
+ break;
+
+ case SLJIT_FMUL:
+ FAIL_IF(push_inst(compiler, FMUL | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */));
+ break;
+
+ case SLJIT_FDIV:
+ FAIL_IF(push_inst(compiler, FDIV | FD(dst_fr) | FA(src1) | FB(src2)));
+ break;
+ }
+
+ if (dst_fr == TMP_FREG1)
+ FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+
+ compiler->has_locals = local_size > 0;
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ compiler->local_size = (2 + saveds + 2) * sizeof(sljit_w) + local_size;
+#else
+ compiler->local_size = (2 + saveds + 7 + 8) * sizeof(sljit_w) + local_size;
+#endif
+ compiler->local_size = (compiler->local_size + 15) & ~0xf;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return push_inst(compiler, MFLR | D(dst));
+ else if (dst & SLJIT_MEM) {
+ FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2)));
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ FAIL_IF(push_inst(compiler, MTLR | S(src)));
+ else {
+ if (src & SLJIT_MEM)
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ else if (src & SLJIT_IMM)
+ FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+ FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
+ }
+ return push_inst(compiler, BLR);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ return (12 << 21) | (2 << 16);
+
+ case SLJIT_C_NOT_EQUAL:
+ return (4 << 21) | (2 << 16);
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return (12 << 21) | ((4 + 0) << 16);
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return (4 << 21) | ((4 + 0) << 16);
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return (12 << 21) | ((4 + 1) << 16);
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return (4 << 21) | ((4 + 1) << 16);
+
+ case SLJIT_C_SIG_LESS:
+ return (12 << 21) | (0 << 16);
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return (4 << 21) | (0 << 16);
+
+ case SLJIT_C_SIG_GREATER:
+ return (12 << 21) | (1 << 16);
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return (4 << 21) | (1 << 16);
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ return (12 << 21) | (3 << 16);
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ return (4 << 21) | (3 << 16);
+
+ case SLJIT_C_FLOAT_EQUAL:
+ return (12 << 21) | ((4 + 2) << 16);
+
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return (4 << 21) | ((4 + 2) << 16);
+
+ case SLJIT_C_FLOAT_NAN:
+ return (12 << 21) | ((4 + 3) << 16);
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return (4 << 21) | ((4 + 3) << 16);
+
+ default:
+ SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
+ return (20 << 21);
+ }
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ struct sljit_jump *jump;
+ sljit_ins bo_bi_flags;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ bo_bi_flags = get_bo_bi_flags(compiler, type & 0xff);
+ if (!bo_bi_flags)
+ return NULL;
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ /* In PPC, we don't need to touch the arguments. */
+ if (type >= SLJIT_JUMP)
+ jump->flags |= UNCOND_B;
+
+ PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
+ PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1)));
+ jump->addr = compiler->size;
+ PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ sljit_ins bo_bi_flags;
+ struct sljit_jump *jump = NULL;
+ int src_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ bo_bi_flags = get_bo_bi_flags(compiler, type);
+ FAIL_IF(!bo_bi_flags);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ src_r = src;
+ else if (src & SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR | UNCOND_B);
+ jump->u.target = srcw;
+
+ FAIL_IF(emit_const(compiler, TMP_REG2, 0));
+ src_r = TMP_REG2;
+ }
+ else {
+ FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
+ src_r = TMP_REG2;
+ }
+
+ FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
+ if (jump)
+ jump->addr = compiler->size;
+ return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0));
+}
+
+/* Get a bit from CR, all other bits are zeroed. */
+#define GET_CR_BIT(bit, dst) \
+ FAIL_IF(push_inst(compiler, MFCR | D(dst))); \
+ FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | ((1 + (bit)) << 11) | (31 << 6) | (31 << 1)));
+
+#define INVERT_BIT(dst) \
+ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1));
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ int reg;
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ GET_CR_BIT(2, reg);
+ break;
+
+ case SLJIT_C_NOT_EQUAL:
+ GET_CR_BIT(2, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ GET_CR_BIT(4 + 0, reg);
+ break;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ GET_CR_BIT(4 + 0, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ GET_CR_BIT(4 + 1, reg);
+ break;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ GET_CR_BIT(4 + 1, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_SIG_LESS:
+ GET_CR_BIT(0, reg);
+ break;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ GET_CR_BIT(0, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_SIG_GREATER:
+ GET_CR_BIT(1, reg);
+ break;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ GET_CR_BIT(1, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ GET_CR_BIT(3, reg);
+ break;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ GET_CR_BIT(3, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_FLOAT_EQUAL:
+ GET_CR_BIT(4 + 2, reg);
+ break;
+
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ GET_CR_BIT(4 + 2, reg);
+ INVERT_BIT(reg);
+ break;
+
+ case SLJIT_C_FLOAT_NAN:
+ GET_CR_BIT(4 + 3, reg);
+ break;
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ GET_CR_BIT(4 + 3, reg);
+ INVERT_BIT(reg);
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+
+ if (GET_OPCODE(op) == SLJIT_OR)
+ return emit_op(compiler, GET_OPCODE(op), GET_FLAGS(op) ? ALT_SET_FLAGS : 0, dst, dstw, dst, dstw, TMP_REG2, 0);
+
+ if (reg == TMP_REG2)
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ struct sljit_const *const_;
+ int reg;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2;
+
+ PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ return const_;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_32.c b/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
new file mode 100644
index 00000000000..68bca8441ae
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
@@ -0,0 +1,517 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* x86 32-bit arch dependent functions. */
+
+static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm)
+{
+ sljit_ub *buf;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w));
+ FAIL_IF(!buf);
+ INC_SIZE(1 + sizeof(sljit_w));
+ *buf++ = opcode;
+ *(sljit_w*)buf = imm;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
+{
+ if (type == SLJIT_JUMP) {
+ *code_ptr++ = 0xe9;
+ jump->addr++;
+ }
+ else if (type >= SLJIT_FAST_CALL) {
+ *code_ptr++ = 0xe8;
+ jump->addr++;
+ }
+ else {
+ *code_ptr++ = 0x0f;
+ *code_ptr++ = get_jump_code(type);
+ jump->addr += 2;
+ }
+
+ if (jump->flags & JUMP_LABEL)
+ jump->flags |= PATCH_MW;
+ else
+ *(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4);
+ code_ptr += 4;
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->args = args;
+ compiler->flags_saved = 0;
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (args * 2) : 0) + (args > 2 ? 2 : 0);
+#else
+ size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+ PUSH_REG(reg_map[TMP_REGISTER]);
+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (args > 0) {
+ *buf++ = 0x8b;
+ *buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3);
+ }
+#endif
+ if (saveds > 2)
+ PUSH_REG(reg_map[SLJIT_SAVED_REG3]);
+ if (saveds > 1)
+ PUSH_REG(reg_map[SLJIT_SAVED_REG2]);
+ if (saveds > 0)
+ PUSH_REG(reg_map[SLJIT_SAVED_REG1]);
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (args > 0) {
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3];
+ }
+ if (args > 1) {
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2];
+ }
+ if (args > 2) {
+ *buf++ = 0x8b;
+ *buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3);
+ *buf++ = 0x24;
+ *buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */
+ }
+#else
+ if (args > 0) {
+ *buf++ = 0x8b;
+ *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
+ *buf++ = sizeof(sljit_w) * 2;
+ }
+ if (args > 1) {
+ *buf++ = 0x8b;
+ *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
+ *buf++ = sizeof(sljit_w) * 3;
+ }
+ if (args > 2) {
+ *buf++ = 0x8b;
+ *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
+ *buf++ = sizeof(sljit_w) * 4;
+ }
+#endif
+
+ local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+ compiler->temporaries_start = local_size;
+ if (temporaries > 3)
+ local_size += (temporaries - 3) * sizeof(sljit_uw);
+ compiler->saveds_start = local_size;
+ if (saveds > 3)
+ local_size += (saveds - 3) * sizeof(sljit_uw);
+
+#ifdef _WIN32
+ if (local_size > 1024) {
+ FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size));
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
+ }
+#endif
+
+ compiler->local_size = local_size;
+ if (local_size > 0)
+ return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
+ SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->args = args;
+ compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+ compiler->temporaries_start = compiler->local_size;
+ if (temporaries > 3)
+ compiler->local_size += (temporaries - 3) * sizeof(sljit_uw);
+ compiler->saveds_start = compiler->local_size;
+ if (saveds > 3)
+ compiler->local_size += (saveds - 3) * sizeof(sljit_uw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ int size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+ SLJIT_ASSERT(compiler->args >= 0);
+
+ compiler->flags_saved = 0;
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0)
+ FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
+ SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
+
+ size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (compiler->args > 2)
+ size += 2;
+#else
+ if (compiler->args > 0)
+ size += 2;
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+
+ if (compiler->saveds > 0)
+ POP_REG(reg_map[SLJIT_SAVED_REG1]);
+ if (compiler->saveds > 1)
+ POP_REG(reg_map[SLJIT_SAVED_REG2]);
+ if (compiler->saveds > 2)
+ POP_REG(reg_map[SLJIT_SAVED_REG3]);
+ POP_REG(reg_map[TMP_REGISTER]);
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (compiler->args > 2)
+ RETN(sizeof(sljit_w));
+ else
+ RET();
+#else
+ if (compiler->args > 0)
+ RETN(compiler->args * sizeof(sljit_w));
+ else
+ RET();
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+/* Size contains the flags as well. */
+static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
+ /* The register or immediate operand. */
+ int a, sljit_w imma,
+ /* The general operand (not immediate). */
+ int b, sljit_w immb)
+{
+ sljit_ub *buf;
+ sljit_ub *buf_ptr;
+ int flags = size & ~0xf;
+ int inst_size;
+
+ /* Both cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
+ /* Size flags not allowed for typed instructions. */
+ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
+ /* Both size flags cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ /* SSE2 and immediate is not possible. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
+#endif
+
+ size &= 0xf;
+ inst_size = size;
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ inst_size++;
+#endif
+ if (flags & EX86_PREF_66)
+ inst_size++;
+
+ /* Calculate size of b. */
+ inst_size += 1; /* mod r/m byte. */
+ if (b & SLJIT_MEM) {
+ if ((b & 0x0f) == SLJIT_UNUSED)
+ inst_size += sizeof(sljit_w);
+ else if (immb != 0 && !(b & 0xf0)) {
+ /* Immediate operand. */
+ if (immb <= 127 && immb >= -128)
+ inst_size += sizeof(sljit_b);
+ else
+ inst_size += sizeof(sljit_w);
+ }
+
+ if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
+ b |= SLJIT_LOCALS_REG << 4;
+
+ if ((b & 0xf0) != SLJIT_UNUSED)
+ inst_size += 1; /* SIB byte. */
+ }
+
+ /* Calculate size of a. */
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BIN_INS) {
+ if (imma <= 127 && imma >= -128) {
+ inst_size += 1;
+ flags |= EX86_BYTE_ARG;
+ } else
+ inst_size += 4;
+ }
+ else if (flags & EX86_SHIFT_INS) {
+ imma &= 0x1f;
+ if (imma != 1) {
+ inst_size ++;
+ flags |= EX86_BYTE_ARG;
+ }
+ } else if (flags & EX86_BYTE_ARG)
+ inst_size++;
+ else if (flags & EX86_HALF_ARG)
+ inst_size += sizeof(short);
+ else
+ inst_size += sizeof(sljit_w);
+ }
+ else
+ SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
+ PTR_FAIL_IF(!buf);
+
+ /* Encoding the byte. */
+ INC_SIZE(inst_size);
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ *buf++ = 0xf2;
+#endif
+ if (flags & EX86_PREF_66)
+ *buf++ = 0x66;
+
+ buf_ptr = buf + size;
+
+ /* Encode mod/rm byte. */
+ if (!(flags & EX86_SHIFT_INS)) {
+ if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
+ *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
+
+ if ((a & SLJIT_IMM) || (a == 0))
+ *buf_ptr = 0;
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ else if (!(flags & EX86_SSE2))
+ *buf_ptr = reg_map[a] << 3;
+ else
+ *buf_ptr = a << 3;
+#else
+ else
+ *buf_ptr = reg_map[a] << 3;
+#endif
+ }
+ else {
+ if (a & SLJIT_IMM) {
+ if (imma == 1)
+ *buf = 0xd1;
+ else
+ *buf = 0xc1;
+ } else
+ *buf = 0xd3;
+ *buf_ptr = 0;
+ }
+
+ if (!(b & SLJIT_MEM))
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
+#else
+ *buf_ptr++ |= 0xc0 + reg_map[b];
+#endif
+ else if ((b & 0x0f) != SLJIT_UNUSED) {
+ if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr |= 0x40;
+ else
+ *buf_ptr |= 0x80;
+ }
+
+ if ((b & 0xf0) == SLJIT_UNUSED)
+ *buf_ptr++ |= reg_map[b & 0x0f];
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3);
+ }
+
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr++ = immb; /* 8 bit displacement. */
+ else {
+ *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_w);
+ }
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_map[b & 0x0f] | (reg_map[(b >> 4) & 0x0f] << 3) | (immb << 6);
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x05;
+ *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_w);
+ }
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BYTE_ARG)
+ *buf_ptr = imma;
+ else if (flags & EX86_HALF_ARG)
+ *(short*)buf_ptr = imma;
+ else if (!(flags & EX86_SHIFT_INS))
+ *(sljit_w*)buf_ptr = imma;
+ }
+
+ return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Call / return instructions */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
+{
+ sljit_ub *buf;
+
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
+
+ if (type >= SLJIT_CALL3)
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1];
+#else
+ buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(type - SLJIT_CALL0);
+ if (type >= SLJIT_CALL3)
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
+ if (type >= SLJIT_CALL2)
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]);
+ PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]);
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->args = args;
+ compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+ compiler->temporaries_start = compiler->local_size;
+ if (temporaries > 3)
+ compiler->local_size += (temporaries - 3) * sizeof(sljit_uw);
+ compiler->saveds_start = compiler->local_size;
+ if (saveds > 3)
+ compiler->local_size += (saveds - 3) * sizeof(sljit_uw);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1);
+ POP_REG(reg_map[dst]);
+ return SLJIT_SUCCESS;
+ }
+ else if (dst & SLJIT_MEM) {
+ buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!buf);
+ *buf++ = 0x8f;
+ return SLJIT_SUCCESS;
+ }
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1);
+ POP_REG(reg_map[TMP_REGISTER]);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1 + 1);
+ PUSH_REG(reg_map[src]);
+ }
+ else if (src & SLJIT_MEM) {
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf++ = 0xff;
+ *buf |= 6 << 3;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ }
+ else {
+ /* SLJIT_IMM. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(5 + 1);
+ *buf++ = 0x68;
+ *(sljit_w*)buf = srcw;
+ buf += sizeof(sljit_w);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_64.c b/src/3rdparty/pcre/sljit/sljitNativeX86_64.c
new file mode 100644
index 00000000000..40d875b8413
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_64.c
@@ -0,0 +1,842 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* x86 64-bit arch dependent functions. */
+
+static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)
+{
+ sljit_ub *buf;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w));
+ FAIL_IF(!buf);
+ INC_SIZE(2 + sizeof(sljit_w));
+ *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
+ *buf++ = 0xb8 + (reg_map[reg] & 0x7);
+ *(sljit_w*)buf = imm;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
+{
+ if (type < SLJIT_JUMP) {
+ *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
+ *code_ptr++ = 10 + 3;
+ }
+
+ SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
+ *code_ptr++ = REX_W | REX_B;
+ *code_ptr++ = 0xb8 + 1;
+ jump->addr = (sljit_uw)code_ptr;
+
+ if (jump->flags & JUMP_LABEL)
+ jump->flags |= PATCH_MD;
+ else
+ *(sljit_w*)code_ptr = jump->u.target;
+
+ code_ptr += sizeof(sljit_w);
+ *code_ptr++ = REX_B;
+ *code_ptr++ = 0xff;
+ *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
+
+ return code_ptr;
+}
+
+static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)
+{
+ sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));
+
+ if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
+ *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
+ *(sljit_w*)code_ptr = delta;
+ }
+ else {
+ SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
+ *code_ptr++ = REX_W | REX_B;
+ *code_ptr++ = 0xb8 + 1;
+ *(sljit_w*)code_ptr = addr;
+ code_ptr += sizeof(sljit_w);
+ *code_ptr++ = REX_B;
+ *code_ptr++ = 0xff;
+ *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int size, pushed_size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->flags_saved = 0;
+
+ size = saveds;
+ /* Including the return address saved by the call instruction. */
+ pushed_size = (saveds + 1) * sizeof(sljit_w);
+#ifndef _WIN64
+ if (saveds >= 2)
+ size += saveds - 1;
+#else
+ /* Saving the virtual stack pointer. */
+ compiler->has_locals = local_size > 0;
+ if (local_size > 0) {
+ size += 2;
+ pushed_size += sizeof(sljit_w);
+ }
+ if (saveds >= 4)
+ size += saveds - 3;
+ if (temporaries >= 5) {
+ size += (5 - 4) * 2;
+ pushed_size += sizeof(sljit_w);
+ }
+#endif
+ size += args * 3;
+ if (size > 0) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+ if (saveds >= 5) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);
+ }
+ if (saveds >= 4) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);
+ }
+ if (saveds >= 3) {
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);
+ *buf++ = REX_B;
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
+#endif
+ PUSH_REG(reg_lmap[SLJIT_SAVED_REG3]);
+ }
+ if (saveds >= 2) {
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
+ *buf++ = REX_B;
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
+#endif
+ PUSH_REG(reg_lmap[SLJIT_SAVED_REG2]);
+ }
+ if (saveds >= 1) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG1] < 8, saved_reg1_is_loreg);
+ PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
+ }
+#ifdef _WIN64
+ if (temporaries >= 5) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
+ }
+ if (local_size > 0) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_LOCALS_REG] >= 8, locals_reg_is_hireg);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[SLJIT_LOCALS_REG]);
+ }
+#endif
+
+#ifndef _WIN64
+ if (args > 0) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7;
+ }
+ if (args > 1) {
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6;
+ }
+ if (args > 2) {
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2;
+ }
+#else
+ if (args > 0) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1;
+ }
+ if (args > 1) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2;
+ }
+ if (args > 2) {
+ *buf++ = REX_W | REX_B;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0;
+ }
+#endif
+ }
+
+ local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
+#ifdef _WIN64
+ local_size += 4 * sizeof(sljit_w);
+ compiler->local_size = local_size;
+ if (local_size > 1024) {
+ /* Allocate the stack for the function itself. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4);
+ *buf++ = REX_W;
+ *buf++ = 0x83;
+ *buf++ = 0xc0 | (5 << 3) | 4;
+ /* Pushed size must be divisible by 8. */
+ SLJIT_ASSERT(!(pushed_size & 0x7));
+ if (pushed_size & 0x8) {
+ *buf++ = 5 * sizeof(sljit_w);
+ local_size -= 5 * sizeof(sljit_w);
+ } else {
+ *buf++ = 4 * sizeof(sljit_w);
+ local_size -= 4 * sizeof(sljit_w);
+ }
+ FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
+ FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_touch_stack)));
+ }
+#else
+ compiler->local_size = local_size;
+ if (local_size > 0) {
+#endif
+ /* In case of Win64, local_size is always > 4 * sizeof(sljit_w) */
+ if (local_size <= 127) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4);
+ *buf++ = REX_W;
+ *buf++ = 0x83;
+ *buf++ = 0xc0 | (5 << 3) | 4;
+ *buf++ = local_size;
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
+ FAIL_IF(!buf);
+ INC_SIZE(7);
+ *buf++ = REX_W;
+ *buf++ = 0x81;
+ *buf++ = 0xc0 | (5 << 3) | 4;
+ *(sljit_hw*)buf = local_size;
+ buf += sizeof(sljit_hw);
+ }
+#ifndef _WIN64
+ }
+#endif
+
+#ifdef _WIN64
+ if (compiler->has_locals) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!buf);
+ INC_SIZE(5);
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8d;
+ *buf++ = 0x40 | (reg_lmap[SLJIT_LOCALS_REG] << 3) | 0x4;
+ *buf++ = 0x24;
+ *buf = 4 * sizeof(sljit_w);
+ }
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
+{
+ int pushed_size;
+
+ CHECK_ERROR_VOID();
+ check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ /* Including the return address saved by the call instruction. */
+ pushed_size = (saveds + 1) * sizeof(sljit_w);
+#ifdef _WIN64
+ compiler->has_locals = local_size > 0;
+ if (local_size > 0)
+ pushed_size += sizeof(sljit_w);
+ if (temporaries >= 5)
+ pushed_size += sizeof(sljit_w);
+#endif
+ compiler->local_size = ((local_size + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
+#ifdef _WIN64
+ compiler->local_size += 4 * sizeof(sljit_w);
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
+{
+ int size;
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_return(compiler, op, src, srcw);
+
+ compiler->flags_saved = 0;
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ if (compiler->local_size > 0) {
+ if (compiler->local_size <= 127) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4);
+ *buf++ = REX_W;
+ *buf++ = 0x83;
+ *buf++ = 0xc0 | (0 << 3) | 4;
+ *buf = compiler->local_size;
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
+ FAIL_IF(!buf);
+ INC_SIZE(7);
+ *buf++ = REX_W;
+ *buf++ = 0x81;
+ *buf++ = 0xc0 | (0 << 3) | 4;
+ *(sljit_hw*)buf = compiler->local_size;
+ }
+ }
+
+ size = 1 + compiler->saveds;
+#ifndef _WIN64
+ if (compiler->saveds >= 2)
+ size += compiler->saveds - 1;
+#else
+ if (compiler->has_locals)
+ size += 2;
+ if (compiler->saveds >= 4)
+ size += compiler->saveds - 3;
+ if (compiler->temporaries >= 5)
+ size += (5 - 4) * 2;
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+
+ INC_SIZE(size);
+
+#ifdef _WIN64
+ if (compiler->has_locals) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_LOCALS_REG]);
+ }
+ if (compiler->temporaries >= 5) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
+ }
+#endif
+ if (compiler->saveds >= 1)
+ POP_REG(reg_map[SLJIT_SAVED_REG1]);
+ if (compiler->saveds >= 2) {
+#ifndef _WIN64
+ *buf++ = REX_B;
+#endif
+ POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
+ }
+ if (compiler->saveds >= 3) {
+#ifndef _WIN64
+ *buf++ = REX_B;
+#endif
+ POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
+ }
+ if (compiler->saveds >= 4) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
+ }
+ if (compiler->saveds >= 5) {
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)
+{
+ sljit_ub *buf;
+
+ if (rex != 0) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw));
+ FAIL_IF(!buf);
+ INC_SIZE(2 + sizeof(sljit_hw));
+ *buf++ = rex;
+ *buf++ = opcode;
+ *(sljit_hw*)buf = imm;
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw));
+ FAIL_IF(!buf);
+ INC_SIZE(1 + sizeof(sljit_hw));
+ *buf++ = opcode;
+ *(sljit_hw*)buf = imm;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
+ /* The register or immediate operand. */
+ int a, sljit_w imma,
+ /* The general operand (not immediate). */
+ int b, sljit_w immb)
+{
+ sljit_ub *buf;
+ sljit_ub *buf_ptr;
+ sljit_ub rex = 0;
+ int flags = size & ~0xf;
+ int inst_size;
+
+ /* The immediate operand must be 32 bit. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
+ /* Both cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
+ /* Size flags not allowed for typed instructions. */
+ SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
+ /* Both size flags cannot be switched on. */
+ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ /* SSE2 and immediate is not possible. */
+ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
+#endif
+
+ size &= 0xf;
+ inst_size = size;
+
+ if ((b & SLJIT_MEM) && !(b & 0xf0) && NOT_HALFWORD(immb)) {
+ if (emit_load_imm64(compiler, TMP_REG3, immb))
+ return NULL;
+ immb = 0;
+ if (b & 0xf)
+ b |= TMP_REG3 << 4;
+ else
+ b |= TMP_REG3;
+ }
+
+ if (!compiler->mode32 && !(flags & EX86_NO_REXW))
+ rex |= REX_W;
+ else if (flags & EX86_REX)
+ rex |= REX;
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ inst_size++;
+#endif
+ if (flags & EX86_PREF_66)
+ inst_size++;
+
+ /* Calculate size of b. */
+ inst_size += 1; /* mod r/m byte. */
+ if (b & SLJIT_MEM) {
+ if ((b & 0x0f) == SLJIT_UNUSED)
+ inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */
+ else {
+ if (reg_map[b & 0x0f] >= 8)
+ rex |= REX_B;
+ if (immb != 0 && !(b & 0xf0)) {
+ /* Immediate operand. */
+ if (immb <= 127 && immb >= -128)
+ inst_size += sizeof(sljit_b);
+ else
+ inst_size += sizeof(sljit_hw);
+ }
+ }
+
+#ifndef _WIN64
+ if ((b & 0xf) == SLJIT_LOCALS_REG && (b & 0xf0) == 0)
+ b |= SLJIT_LOCALS_REG << 4;
+#endif
+
+ if ((b & 0xf0) != SLJIT_UNUSED) {
+ inst_size += 1; /* SIB byte. */
+ if (reg_map[(b >> 4) & 0x0f] >= 8)
+ rex |= REX_X;
+ }
+ }
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ else if (!(flags & EX86_SSE2) && reg_map[b] >= 8)
+ rex |= REX_B;
+#else
+ else if (reg_map[b] >= 8)
+ rex |= REX_B;
+#endif
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BIN_INS) {
+ if (imma <= 127 && imma >= -128) {
+ inst_size += 1;
+ flags |= EX86_BYTE_ARG;
+ } else
+ inst_size += 4;
+ }
+ else if (flags & EX86_SHIFT_INS) {
+ imma &= compiler->mode32 ? 0x1f : 0x3f;
+ if (imma != 1) {
+ inst_size ++;
+ flags |= EX86_BYTE_ARG;
+ }
+ } else if (flags & EX86_BYTE_ARG)
+ inst_size++;
+ else if (flags & EX86_HALF_ARG)
+ inst_size += sizeof(short);
+ else
+ inst_size += sizeof(sljit_hw);
+ }
+ else {
+ SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
+ /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (!(flags & EX86_SSE2) && reg_map[a] >= 8)
+ rex |= REX_R;
+#else
+ if (reg_map[a] >= 8)
+ rex |= REX_R;
+#endif
+ }
+
+ if (rex)
+ inst_size++;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
+ PTR_FAIL_IF(!buf);
+
+ /* Encoding the byte. */
+ INC_SIZE(inst_size);
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ if (flags & EX86_PREF_F2)
+ *buf++ = 0xf2;
+#endif
+ if (flags & EX86_PREF_66)
+ *buf++ = 0x66;
+ if (rex)
+ *buf++ = rex;
+ buf_ptr = buf + size;
+
+ /* Encode mod/rm byte. */
+ if (!(flags & EX86_SHIFT_INS)) {
+ if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
+ *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
+
+ if ((a & SLJIT_IMM) || (a == 0))
+ *buf_ptr = 0;
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ else if (!(flags & EX86_SSE2))
+ *buf_ptr = reg_lmap[a] << 3;
+ else
+ *buf_ptr = a << 3;
+#else
+ else
+ *buf_ptr = reg_lmap[a] << 3;
+#endif
+ }
+ else {
+ if (a & SLJIT_IMM) {
+ if (imma == 1)
+ *buf = 0xd1;
+ else
+ *buf = 0xc1;
+ } else
+ *buf = 0xd3;
+ *buf_ptr = 0;
+ }
+
+ if (!(b & SLJIT_MEM))
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+ *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
+#else
+ *buf_ptr++ |= 0xc0 + reg_lmap[b];
+#endif
+ else if ((b & 0x0f) != SLJIT_UNUSED) {
+#ifdef _WIN64
+ SLJIT_ASSERT((b & 0xf0) != (SLJIT_LOCALS_REG << 4));
+#endif
+ if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr |= 0x40;
+ else
+ *buf_ptr |= 0x80;
+ }
+
+ if ((b & 0xf0) == SLJIT_UNUSED)
+ *buf_ptr++ |= reg_lmap[b & 0x0f];
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3);
+ }
+
+ if (immb != 0) {
+ if (immb <= 127 && immb >= -128)
+ *buf_ptr++ = immb; /* 8 bit displacement. */
+ else {
+ *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_hw);
+ }
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = reg_lmap[b & 0x0f] | (reg_lmap[(b >> 4) & 0x0f] << 3) | (immb << 6);
+ }
+ }
+ else {
+ *buf_ptr++ |= 0x04;
+ *buf_ptr++ = 0x25;
+ *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
+ buf_ptr += sizeof(sljit_hw);
+ }
+
+ if (a & SLJIT_IMM) {
+ if (flags & EX86_BYTE_ARG)
+ *buf_ptr = imma;
+ else if (flags & EX86_HALF_ARG)
+ *(short*)buf_ptr = imma;
+ else if (!(flags & EX86_SHIFT_INS))
+ *(sljit_hw*)buf_ptr = imma;
+ }
+
+ return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
+}
+
+/* --------------------------------------------------------------------- */
+/* Call / return instructions */
+/* --------------------------------------------------------------------- */
+
+static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
+{
+ sljit_ub *buf;
+
+#ifndef _WIN64
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
+ FAIL_IF(!buf);
+ INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
+ if (type >= SLJIT_CALL3) {
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
+ }
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
+#else
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
+ FAIL_IF(!buf);
+ INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
+ if (type >= SLJIT_CALL3) {
+ *buf++ = REX_W | REX_R;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
+ }
+ *buf++ = REX_W;
+ *buf++ = 0x8b;
+ *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, saveds, local_size);
+
+ compiler->temporaries = temporaries;
+ compiler->saveds = saveds;
+ compiler->local_size = (local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1);
+#ifdef _WIN64
+ compiler->local_size += 4 * sizeof(sljit_w);
+#endif
+
+ /* For UNUSED dst. Uncommon, but possible. */
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REGISTER;
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+ if (reg_map[dst] < 8) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1);
+ POP_REG(reg_lmap[dst]);
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+
+ INC_SIZE(2);
+ *buf++ = REX_B;
+ POP_REG(reg_lmap[dst]);
+ }
+ }
+ else if (dst & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!buf);
+ *buf++ = 0x8f;
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_fast_return(compiler, src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+ if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, srcw));
+ src = TMP_REGISTER;
+ }
+
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
+ if (reg_map[src] < 8) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(1 + 1);
+ PUSH_REG(reg_lmap[src]);
+ }
+ else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(2 + 1);
+ *buf++ = REX_B;
+ PUSH_REG(reg_lmap[src]);
+ }
+ }
+ else if (src & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf++ = 0xff;
+ *buf |= 6 << 3;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ }
+ else {
+ SLJIT_ASSERT(IS_HALFWORD(srcw));
+ /* SLJIT_IMM. */
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
+ FAIL_IF(!buf);
+
+ INC_SIZE(5 + 1);
+ *buf++ = 0x68;
+ *(sljit_hw*)buf = srcw;
+ buf += sizeof(sljit_hw);
+ }
+
+ RET();
+ return SLJIT_SUCCESS;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Extend input */
+/* --------------------------------------------------------------------- */
+
+static int emit_mov_int(struct sljit_compiler *compiler, int sign,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+
+ compiler->mode32 = 0;
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ return SLJIT_SUCCESS;
+ }
+ return emit_load_imm64(compiler, dst, srcw);
+ }
+ compiler->mode32 = 1;
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ compiler->mode32 = 0;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER;
+
+ if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3))
+ dst_r = src;
+ else {
+ if (sign) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x63;
+ } else {
+ compiler->mode32 = 1;
+ FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
+ compiler->mode32 = 0;
+ }
+ }
+
+ if (dst & SLJIT_MEM) {
+ compiler->mode32 = 1;
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ compiler->mode32 = 0;
+ }
+
+ return SLJIT_SUCCESS;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
new file mode 100644
index 00000000000..0a44163802f
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
@@ -0,0 +1,2858 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name()
+{
+ return "x86" SLJIT_CPUINFO;
+}
+
+/*
+ 32b register indexes:
+ 0 - EAX
+ 1 - ECX
+ 2 - EDX
+ 3 - EBX
+ 4 - none
+ 5 - EBP
+ 6 - ESI
+ 7 - EDI
+*/
+
+/*
+ 64b register indexes:
+ 0 - RAX
+ 1 - RCX
+ 2 - RDX
+ 3 - RBX
+ 4 - none
+ 5 - RBP
+ 6 - RSI
+ 7 - RDI
+ 8 - R8 - From now on REX prefix is required
+ 9 - R9
+ 10 - R10
+ 11 - R11
+ 12 - R12
+ 13 - R13
+ 14 - R14
+ 15 - R15
+*/
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+
+/* Last register + 1. */
+#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
+
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = {
+ 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5
+};
+
+#define CHECK_EXTRA_REGS(p, w, do) \
+ if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \
+ w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \
+ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
+ do; \
+ } \
+ else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \
+ w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \
+ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \
+ do; \
+ }
+
+#else /* SLJIT_CONFIG_X86_32 */
+
+/* Last register + 1. */
+#define TMP_REGISTER (SLJIT_NO_REGISTERS + 1)
+#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
+#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
+
+/* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present
+ Note: avoid to use r12 and r13 for memory addessing
+ therefore r12 is better for SAVED_EREG than SAVED_REG. */
+#ifndef _WIN64
+/* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9
+};
+/* low-map. reg_map & 0x7. */
+static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1
+};
+#else
+/* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 12, 15, 10, 8, 9
+};
+/* low-map. reg_map & 0x7. */
+static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
+ 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 4, 7, 2, 0, 1
+};
+#endif
+
+#define REX_W 0x48
+#define REX_R 0x44
+#define REX_X 0x42
+#define REX_B 0x41
+#define REX 0x40
+
+typedef unsigned int sljit_uhw;
+typedef int sljit_hw;
+
+#define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll)
+#define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll)
+
+#define CHECK_EXTRA_REGS(p, w, do)
+
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+#define TMP_FREG (SLJIT_FLOAT_REG4 + 1)
+#endif
+
+/* Size flags for emit_x86_instruction: */
+#define EX86_BIN_INS 0x0010
+#define EX86_SHIFT_INS 0x0020
+#define EX86_REX 0x0040
+#define EX86_NO_REXW 0x0080
+#define EX86_BYTE_ARG 0x0100
+#define EX86_HALF_ARG 0x0200
+#define EX86_PREF_66 0x0400
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+#define EX86_PREF_F2 0x0800
+#define EX86_SSE2 0x1000
+#endif
+
+#define INC_SIZE(s) (*buf++ = (s), compiler->size += (s))
+#define INC_CSIZE(s) (*code++ = (s), compiler->size += (s))
+
+#define PUSH_REG(r) (*buf++ = (0x50 + (r)))
+#define POP_REG(r) (*buf++ = (0x58 + (r)))
+#define RET() (*buf++ = (0xc3))
+#define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0)
+/* r32, r/m32 */
+#define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm))
+
+static sljit_ub get_jump_code(int type)
+{
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_FLOAT_EQUAL:
+ return 0x84;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ return 0x85;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ return 0x82;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ return 0x83;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ return 0x87;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ return 0x86;
+
+ case SLJIT_C_SIG_LESS:
+ return 0x8c;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ return 0x8d;
+
+ case SLJIT_C_SIG_GREATER:
+ return 0x8f;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ return 0x8e;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ return 0x80;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ return 0x81;
+
+ case SLJIT_C_FLOAT_NAN:
+ return 0x8a;
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ return 0x8b;
+ }
+ return 0;
+}
+
+static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type);
+#endif
+
+static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type)
+{
+ int short_jump;
+ sljit_uw label_addr;
+
+ if (jump->flags & JUMP_LABEL)
+ label_addr = (sljit_uw)(code + jump->u.label->size);
+ else
+ label_addr = jump->u.target;
+ short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll)
+ return generate_far_jump_code(jump, code_ptr, type);
+#endif
+
+ if (type == SLJIT_JUMP) {
+ if (short_jump)
+ *code_ptr++ = 0xeb;
+ else
+ *code_ptr++ = 0xe9;
+ jump->addr++;
+ }
+ else if (type >= SLJIT_FAST_CALL) {
+ short_jump = 0;
+ *code_ptr++ = 0xe8;
+ jump->addr++;
+ }
+ else if (short_jump) {
+ *code_ptr++ = get_jump_code(type) - 0x10;
+ jump->addr++;
+ }
+ else {
+ *code_ptr++ = 0x0f;
+ *code_ptr++ = get_jump_code(type);
+ jump->addr += 2;
+ }
+
+ if (short_jump) {
+ jump->flags |= PATCH_MB;
+ code_ptr += sizeof(sljit_b);
+ } else {
+ jump->flags |= PATCH_MW;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code_ptr += sizeof(sljit_w);
+#else
+ code_ptr += sizeof(sljit_hw);
+#endif
+ }
+
+ return code_ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_memory_fragment *buf;
+ sljit_ub *code;
+ sljit_ub *code_ptr;
+ sljit_ub *buf_ptr;
+ sljit_ub *buf_end;
+ sljit_ub len;
+
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_const *const_;
+
+ CHECK_ERROR_PTR();
+ check_sljit_generate_code(compiler);
+ reverse_buf(compiler);
+
+ /* Second code generation pass. */
+ code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size);
+ PTR_FAIL_WITH_EXEC_IF(code);
+ buf = compiler->buf;
+
+ code_ptr = code;
+ label = compiler->labels;
+ jump = compiler->jumps;
+ const_ = compiler->consts;
+ do {
+ buf_ptr = buf->memory;
+ buf_end = buf_ptr + buf->used_size;
+ do {
+ len = *buf_ptr++;
+ if (len > 0) {
+ /* The code is already generated. */
+ SLJIT_MEMMOVE(code_ptr, buf_ptr, len);
+ code_ptr += len;
+ buf_ptr += len;
+ }
+ else {
+ if (*buf_ptr >= 4) {
+ jump->addr = (sljit_uw)code_ptr;
+ if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
+ code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 4);
+ else
+ code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 4);
+ jump = jump->next;
+ }
+ else if (*buf_ptr == 0) {
+ label->addr = (sljit_uw)code_ptr;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ else if (*buf_ptr == 1) {
+ const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w);
+ const_ = const_->next;
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
+ buf_ptr++;
+ *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w));
+ code_ptr += sizeof(sljit_w);
+ buf_ptr += sizeof(sljit_w) - 1;
+#else
+ code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr);
+ buf_ptr += sizeof(sljit_w);
+#endif
+ }
+ buf_ptr++;
+ }
+ } while (buf_ptr < buf_end);
+ SLJIT_ASSERT(buf_ptr == buf_end);
+ buf = buf->next;
+ } while (buf);
+
+ SLJIT_ASSERT(!label);
+ SLJIT_ASSERT(!jump);
+ SLJIT_ASSERT(!const_);
+
+ jump = compiler->jumps;
+ while (jump) {
+ if (jump->flags & PATCH_MB) {
+ SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127);
+ *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b)));
+ } else if (jump->flags & PATCH_MW) {
+ if (jump->flags & JUMP_LABEL) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w)));
+#else
+ SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
+ *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw)));
+#endif
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w)));
+#else
+ SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll);
+ *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw)));
+#endif
+ }
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ else if (jump->flags & PATCH_MD)
+ *(sljit_w*)jump->addr = jump->u.label->addr;
+#endif
+
+ jump = jump->next;
+ }
+
+ /* Maybe we waste some space because of short jumps. */
+ SLJIT_ASSERT(code_ptr <= code + compiler->size);
+ compiler->error = SLJIT_ERR_COMPILED;
+ compiler->executable_size = compiler->size;
+ return (void*)code;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+static int emit_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+static int emit_non_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w);
+
+static int emit_mov(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw);
+
+static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler)
+{
+ sljit_ub *buf;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!buf);
+ INC_SIZE(5);
+ *buf++ = 0x9c; /* pushfd */
+#else
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
+ FAIL_IF(!buf);
+ INC_SIZE(6);
+ *buf++ = 0x9c; /* pushfq */
+ *buf++ = 0x48;
+#endif
+ *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
+ *buf++ = 0x64;
+ *buf++ = 0x24;
+ *buf++ = sizeof(sljit_w);
+ compiler->flags_saved = 1;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags)
+{
+ sljit_ub *buf;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
+ FAIL_IF(!buf);
+ INC_SIZE(5);
+#else
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
+ FAIL_IF(!buf);
+ INC_SIZE(6);
+ *buf++ = 0x48;
+#endif
+ *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
+ *buf++ = 0x64;
+ *buf++ = 0x24;
+ *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
+ *buf++ = 0x9d; /* popfd / popfq */
+ compiler->flags_saved = keep_flags;
+ return SLJIT_SUCCESS;
+}
+
+#ifdef _WIN32
+#include
+
+static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)
+{
+ /* Workaround for calling _chkstk. */
+ alloca(local_size);
+}
+#endif
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#include "sljitNativeX86_32.c"
+#else
+#include "sljitNativeX86_64.c"
+#endif
+
+static int emit_mov(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ /* No destination, doesn't need to setup flags. */
+ if (src & SLJIT_MEM) {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8b;
+ }
+ return SLJIT_SUCCESS;
+ }
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
+ code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ return SLJIT_SUCCESS;
+ }
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
+#else
+ if (!compiler->mode32) {
+ if (NOT_HALFWORD(srcw))
+ return emit_load_imm64(compiler, dst, srcw);
+ }
+ else
+ return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw);
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (!compiler->mode32 && NOT_HALFWORD(srcw)) {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ return SLJIT_SUCCESS;
+ }
+#endif
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+ code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8b;
+ return SLJIT_SUCCESS;
+ }
+
+ /* Memory to memory move. Requires two instruction. */
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8b;
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ return SLJIT_SUCCESS;
+}
+
+#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
+ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op)
+{
+ sljit_ub *buf;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int size;
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op0(compiler, op);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_BREAKPOINT:
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0xcc;
+ break;
+ case SLJIT_NOP:
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0x90;
+ break;
+ case SLJIT_UMUL:
+ case SLJIT_SMUL:
+ case SLJIT_UDIV:
+ case SLJIT_SDIV:
+ compiler->flags_saved = 0;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+#ifdef _WIN64
+ SLJIT_COMPILE_ASSERT(
+ reg_map[SLJIT_TEMPORARY_REG1] == 0
+ && reg_map[SLJIT_TEMPORARY_REG2] == 2
+ && reg_map[TMP_REGISTER] > 7,
+ invalid_register_assignment_for_div_mul);
+#else
+ SLJIT_COMPILE_ASSERT(
+ reg_map[SLJIT_TEMPORARY_REG1] == 0
+ && reg_map[SLJIT_TEMPORARY_REG2] < 7
+ && reg_map[TMP_REGISTER] == 2,
+ invalid_register_assignment_for_div_mul);
+#endif
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+
+ op = GET_OPCODE(op);
+ if (op == SLJIT_UDIV) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
+ buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0);
+#else
+ buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
+#endif
+ FAIL_IF(!buf);
+ *buf = 0x33;
+ }
+
+ if (op == SLJIT_SDIV) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0);
+#endif
+
+ /* CDQ instruction */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0x99;
+#else
+ if (compiler->mode32) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(1);
+ *buf = 0x99;
+ } else {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = REX_W;
+ *buf = 0x99;
+ }
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = 0xf7;
+ *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]);
+#else
+#ifdef _WIN64
+ size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2;
+#else
+ size = (!compiler->mode32) ? 3 : 2;
+#endif
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+ INC_SIZE(size);
+#ifdef _WIN64
+ if (!compiler->mode32)
+ *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0);
+ else if (op >= SLJIT_UDIV)
+ *buf++ = REX_B;
+ *buf++ = 0xf7;
+ *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]);
+#else
+ if (!compiler->mode32)
+ *buf++ = REX_W;
+ *buf++ = 0xf7;
+ *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2];
+#endif
+#endif
+ switch (op) {
+ case SLJIT_UMUL:
+ *buf |= 4 << 3;
+ break;
+ case SLJIT_SMUL:
+ *buf |= 5 << 3;
+ break;
+ case SLJIT_UDIV:
+ *buf |= 6 << 3;
+ break;
+ case SLJIT_SDIV:
+ *buf |= 7 << 3;
+ break;
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
+ EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0);
+#endif
+ break;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+#define ENCODE_PREFIX(prefix) \
+ do { \
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \
+ FAIL_IF(!code); \
+ INC_CSIZE(1); \
+ *code = (prefix); \
+ } while (0)
+
+static int emit_mov_byte(struct sljit_compiler *compiler, int sign,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ int work_r;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
+#else
+ return emit_load_imm64(compiler, dst, srcw);
+#endif
+ }
+ code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc6;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
+
+ if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (reg_map[src] >= 4) {
+ SLJIT_ASSERT(dst_r == TMP_REGISTER);
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
+ } else
+ dst_r = src;
+#else
+ dst_r = src;
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) {
+ /* src, dst are registers. */
+ SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER);
+ if (reg_map[dst] < 4) {
+ if (dst != src)
+ EMIT_MOV(compiler, dst, 0, src, 0);
+ code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = sign ? 0xbe : 0xb6;
+ }
+ else {
+ if (dst != src)
+ EMIT_MOV(compiler, dst, 0, src, 0);
+ if (sign) {
+ /* shl reg, 24 */
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
+ FAIL_IF(!code);
+ *code |= 0x4 << 3;
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0);
+ FAIL_IF(!code);
+ /* shr/sar reg, 24 */
+ *code |= 0x7 << 3;
+ }
+ else {
+ /* and dst, 0xff */
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0);
+ FAIL_IF(!code);
+ *(code + 1) |= 0x4 << 3;
+ }
+ }
+ return SLJIT_SUCCESS;
+ }
+#endif
+ else {
+ /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = sign ? 0xbe : 0xb6;
+ }
+
+ if (dst & SLJIT_MEM) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst_r == TMP_REGISTER) {
+ /* Find a non-used register, whose reg_map[src] < 4. */
+ if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) {
+ if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4))
+ work_r = SLJIT_TEMPORARY_REG3;
+ else
+ work_r = SLJIT_TEMPORARY_REG2;
+ }
+ else {
+ if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
+ work_r = SLJIT_TEMPORARY_REG1;
+ else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2)
+ work_r = SLJIT_TEMPORARY_REG3;
+ else
+ work_r = SLJIT_TEMPORARY_REG2;
+ }
+
+ if (work_r == SLJIT_TEMPORARY_REG1) {
+ ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
+ FAIL_IF(!code);
+ *code = 0x87;
+ }
+
+ code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x88;
+
+ if (work_r == SLJIT_TEMPORARY_REG1) {
+ ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0);
+ FAIL_IF(!code);
+ *code = 0x87;
+ }
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x88;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x88;
+#endif
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_mov_half(struct sljit_compiler *compiler, int sign,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
+ return SLJIT_SUCCESS; /* Empty instruction. */
+
+ if (src & SLJIT_IMM) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw);
+#else
+ return emit_load_imm64(compiler, dst, srcw);
+#endif
+ }
+ code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0xc7;
+ return SLJIT_SUCCESS;
+ }
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
+
+ if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS))
+ dst_r = src;
+ else {
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = sign ? 0xbf : 0xb7;
+ }
+
+ if (dst & SLJIT_MEM) {
+ code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x89;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_unary(struct sljit_compiler *compiler, int un_index,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == src && dstw == srcw) {
+ /* Same input and output */
+ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ return SLJIT_SUCCESS;
+ }
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= (un_index) << 3;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+}
+
+static int emit_not_with_flags(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0x0b;
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+ code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0);
+ FAIL_IF(!code);
+ *code = 0x0b;
+ return SLJIT_SUCCESS;
+ }
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0x0b;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+}
+
+static int emit_clz(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int dst_r;
+
+ SLJIT_UNUSED_ARG(op);
+ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
+ /* Just set the zero flag. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0xf7;
+ *code |= 0x2 << 3;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0);
+#else
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0);
+#endif
+ FAIL_IF(!code);
+ *code |= 0x5 << 3;
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ src = TMP_REGISTER;
+ srcw = 0;
+ }
+
+ code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xbd;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER)
+ dst_r = dst;
+ else {
+ /* Find an unused temporary register. */
+ if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4))
+ dst_r = SLJIT_TEMPORARY_REG1;
+ else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4))
+ dst_r = SLJIT_TEMPORARY_REG2;
+ else
+ dst_r = SLJIT_TEMPORARY_REG3;
+ EMIT_MOV(compiler, dst, dstw, dst_r, 0);
+ }
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31);
+#else
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2;
+ compiler->mode32 = 0;
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31);
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0x45;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0);
+#else
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0);
+#endif
+ FAIL_IF(!code);
+ *(code + 1) |= 0x6 << 3;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst & SLJIT_MEM) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x87;
+ }
+#else
+ if (dst & SLJIT_MEM)
+ EMIT_MOV(compiler, dst, dstw, TMP_REG2, 0);
+#endif
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ sljit_ub* code;
+ int update = 0;
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ int dst_is_ereg = 0;
+ int src_is_ereg = 0;
+#else
+ #define src_is_ereg 0
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+ CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
+ CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
+
+ if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
+ op = GET_OPCODE(op);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+ SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset);
+ if (op >= SLJIT_MOVU) {
+ update = 1;
+ op -= 7;
+ }
+
+ if (src & SLJIT_IMM) {
+ switch (op) {
+ case SLJIT_MOV_UB:
+ srcw = (unsigned char)srcw;
+ break;
+ case SLJIT_MOV_SB:
+ srcw = (signed char)srcw;
+ break;
+ case SLJIT_MOV_UH:
+ srcw = (unsigned short)srcw;
+ break;
+ case SLJIT_MOV_SH:
+ srcw = (signed short)srcw;
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV_UI:
+ srcw = (unsigned int)srcw;
+ break;
+ case SLJIT_MOV_SI:
+ srcw = (signed int)srcw;
+ break;
+#endif
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg))
+ return emit_mov(compiler, dst, dstw, src, srcw);
+#endif
+ }
+
+ if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) {
+ code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw);
+ FAIL_IF(!code);
+ *code = 0x8d;
+ src &= SLJIT_MEM | 0xf;
+ srcw = 0;
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) {
+ SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG));
+ dst = TMP_REGISTER;
+ }
+#endif
+
+ switch (op) {
+ case SLJIT_MOV:
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ case SLJIT_MOV_UI:
+ case SLJIT_MOV_SI:
+#endif
+ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
+ break;
+ case SLJIT_MOV_UB:
+ FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw));
+ break;
+ case SLJIT_MOV_SB:
+ FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw));
+ break;
+ case SLJIT_MOV_UH:
+ FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw));
+ break;
+ case SLJIT_MOV_SH:
+ FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw));
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV_UI:
+ FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw));
+ break;
+ case SLJIT_MOV_SI:
+ FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw));
+ break;
+#endif
+ }
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REGISTER)
+ return emit_mov(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), dstw, TMP_REGISTER, 0);
+#endif
+
+ if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) {
+ code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = 0x8d;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_NOT:
+ if (SLJIT_UNLIKELY(op & SLJIT_SET_E))
+ return emit_not_with_flags(compiler, dst, dstw, src, srcw);
+ return emit_unary(compiler, 0x2, dst, dstw, src, srcw);
+
+ case SLJIT_NEG:
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_unary(compiler, 0x3, dst, dstw, src, srcw);
+
+ case SLJIT_CLZ:
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_clz(compiler, op, dst, dstw, src, srcw);
+ }
+
+ return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ #undef src_is_ereg
+#endif
+}
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+
+#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
+ if (IS_HALFWORD(immw) || compiler->mode32) { \
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
+ FAIL_IF(!code); \
+ *(code + 1) |= (_op_imm_); \
+ } \
+ else { \
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \
+ FAIL_IF(!code); \
+ *code = (_op_mr_); \
+ }
+
+#define BINARY_EAX_IMM(_op_eax_imm_, immw) \
+ FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw))
+
+#else
+
+#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \
+ code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \
+ FAIL_IF(!code); \
+ *(code + 1) |= (_op_imm_);
+
+#define BINARY_EAX_IMM(_op_eax_imm_, immw) \
+ FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw))
+
+#endif
+
+static int emit_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == src1 && dstw == src1w) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src2w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
+ }
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) {
+ /* Special exception for sljit_emit_cond_value. */
+ code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* Only for cumulative operations. */
+ if (dst == src2 && dstw == src2w) {
+ if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+#else
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src1w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src1w, dst, dstw);
+ }
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* General version. */
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ }
+ else {
+ /* This version requires less memory writing. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_non_cum_binary(struct sljit_compiler *compiler,
+ sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == src1 && dstw == src1w) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(op_eax_imm, src2w);
+ }
+ else {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, dstw);
+ }
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+ code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw);
+ FAIL_IF(!code);
+ *code = op_mr;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ /* General version. */
+ if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, dst, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ }
+ else {
+ /* This version requires less memory writing. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = op_rm;
+ }
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_mul(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+ int dst_r;
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ /* Register destination. */
+ if (dst_r == src1 && !(src2 & SLJIT_IMM)) {
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+ else if (dst_r == src2 && !(src1 & SLJIT_IMM)) {
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+ else if (src1 & SLJIT_IMM) {
+ if (src2 & SLJIT_IMM) {
+ EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w);
+ src2 = dst_r;
+ src2w = 0;
+ }
+
+ if (src1w <= 127 && src1w >= -128) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x6b;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!code);
+ INC_CSIZE(1);
+ *code = (sljit_b)src1w;
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_w*)code = src1w;
+ }
+#else
+ else if (IS_HALFWORD(src1w)) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_hw*)code = (sljit_hw)src1w;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
+ if (dst_r != src2)
+ EMIT_MOV(compiler, dst_r, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+#endif
+ }
+ else if (src2 & SLJIT_IMM) {
+ /* Note: src1 is NOT immediate. */
+
+ if (src2w <= 127 && src2w >= -128) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x6b;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 1);
+ FAIL_IF(!code);
+ INC_CSIZE(1);
+ *code = (sljit_b)src2w;
+ }
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ else {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_w*)code = src2w;
+ }
+#else
+ else if (IS_HALFWORD(src2w)) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x69;
+ code = (sljit_ub*)ensure_buf(compiler, 1 + 4);
+ FAIL_IF(!code);
+ INC_CSIZE(4);
+ *(sljit_hw*)code = (sljit_hw)src2w;
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w);
+ if (dst_r != src1)
+ EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+#endif
+ }
+ else {
+ /* Neither argument is immediate. */
+ if (ADDRESSING_DEPENDS_ON(src2, dst_r))
+ dst_r = TMP_REGISTER;
+ EMIT_MOV(compiler, dst_r, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code++ = 0x0f;
+ *code = 0xaf;
+ }
+
+ if (dst_r == TMP_REGISTER)
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_lea_binary(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+ int dst_r, done = 0;
+
+ /* These cases better be left to handled by normal way. */
+ if (dst == src1 && dstw == src1w)
+ return SLJIT_ERR_UNSUPPORTED;
+ if (dst == src2 && dstw == src2w)
+ return SLJIT_ERR_UNSUPPORTED;
+
+ dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+ /* It is not possible to be both SLJIT_LOCALS_REG. */
+ if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
+ FAIL_IF(!code);
+ *code = 0x8d;
+ done = 1;
+ }
+ }
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w);
+#else
+ if (src2 & SLJIT_IMM) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w);
+#endif
+ FAIL_IF(!code);
+ *code = 0x8d;
+ done = 1;
+ }
+ }
+ else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w);
+#else
+ if (src1 & SLJIT_IMM) {
+ code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w);
+#endif
+ FAIL_IF(!code);
+ *code = 0x8d;
+ done = 1;
+ }
+ }
+
+ if (done) {
+ if (dst_r == TMP_REGISTER)
+ return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+ }
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+static int emit_cmp_binary(struct sljit_compiler *compiler,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(0x3d, src2w);
+ return SLJIT_SUCCESS;
+ }
+
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ if (src2 & SLJIT_IMM) {
+ BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0);
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x3b;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) {
+ code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x39;
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 & SLJIT_IMM) {
+ if (src1 & SLJIT_IMM) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ src1 = TMP_REGISTER;
+ src1w = 0;
+ }
+ BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w);
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x3b;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static int emit_test_binary(struct sljit_compiler *compiler,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) {
+#else
+ if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) {
+#endif
+ BINARY_EAX_IMM(0xa9, src2w);
+ return SLJIT_SUCCESS;
+ }
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) {
+#else
+ if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) {
+#endif
+ BINARY_EAX_IMM(0xa9, src1w);
+ return SLJIT_SUCCESS;
+ }
+
+ if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src2w) || compiler->mode32) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+#endif
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {
+ if (src1 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src1w) || compiler->mode32) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+#endif
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (IS_HALFWORD(src2w) || compiler->mode32) {
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+ }
+ else {
+ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
+ code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+#else
+ code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code = 0xf7;
+#endif
+ }
+ else {
+ code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w);
+ FAIL_IF(!code);
+ *code = 0x85;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static int emit_shift(struct sljit_compiler *compiler,
+ sljit_ub mode,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ sljit_ub* code;
+
+ if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) {
+ if (dst == src1 && dstw == src1w) {
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw);
+ FAIL_IF(!code);
+ *code |= mode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == SLJIT_UNUSED) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ return SLJIT_SUCCESS;
+ }
+ if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+ }
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ return SLJIT_SUCCESS;
+ }
+
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ return SLJIT_SUCCESS;
+ }
+
+ if (dst == SLJIT_PREF_SHIFT_REG) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ }
+ else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
+ if (src1 != dst)
+ EMIT_MOV(compiler, dst, 0, src1, src1w);
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_PREF_SHIFT_REG, 0);
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ }
+ else {
+ /* This case is really difficult, since ecx itself may used for
+ addressing, and we must ensure to work even in that case. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
+#else
+ /* [esp - 4] is reserved for eflags. */
+ EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);
+#endif
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
+ code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
+ FAIL_IF(!code);
+ *code |= mode;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
+#else
+ /* [esp - 4] is reserved for eflags. */
+ EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)));
+#endif
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+static int emit_shift_with_flags(struct sljit_compiler *compiler,
+ sljit_ub mode, int set_flags,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ /* The CPU does not set flags if the shift count is 0. */
+ if (src2 & SLJIT_IMM) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#else
+ if ((src2w & 0x1f) != 0)
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#endif
+ if (!set_flags)
+ return emit_mov(compiler, dst, dstw, src1, src1w);
+ /* OR dst, src, 0 */
+ return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
+ dst, dstw, src1, src1w, SLJIT_IMM, 0);
+ }
+
+ if (!set_flags)
+ return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+
+ if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS))
+ FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
+
+ FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
+
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+ return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ CHECK_ERROR();
+ check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = op & SLJIT_INT_OP;
+#endif
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ CHECK_EXTRA_REGS(src1, src1w, (void)0);
+ CHECK_EXTRA_REGS(src2, src2w, (void)0);
+
+ if (GET_OPCODE(op) >= SLJIT_MUL) {
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ }
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ if (!GET_FLAGS(op)) {
+ if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
+ return compiler->error;
+ }
+ else
+ compiler->flags_saved = 0;
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_ADDC:
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
+ FAIL_IF(emit_restore_flags(compiler, 1));
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
+ FAIL_IF(emit_save_flags(compiler));
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SUB:
+ if (!GET_FLAGS(op)) {
+ if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
+ return compiler->error;
+ }
+ else
+ compiler->flags_saved = 0;
+ if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
+ FAIL_IF(emit_save_flags(compiler));
+ if (dst == SLJIT_UNUSED)
+ return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
+ return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SUBC:
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */
+ FAIL_IF(emit_restore_flags(compiler, 1));
+ else if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS))
+ FAIL_IF(emit_save_flags(compiler));
+ if (SLJIT_UNLIKELY(GET_FLAGS(op)))
+ compiler->flags_saved = 0;
+ return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_MUL:
+ return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_AND:
+ if (dst == SLJIT_UNUSED)
+ return emit_test_binary(compiler, src1, src1w, src2, src2w);
+ return emit_cum_binary(compiler, 0x23, 0x21, 0x4 << 3, 0x25,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_OR:
+ return emit_cum_binary(compiler, 0x0b, 0x09, 0x1 << 3, 0x0d,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_XOR:
+ return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_SHL:
+ return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_LSHR:
+ return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ case SLJIT_ASHR:
+ return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
+ dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg)
+{
+ check_sljit_get_register_index(reg);
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (reg == SLJIT_TEMPORARY_EREG1 || reg == SLJIT_TEMPORARY_EREG2
+ || reg == SLJIT_SAVED_EREG1 || reg == SLJIT_SAVED_EREG2)
+ return -1;
+#endif
+ return reg_map[reg];
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, int size)
+{
+ sljit_ub *buf;
+
+ CHECK_ERROR();
+ check_sljit_emit_op_custom(compiler, instruction, size);
+ SLJIT_ASSERT(size > 0 && size < 16);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
+ FAIL_IF(!buf);
+ INC_SIZE(size);
+ SLJIT_MEMMOVE(buf, instruction, size);
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+static int sse2_available = 0;
+#endif
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+
+/* Alignment + 2 * 16 bytes. */
+static sljit_i sse2_data[3 + 4 + 4];
+static sljit_i *sse2_buffer;
+
+static void init_compiler()
+{
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+ int features = 0;
+#endif
+
+ sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
+ sse2_buffer[0] = 0;
+ sse2_buffer[1] = 0x80000000;
+ sse2_buffer[4] = 0xffffffff;
+ sse2_buffer[5] = 0x7fffffff;
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+#ifdef __GNUC__
+ /* AT&T syntax. */
+ asm (
+ "pushl %%ebx\n"
+ "movl $0x1, %%eax\n"
+ "cpuid\n"
+ "popl %%ebx\n"
+ "movl %%edx, %0\n"
+ : "=g" (features)
+ :
+ : "%eax", "%ecx", "%edx"
+ );
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
+ /* Intel syntax. */
+ __asm {
+ mov eax, 1
+ push ebx
+ cpuid
+ pop ebx
+ mov features, edx
+ }
+#else
+ #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"
+#endif
+ sse2_available = (features >> 26) & 0x1;
+#endif
+}
+
+#endif
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
+{
+ /* Always available. */
+ return 1;
+}
+
+#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+
+static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode,
+ int xmm1, int xmm2, sljit_w xmm2w)
+{
+ sljit_ub *buf;
+
+ buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
+ FAIL_IF(!buf);
+ *buf++ = 0x0f;
+ *buf = opcode;
+ return SLJIT_SUCCESS;
+}
+
+static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode,
+ int xmm1, int xmm2, sljit_w xmm2w)
+{
+ sljit_ub *buf;
+
+ buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w);
+ FAIL_IF(!buf);
+ *buf++ = 0x0f;
+ *buf = opcode;
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler,
+ int dst, int src, sljit_w srcw)
+{
+ return emit_sse2(compiler, 0x10, dst, src, srcw);
+}
+
+static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler,
+ int dst, sljit_w dstw, int src)
+{
+ return emit_sse2(compiler, 0x11, src, dst, dstw);
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ compiler->flags_saved = 0;
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
+ dst_r = dst;
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw));
+ }
+ return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw);
+ }
+
+ if (op == SLJIT_FMOV) {
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4)
+ return emit_sse2_load(compiler, dst, src, srcw);
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4)
+ return emit_sse2_store(compiler, dst, dstw, src);
+ FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw));
+ return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
+ }
+
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
+ dst_r = dst;
+ if (dst != src)
+ FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
+ }
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw));
+ }
+
+ switch (op) {
+ case SLJIT_FNEG:
+ FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer));
+ break;
+
+ case SLJIT_FABS:
+ FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4)));
+ break;
+ }
+
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ int dst_r;
+
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) {
+ dst_r = dst;
+ if (dst == src1)
+ ; /* Do nothing here. */
+ else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) {
+ /* Swap arguments. */
+ src2 = src1;
+ src2w = src1w;
+ }
+ else if (dst != src2)
+ FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w));
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
+ }
+ }
+ else {
+ dst_r = TMP_FREG;
+ FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w));
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_FSUB:
+ FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_FMUL:
+ FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w));
+ break;
+
+ case SLJIT_FDIV:
+ FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w));
+ break;
+ }
+
+ if (dst_r == TMP_FREG)
+ return emit_sse2_store(compiler, dst, dstw, TMP_FREG);
+ return SLJIT_SUCCESS;
+}
+
+#endif
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)
+
+static int emit_fld(struct sljit_compiler *compiler,
+ int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = 0xd9;
+ *buf = 0xc0 + src - 1;
+ return SLJIT_SUCCESS;
+ }
+
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf = 0xdd;
+ return SLJIT_SUCCESS;
+}
+
+static int emit_fop(struct sljit_compiler *compiler,
+ sljit_ub st_arg, sljit_ub st_arg2,
+ sljit_ub m64fp_arg, sljit_ub m64fp_arg2,
+ int src, sljit_w srcw)
+{
+ sljit_ub *buf;
+
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = st_arg;
+ *buf = st_arg2 + src;
+ return SLJIT_SUCCESS;
+ }
+
+ buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!buf);
+ *buf++ = m64fp_arg;
+ *buf |= m64fp_arg2;
+ return SLJIT_SUCCESS;
+}
+
+static int emit_fop_regs(struct sljit_compiler *compiler,
+ sljit_ub st_arg, sljit_ub st_arg2,
+ int src)
+{
+ sljit_ub *buf;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
+ FAIL_IF(!buf);
+ INC_SIZE(2);
+ *buf++ = st_arg;
+ *buf = st_arg2 + src;
+ return SLJIT_SUCCESS;
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+#if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_ub *buf;
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (GET_OPCODE(op) == SLJIT_FCMP) {
+ compiler->flags_saved = 0;
+#if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ FAIL_IF(emit_fld(compiler, dst, dstw));
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xd8, 0xdc, 0x3 << 3, src, srcw));
+
+ /* Copy flags. */
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3);
+ *buf++ = 0xdf;
+ *buf++ = 0xe0;
+ /* Note: lahf is not supported on all x86-64 architectures. */
+ *buf++ = 0x9e;
+ EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
+#else
+ if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {
+ FAIL_IF(emit_fld(compiler, dst, dstw));
+ FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
+ } else {
+ FAIL_IF(emit_fld(compiler, src, srcw));
+ FAIL_IF(emit_fld(compiler, dst + ((dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? 1 : 0), dstw));
+ FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src));
+ FAIL_IF(emit_fop_regs(compiler, 0xdd, 0xd8, 0));
+ }
+#endif
+ return SLJIT_SUCCESS;
+ }
+
+ FAIL_IF(emit_fld(compiler, src, srcw));
+
+ switch (op) {
+ case SLJIT_FNEG:
+ FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0));
+ break;
+ case SLJIT_FABS:
+ FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0));
+ break;
+ }
+
+ FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+
+#if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+#else
+static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,
+#endif
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ CHECK_ERROR();
+ check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 1;
+#endif
+
+ if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) {
+ FAIL_IF(emit_fld(compiler, src2, src2w));
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1));
+ break;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ FAIL_IF(emit_fld(compiler, src1, src1w));
+
+ if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) {
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2));
+ break;
+ }
+ return SLJIT_SUCCESS;
+ }
+
+ switch (op) {
+ case SLJIT_FADD:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w));
+ break;
+ case SLJIT_FSUB:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w));
+ break;
+ case SLJIT_FMUL:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w));
+ break;
+ case SLJIT_FDIV:
+ FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w));
+ break;
+ }
+
+ FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw));
+
+ return SLJIT_SUCCESS;
+}
+#endif
+
+#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src, sljit_w srcw)
+{
+ if (sse2_available)
+ return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);
+ else
+ return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
+ int dst, sljit_w dstw,
+ int src1, sljit_w src1w,
+ int src2, sljit_w src2w)
+{
+ if (sse2_available)
+ return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+ else
+ return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
+}
+
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ sljit_ub *buf;
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_label(compiler);
+
+ /* We should restore the flags before the label,
+ since other taken jumps has their own flags as well. */
+ if (SLJIT_UNLIKELY(compiler->flags_saved))
+ PTR_FAIL_IF(emit_restore_flags(compiler, 0));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!buf);
+
+ *buf++ = 0;
+ *buf++ = 0;
+
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
+{
+ sljit_ub *buf;
+ struct sljit_jump *jump;
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_jump(compiler, type);
+
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) {
+ if ((type & 0xff) <= SLJIT_JUMP)
+ PTR_FAIL_IF(emit_restore_flags(compiler, 0));
+ compiler->flags_saved = 0;
+ }
+
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF_NULL(jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ type &= 0xff;
+
+ if (type >= SLJIT_CALL1)
+ PTR_FAIL_IF(call_with_args(compiler, type));
+
+ /* Worst case size. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
+#else
+ compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
+#endif
+
+ buf = (sljit_ub*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF_NULL(buf);
+
+ *buf++ = 0;
+ *buf++ = type + 4;
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw)
+{
+ sljit_ub *code;
+ struct sljit_jump *jump;
+
+ CHECK_ERROR();
+ check_sljit_emit_ijump(compiler, type, src, srcw);
+
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
+ if (SLJIT_UNLIKELY(compiler->flags_saved)) {
+ if (type <= SLJIT_JUMP)
+ FAIL_IF(emit_restore_flags(compiler, 0));
+ compiler->flags_saved = 0;
+ }
+
+ if (type >= SLJIT_CALL1) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+ if (src == SLJIT_TEMPORARY_REG3) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
+ src = TMP_REGISTER;
+ }
+ if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {
+ if (src & 0xf0) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ src = TMP_REGISTER;
+ }
+ else
+ srcw += sizeof(sljit_w);
+ }
+#else
+ if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {
+ if (src & 0xf0) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);
+ src = TMP_REGISTER;
+ }
+ else
+ srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
+ }
+#endif
+#endif
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
+ if (src == SLJIT_TEMPORARY_REG3) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
+ src = TMP_REGISTER;
+ }
+#endif
+ FAIL_IF(call_with_args(compiler, type));
+ }
+
+ if (src == SLJIT_IMM) {
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF_NULL(jump);
+ set_jump(jump, compiler, JUMP_ADDR);
+ jump->u.target = srcw;
+
+ /* Worst case size. */
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ compiler->size += 5;
+#else
+ compiler->size += 10 + 3;
+#endif
+
+ code = (sljit_ub*)ensure_buf(compiler, 2);
+ FAIL_IF_NULL(code);
+
+ *code++ = 0;
+ *code++ = type + 4;
+ }
+ else {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ /* REX_W is not necessary (src is not immediate). */
+ compiler->mode32 = 1;
+#endif
+ code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
+ FAIL_IF(!code);
+ *code++ = 0xff;
+ *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
+ }
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type)
+{
+ sljit_ub *buf;
+ sljit_ub cond_set = 0;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int reg;
+#endif
+
+ CHECK_ERROR();
+ check_sljit_emit_cond_value(compiler, op, dst, dstw, type);
+
+ if (dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ if (SLJIT_UNLIKELY(compiler->flags_saved))
+ FAIL_IF(emit_restore_flags(compiler, 0));
+
+ switch (type) {
+ case SLJIT_C_EQUAL:
+ case SLJIT_C_FLOAT_EQUAL:
+ cond_set = 0x94;
+ break;
+
+ case SLJIT_C_NOT_EQUAL:
+ case SLJIT_C_FLOAT_NOT_EQUAL:
+ cond_set = 0x95;
+ break;
+
+ case SLJIT_C_LESS:
+ case SLJIT_C_FLOAT_LESS:
+ cond_set = 0x92;
+ break;
+
+ case SLJIT_C_GREATER_EQUAL:
+ case SLJIT_C_FLOAT_GREATER_EQUAL:
+ cond_set = 0x93;
+ break;
+
+ case SLJIT_C_GREATER:
+ case SLJIT_C_FLOAT_GREATER:
+ cond_set = 0x97;
+ break;
+
+ case SLJIT_C_LESS_EQUAL:
+ case SLJIT_C_FLOAT_LESS_EQUAL:
+ cond_set = 0x96;
+ break;
+
+ case SLJIT_C_SIG_LESS:
+ cond_set = 0x9c;
+ break;
+
+ case SLJIT_C_SIG_GREATER_EQUAL:
+ cond_set = 0x9d;
+ break;
+
+ case SLJIT_C_SIG_GREATER:
+ cond_set = 0x9f;
+ break;
+
+ case SLJIT_C_SIG_LESS_EQUAL:
+ cond_set = 0x9e;
+ break;
+
+ case SLJIT_C_OVERFLOW:
+ case SLJIT_C_MUL_OVERFLOW:
+ cond_set = 0x90;
+ break;
+
+ case SLJIT_C_NOT_OVERFLOW:
+ case SLJIT_C_MUL_NOT_OVERFLOW:
+ cond_set = 0x91;
+ break;
+
+ case SLJIT_C_FLOAT_NAN:
+ cond_set = 0x9a;
+ break;
+
+ case SLJIT_C_FLOAT_NOT_NAN:
+ cond_set = 0x9b;
+ break;
+ }
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
+ FAIL_IF(!buf);
+ INC_SIZE(4 + 4);
+ /* Set low register to conditional flag. */
+ *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B;
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0 | reg_lmap[reg];
+ *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R));
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg];
+
+ if (reg == TMP_REGISTER) {
+ if (op == SLJIT_MOV) {
+ compiler->mode32 = 0;
+ EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
+ }
+ else {
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
+ }
+ }
+#else
+ if (op == SLJIT_MOV) {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3 + 3);
+ /* Set low byte to conditional flag. */
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0 | reg_map[dst];
+
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst];
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3 + 3);
+ /* Set al to conditional flag. */
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0;
+
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS)
+ *buf = 0xC0 | (reg_map[dst] << 3);
+ else {
+ *buf = 0xC0;
+ EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0);
+ }
+
+ EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0);
+ }
+ }
+ else {
+ if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0);
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3);
+ FAIL_IF(!buf);
+ INC_SIZE(3);
+
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0 | reg_map[dst];
+ }
+ else {
+ EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0);
+
+ buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1);
+ FAIL_IF(!buf);
+ INC_SIZE(3 + 3 + 1);
+ /* Set al to conditional flag. */
+ *buf++ = 0x0f;
+ *buf++ = cond_set;
+ *buf++ = 0xC0;
+
+ *buf++ = 0x0f;
+ *buf++ = 0xb6;
+ *buf++ = 0xC0;
+
+ *buf++ = 0x90 + reg_map[TMP_REGISTER];
+ }
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+ compiler->skip_checks = 1;
+#endif
+ return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);
+ }
+#endif
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
+{
+ sljit_ub *buf;
+ struct sljit_const *const_;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ int reg;
+#endif
+
+ CHECK_ERROR_PTR();
+ check_sljit_emit_const(compiler, dst, dstw, init_value);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+ PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+ reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
+
+ if (emit_load_imm64(compiler, reg, init_value))
+ return NULL;
+#else
+ if (dst == SLJIT_UNUSED)
+ dst = TMP_REGISTER;
+
+ if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
+ return NULL;
+#endif
+
+ buf = (sljit_ub*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!buf);
+
+ *buf++ = 0;
+ *buf++ = 1;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (reg == TMP_REGISTER && dst != SLJIT_UNUSED)
+ if (emit_mov(compiler, dst, dstw, TMP_REGISTER, 0))
+ return NULL;
+#endif
+
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ *(sljit_w*)addr = new_addr - (addr + 4);
+#else
+ *(sljit_uw*)addr = new_addr;
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
+{
+ *(sljit_w*)addr = new_constant;
+}
diff --git a/src/3rdparty/pcre/sljit/sljitUtils.c b/src/3rdparty/pcre/sljit/sljitUtils.c
new file mode 100644
index 00000000000..98beaa0b5ee
--- /dev/null
+++ b/src/3rdparty/pcre/sljit/sljitUtils.c
@@ -0,0 +1,244 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* ------------------------------------------------------------------------ */
+/* Locks */
+/* ------------------------------------------------------------------------ */
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+#ifdef _WIN32
+
+#include "windows.h"
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+static HANDLE allocator_mutex = 0;
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ /* No idea what to do if an error occures. Static mutexes should never fail... */
+ if (!allocator_mutex)
+ allocator_mutex = CreateMutex(NULL, TRUE, NULL);
+ else
+ WaitForSingleObject(allocator_mutex, INFINITE);
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ ReleaseMutex(allocator_mutex);
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+static HANDLE global_mutex = 0;
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ /* No idea what to do if an error occures. Static mutexes should never fail... */
+ if (!global_mutex)
+ global_mutex = CreateMutex(NULL, TRUE, NULL);
+ else
+ WaitForSingleObject(global_mutex, INFINITE);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ ReleaseMutex(global_mutex);
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#else /* _WIN32 */
+
+#include "pthread.h"
+
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+
+static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static SLJIT_INLINE void allocator_grab_lock(void)
+{
+ pthread_mutex_lock(&allocator_mutex);
+}
+
+static SLJIT_INLINE void allocator_release_lock(void)
+{
+ pthread_mutex_unlock(&allocator_mutex);
+}
+
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
+
+#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+
+static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
+{
+ pthread_mutex_lock(&global_mutex);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
+{
+ pthread_mutex_unlock(&global_mutex);
+}
+
+#endif /* SLJIT_UTIL_GLOBAL_LOCK */
+
+#endif /* _WIN32 */
+
+/* ------------------------------------------------------------------------ */
+/* Stack */
+/* ------------------------------------------------------------------------ */
+
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
+
+#ifdef _WIN32
+#include "windows.h"
+#else
+#include
+#include
+#endif
+
+/* Planning to make it even more clever in the future. */
+static sljit_w sljit_page_align = 0;
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
+{
+ struct sljit_stack *stack;
+ union {
+ void *ptr;
+ sljit_uw uw;
+ } base;
+#ifdef _WIN32
+ SYSTEM_INFO si;
+#endif
+
+ if (limit > max_limit || limit < 1)
+ return NULL;
+
+#ifdef _WIN32
+ if (!sljit_page_align) {
+ GetSystemInfo(&si);
+ sljit_page_align = si.dwPageSize - 1;
+ }
+#else
+ if (!sljit_page_align) {
+ sljit_page_align = sysconf(_SC_PAGESIZE);
+ /* Should never happen. */
+ if (sljit_page_align < 0)
+ sljit_page_align = 4096;
+ sljit_page_align--;
+ }
+#endif
+
+ /* Align limit and max_limit. */
+ max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
+
+ stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack));
+ if (!stack)
+ return NULL;
+
+#ifdef _WIN32
+ base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
+ if (!base.ptr) {
+ SLJIT_FREE(stack);
+ return NULL;
+ }
+ stack->base = base.uw;
+ stack->limit = stack->base;
+ stack->max_limit = stack->base + max_limit;
+ if (sljit_stack_resize(stack, stack->base + limit)) {
+ sljit_free_stack(stack);
+ return NULL;
+ }
+#else
+ base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (base.ptr == MAP_FAILED) {
+ SLJIT_FREE(stack);
+ return NULL;
+ }
+ stack->base = base.uw;
+ stack->limit = stack->base + limit;
+ stack->max_limit = stack->base + max_limit;
+#endif
+ stack->top = stack->base;
+ return stack;
+}
+
+#undef PAGE_ALIGN
+
+SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* stack)
+{
+#ifdef _WIN32
+ VirtualFree((void*)stack->base, 0, MEM_RELEASE);
+#else
+ munmap((void*)stack->base, stack->max_limit - stack->base);
+#endif
+ SLJIT_FREE(stack);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
+{
+ sljit_uw aligned_old_limit;
+ sljit_uw aligned_new_limit;
+
+ if ((new_limit > stack->max_limit) || (new_limit < stack->base))
+ return -1;
+#ifdef _WIN32
+ aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
+ aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
+ if (aligned_new_limit != aligned_old_limit) {
+ if (aligned_new_limit > aligned_old_limit) {
+ if (!VirtualAlloc((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_COMMIT, PAGE_READWRITE))
+ return -1;
+ }
+ else {
+ if (!VirtualFree((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_DECOMMIT))
+ return -1;
+ }
+ }
+ stack->limit = new_limit;
+ return 0;
+#else
+ if (new_limit >= stack->limit) {
+ stack->limit = new_limit;
+ return 0;
+ }
+ aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
+ aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
+ if (aligned_new_limit < aligned_old_limit)
+ madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
+ stack->limit = new_limit;
+ return 0;
+#endif
+}
+
+#endif /* SLJIT_UTIL_STACK */
+
+#endif
diff --git a/src/3rdparty/pcre/ucp.h b/src/3rdparty/pcre/ucp.h
new file mode 100644
index 00000000000..34077fe07e6
--- /dev/null
+++ b/src/3rdparty/pcre/ucp.h
@@ -0,0 +1,165 @@
+/*************************************************
+* Unicode Property Table handler *
+*************************************************/
+
+#ifndef _UCP_H
+#define _UCP_H
+
+/* This file contains definitions of the property values that are returned by
+the UCD access macros. New values that are added for new releases of Unicode
+should always be at the end of each enum, for backwards compatibility. */
+
+/* These are the general character categories. */
+
+enum {
+ ucp_C, /* Other */
+ ucp_L, /* Letter */
+ ucp_M, /* Mark */
+ ucp_N, /* Number */
+ ucp_P, /* Punctuation */
+ ucp_S, /* Symbol */
+ ucp_Z /* Separator */
+};
+
+/* These are the particular character types. */
+
+enum {
+ ucp_Cc, /* Control */
+ ucp_Cf, /* Format */
+ ucp_Cn, /* Unassigned */
+ ucp_Co, /* Private use */
+ ucp_Cs, /* Surrogate */
+ ucp_Ll, /* Lower case letter */
+ ucp_Lm, /* Modifier letter */
+ ucp_Lo, /* Other letter */
+ ucp_Lt, /* Title case letter */
+ ucp_Lu, /* Upper case letter */
+ ucp_Mc, /* Spacing mark */
+ ucp_Me, /* Enclosing mark */
+ ucp_Mn, /* Non-spacing mark */
+ ucp_Nd, /* Decimal number */
+ ucp_Nl, /* Letter number */
+ ucp_No, /* Other number */
+ ucp_Pc, /* Connector punctuation */
+ ucp_Pd, /* Dash punctuation */
+ ucp_Pe, /* Close punctuation */
+ ucp_Pf, /* Final punctuation */
+ ucp_Pi, /* Initial punctuation */
+ ucp_Po, /* Other punctuation */
+ ucp_Ps, /* Open punctuation */
+ ucp_Sc, /* Currency symbol */
+ ucp_Sk, /* Modifier symbol */
+ ucp_Sm, /* Mathematical symbol */
+ ucp_So, /* Other symbol */
+ ucp_Zl, /* Line separator */
+ ucp_Zp, /* Paragraph separator */
+ ucp_Zs /* Space separator */
+};
+
+/* These are the script identifications. */
+
+enum {
+ ucp_Arabic,
+ ucp_Armenian,
+ ucp_Bengali,
+ ucp_Bopomofo,
+ ucp_Braille,
+ ucp_Buginese,
+ ucp_Buhid,
+ ucp_Canadian_Aboriginal,
+ ucp_Cherokee,
+ ucp_Common,
+ ucp_Coptic,
+ ucp_Cypriot,
+ ucp_Cyrillic,
+ ucp_Deseret,
+ ucp_Devanagari,
+ ucp_Ethiopic,
+ ucp_Georgian,
+ ucp_Glagolitic,
+ ucp_Gothic,
+ ucp_Greek,
+ ucp_Gujarati,
+ ucp_Gurmukhi,
+ ucp_Han,
+ ucp_Hangul,
+ ucp_Hanunoo,
+ ucp_Hebrew,
+ ucp_Hiragana,
+ ucp_Inherited,
+ ucp_Kannada,
+ ucp_Katakana,
+ ucp_Kharoshthi,
+ ucp_Khmer,
+ ucp_Lao,
+ ucp_Latin,
+ ucp_Limbu,
+ ucp_Linear_B,
+ ucp_Malayalam,
+ ucp_Mongolian,
+ ucp_Myanmar,
+ ucp_New_Tai_Lue,
+ ucp_Ogham,
+ ucp_Old_Italic,
+ ucp_Old_Persian,
+ ucp_Oriya,
+ ucp_Osmanya,
+ ucp_Runic,
+ ucp_Shavian,
+ ucp_Sinhala,
+ ucp_Syloti_Nagri,
+ ucp_Syriac,
+ ucp_Tagalog,
+ ucp_Tagbanwa,
+ ucp_Tai_Le,
+ ucp_Tamil,
+ ucp_Telugu,
+ ucp_Thaana,
+ ucp_Thai,
+ ucp_Tibetan,
+ ucp_Tifinagh,
+ ucp_Ugaritic,
+ ucp_Yi,
+ /* New for Unicode 5.0: */
+ ucp_Balinese,
+ ucp_Cuneiform,
+ ucp_Nko,
+ ucp_Phags_Pa,
+ ucp_Phoenician,
+ /* New for Unicode 5.1: */
+ ucp_Carian,
+ ucp_Cham,
+ ucp_Kayah_Li,
+ ucp_Lepcha,
+ ucp_Lycian,
+ ucp_Lydian,
+ ucp_Ol_Chiki,
+ ucp_Rejang,
+ ucp_Saurashtra,
+ ucp_Sundanese,
+ ucp_Vai,
+ /* New for Unicode 5.2: */
+ ucp_Avestan,
+ ucp_Bamum,
+ ucp_Egyptian_Hieroglyphs,
+ ucp_Imperial_Aramaic,
+ ucp_Inscriptional_Pahlavi,
+ ucp_Inscriptional_Parthian,
+ ucp_Javanese,
+ ucp_Kaithi,
+ ucp_Lisu,
+ ucp_Meetei_Mayek,
+ ucp_Old_South_Arabian,
+ ucp_Old_Turkic,
+ ucp_Samaritan,
+ ucp_Tai_Tham,
+ ucp_Tai_Viet,
+ /* New for Unicode 6.0.0: */
+ ucp_Batak,
+ ucp_Brahmi,
+ ucp_Mandaic
+};
+
+#endif
+
+/* End of ucp.h */
diff --git a/src/concurrent/qfutureinterface_p.h b/src/concurrent/qfutureinterface_p.h
index 3a73f846ac5..b985e31ab61 100644
--- a/src/concurrent/qfutureinterface_p.h
+++ b/src/concurrent/qfutureinterface_p.h
@@ -80,7 +80,7 @@ public:
QFutureCallOutEvent()
: QEvent(QEvent::FutureCallOut), callOutType(CallOutType(0)), index1(-1), index2(-1)
{ }
- QFutureCallOutEvent(CallOutType callOutType, int index1 = -1)
+ explicit QFutureCallOutEvent(CallOutType callOutType, int index1 = -1)
: QEvent(QEvent::FutureCallOut), callOutType(callOutType), index1(index1), index2(-1)
{ }
QFutureCallOutEvent(CallOutType callOutType, int index1, int index2)
diff --git a/src/concurrent/qtconcurrentexception.cpp b/src/concurrent/qtconcurrentexception.cpp
index caeaa8d9be4..57eb604d39c 100644
--- a/src/concurrent/qtconcurrentexception.cpp
+++ b/src/concurrent/qtconcurrentexception.cpp
@@ -69,10 +69,10 @@ QT_BEGIN_NAMESPACE
When using QFuture, transferred exceptions will be thrown when calling the following functions:
\list
- \o QFuture::waitForFinished()
- \o QFuture::result()
- \o QFuture::resultAt()
- \o QFuture::results()
+ \li QFuture::waitForFinished()
+ \li QFuture::result()
+ \li QFuture::resultAt()
+ \li QFuture::results()
\endlist
*/
diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp
index e51626ed138..656ecf73706 100644
--- a/src/concurrent/qtconcurrentrun.cpp
+++ b/src/concurrent/qtconcurrentrun.cpp
@@ -121,9 +121,9 @@
this:
\list
- \o To call a function that takes more than 5 arguments.
- \o To simplify calling a function with constant arguments.
- \o Changing the order of arguments.
+ \li To call a function that takes more than 5 arguments.
+ \li To simplify calling a function with constant arguments.
+ \li Changing the order of arguments.
\endlist
See the documentation for the relevant functions for details on how to use
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index 67598f4f705..5acc13c6f3d 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -30,6 +30,9 @@ list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE)
set(QT_LIBINFIX \"$${QT_LIBINFIX}\")
!!ENDIF
+set(QT_CONFIG \"$${CONFIG}\")
+set(QT_QCONFIG \"$${QT_CONFIG}\")
+
!!IF !isEmpty(CMAKE_WINDOWS_BUILD)
set(Qt5Core_QTMAIN_LIBRARIES Qt5::WinMain)
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index fc51a20a15a..f7ba49c3cd4 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -92,7 +92,7 @@
#include "qanimationgroup.h"
#include "qpropertyanimation_p.h"
-#include
+#include
#ifndef QT_NO_ANIMATION
@@ -268,7 +268,8 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
QPropertyAnimation *animToStop = 0;
{
#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(&staticMetaObject));
+ static QBasicMutex mutex;
+ QMutexLocker locker(&mutex);
#endif
typedef QPair QPropertyAnimationPair;
typedef QHash QPropertyAnimationHash;
@@ -280,6 +281,7 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
d->updateMetaProperty();
animToStop = hash.value(key, 0);
hash.insert(key, this);
+ locker.unlock();
// update the default start value
if (oldState == Stopped) {
d->setDefaultStartEndValue(d->targetValue->property(d->propertyName.constData()));
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 35a340836d9..59b2d6abf3a 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -45,7 +45,6 @@
#include
#include
#include
-#include
#ifndef QT_NO_ANIMATION
@@ -98,18 +97,18 @@ QT_BEGIN_NAMESPACE
supported QVariant types:
\list
- \o \l{QMetaType::}{Int}
- \o \l{QMetaType::}{Double}
- \o \l{QMetaType::}{Float}
- \o \l{QMetaType::}{QLine}
- \o \l{QMetaType::}{QLineF}
- \o \l{QMetaType::}{QPoint}
- \o \l{QMetaType::}{QPointF}
- \o \l{QMetaType::}{QSize}
- \o \l{QMetaType::}{QSizeF}
- \o \l{QMetaType::}{QRect}
- \o \l{QMetaType::}{QRectF}
- \o \l{QMetaType::}{QColor}
+ \li \l{QMetaType::}{Int}
+ \li \l{QMetaType::}{Double}
+ \li \l{QMetaType::}{Float}
+ \li \l{QMetaType::}{QLine}
+ \li \l{QMetaType::}{QLineF}
+ \li \l{QMetaType::}{QPoint}
+ \li \l{QMetaType::}{QPointF}
+ \li \l{QMetaType::}{QSize}
+ \li \l{QMetaType::}{QSizeF}
+ \li \l{QMetaType::}{QRect}
+ \li \l{QMetaType::}{QRectF}
+ \li \l{QMetaType::}{QColor}
\endlist
If you need to interpolate other variant types, including custom
@@ -399,6 +398,7 @@ void QVariantAnimation::setEasingCurve(const QEasingCurve &easing)
typedef QVector QInterpolatorVector;
Q_GLOBAL_STATIC(QInterpolatorVector, registeredInterpolators)
+static QBasicMutex registeredInterpolatorsMutex;
/*!
\fn void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress))
@@ -435,9 +435,7 @@ void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator fun
// in such an order that we get here with interpolators == NULL,
// to continue causes the app to crash on exit with a SEGV
if (interpolators) {
-#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators));
-#endif
+ QMutexLocker locker(®isteredInterpolatorsMutex);
if (int(interpolationType) >= interpolators->count())
interpolators->resize(int(interpolationType) + 1);
interpolators->replace(interpolationType, func);
@@ -452,14 +450,14 @@ template static inline QVariantAnimation::Interpolator castToInterpo
QVariantAnimation::Interpolator QVariantAnimationPrivate::getInterpolator(int interpolationType)
{
- QInterpolatorVector *interpolators = registeredInterpolators();
-#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators));
-#endif
- QVariantAnimation::Interpolator ret = 0;
- if (interpolationType < interpolators->count()) {
- ret = interpolators->at(interpolationType);
- if (ret) return ret;
+ {
+ QInterpolatorVector *interpolators = registeredInterpolators();
+ QMutexLocker locker(®isteredInterpolatorsMutex);
+ QVariantAnimation::Interpolator ret = 0;
+ if (interpolationType < interpolators->count()) {
+ ret = interpolators->at(interpolationType);
+ if (ret) return ret;
+ }
}
switch(interpolationType)
diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h
index 225a7809eb0..9edb74fa73e 100644
--- a/src/corelib/arch/qatomic_gcc.h
+++ b/src/corelib/arch/qatomic_gcc.h
@@ -84,7 +84,7 @@ template struct QAtomicOps: QGenericAtomicOps >
typedef T Type;
#ifndef __ia64__
- static T loadAcquire(T &_q_value)
+ static T loadAcquire(const T &_q_value)
{
T tmp = _q_value;
__sync_synchronize();
diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h
index d82ad122232..5108751f2ad 100644
--- a/src/corelib/arch/qatomic_ia64.h
+++ b/src/corelib/arch/qatomic_ia64.h
@@ -143,9 +143,9 @@ template struct QBasicAtomicOps: QGenericAtomicOps static inline
- T loadAcquire(T &_q_value)
+ T loadAcquire(const T &_q_value)
{
- return *static_cast(&_q_value);
+ return *static_cast(&_q_value);
}
template static inline
diff --git a/src/corelib/codecs/codecs.qdoc b/src/corelib/codecs/codecs.qdoc
index 2127a0a4cf7..669072f7893 100644
--- a/src/corelib/codecs/codecs.qdoc
+++ b/src/corelib/codecs/codecs.qdoc
@@ -77,9 +77,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -126,9 +126,9 @@
Currently, the Big5-HKSCS tables are generated from the following
sources, and with the Euro character added:
\list 1
- \o \l{http://www.microsoft.com/typography/unicode/950.txt}
- \o \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5-iso.txt}
- \o \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5cmp.txt}
+ \li \l{http://www.microsoft.com/typography/unicode/950.txt}
+ \li \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5-iso.txt}
+ \li \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5cmp.txt}
\endlist
There may be more fine-tuning to the QBig5hkscsCodec to maximize its
@@ -147,9 +147,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -195,9 +195,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -238,9 +238,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -282,9 +282,9 @@
Some must-read documents are:
\list
- \o \l{ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/pdf/GB18030_Summary.pdf}
- \o \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/source/gb18030/gb18030.html}
- \o \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/data/xml/gb-18030-2000.xml}
+ \li \l{ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/pdf/GB18030_Summary.pdf}
+ \li \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/source/gb18030/gb18030.html}
+ \li \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/data/xml/gb-18030-2000.xml}
\endlist
The GBK codec was contributed to Qt by
@@ -316,9 +316,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -354,30 +354,30 @@
\list
- \o "unicode-0.9" or "unicode-0201" for Unicode style. This assumes
+ \li "unicode-0.9" or "unicode-0201" for Unicode style. This assumes
JISX0201 for 0x00-0x7f. (0.9 is a table version of jisx02xx mapping
used for Unicode 1.1.)
- \o "unicode-ascii" This assumes US-ASCII for 0x00-0x7f; some
+ \li "unicode-ascii" This assumes US-ASCII for 0x00-0x7f; some
chars (JISX0208 0x2140 and JISX0212 0x2237) are different from
Unicode 1.1 to avoid conflict.
- \o "open-19970715-0201" ("open-0201" for convenience) or
+ \li "open-19970715-0201" ("open-0201" for convenience) or
"jisx0221-1995" for JISX0221-JISX0201 style. JIS X 0221 is JIS
version of Unicode, but a few chars (0x5c, 0x7e, 0x2140, 0x216f,
0x2131) are different from Unicode 1.1. This is used when 0x5c is
treated as YEN SIGN.
- \o "open-19970715-ascii" ("open-ascii" for convenience) for
+ \li "open-19970715-ascii" ("open-ascii" for convenience) for
JISX0221-ASCII style. This is used when 0x5c is treated as REVERSE
SOLIDUS.
- \o "open-19970715-ms" ("open-ms" for convenience) or "cp932" for
+ \li "open-19970715-ms" ("open-ms" for convenience) or "cp932" for
Microsoft Windows style. Windows Code Page 932. Some chars (0x2140,
0x2141, 0x2142, 0x215d, 0x2171, 0x2172) are different from Unicode
1.1.
- \o "jdk1.1.7" for Sun's JDK style. Same as Unicode 1.1, except that
+ \li "jdk1.1.7" for Sun's JDK style. Same as Unicode 1.1, except that
JIS 0x2140 is mapped to UFF3C. Either ASCII or JISX0201 can be used
for 0x00-0x7f.
@@ -405,9 +405,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -454,9 +454,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
@@ -510,9 +510,9 @@
are met:
\list 1
- \o Redistributions of source code must retain the above copyright
+ \li Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- \o Redistributions in binary form must reproduce the above copyright
+ \li 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.
\endlist
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 68866b90004..13f0ec8ce5a 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -111,7 +111,7 @@ static bool qisalnum(register char c)
static bool nameMatch(const QByteArray &name, const QByteArray &test)
{
// if they're the same, return a perfect score
- if (qstricmp(name, test) == 0)
+ if (qstricmp(name.constData(), test.constData()) == 0)
return true;
const char *n = name.constData();
@@ -145,8 +145,6 @@ static bool destroying_is_ok = false;
#endif
static QTextCodec *localeMapper = 0;
-QTextCodec *QTextCodec::cftr = 0;
-
class QTextCodecCleanup
{
@@ -510,7 +508,7 @@ static QTextCodec * ru_RU_hack(const char * i) {
koi8r, latin5, i);
}
#if !defined(QT_NO_SETLOCALE)
- setlocale(LC_CTYPE, origlocale);
+ setlocale(LC_CTYPE, origlocale.constData());
#endif
return ru_RU_codec;
@@ -648,7 +646,7 @@ static void setupLocaleMapper()
else if (try_locale_list(pt_154locales, lang))
localeMapper = QTextCodec::codecForName("PT 154");
else if (try_locale_list(probably_koi8_rlocales, lang))
- localeMapper = ru_RU_hack(lang);
+ localeMapper = ru_RU_hack(lang.constData());
}
}
@@ -789,38 +787,38 @@ QTextCodec::ConverterState::~ConverterState()
The supported encodings are:
\list
- \o Apple Roman
- \o \l{Big5 Text Codec}{Big5}
- \o \l{Big5-HKSCS Text Codec}{Big5-HKSCS}
- \o CP949
- \o \l{EUC-JP Text Codec}{EUC-JP}
- \o \l{EUC-KR Text Codec}{EUC-KR}
- \o \l{GBK Text Codec}{GB18030-0}
- \o IBM 850
- \o IBM 866
- \o IBM 874
- \o \l{ISO 2022-JP (JIS) Text Codec}{ISO 2022-JP}
- \o ISO 8859-1 to 10
- \o ISO 8859-13 to 16
- \o Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
- \o JIS X 0201
- \o JIS X 0208
- \o KOI8-R
- \o KOI8-U
- \o MuleLao-1
- \o ROMAN8
- \o \l{Shift-JIS Text Codec}{Shift-JIS}
- \o TIS-620
- \o \l{TSCII Text Codec}{TSCII}
- \o UTF-8
- \o UTF-16
- \o UTF-16BE
- \o UTF-16LE
- \o UTF-32
- \o UTF-32BE
- \o UTF-32LE
- \o Windows-1250 to 1258
- \o WINSAMI2
+ \li Apple Roman
+ \li \l{Big5 Text Codec}{Big5}
+ \li \l{Big5-HKSCS Text Codec}{Big5-HKSCS}
+ \li CP949
+ \li \l{EUC-JP Text Codec}{EUC-JP}
+ \li \l{EUC-KR Text Codec}{EUC-KR}
+ \li \l{GBK Text Codec}{GB18030-0}
+ \li IBM 850
+ \li IBM 866
+ \li IBM 874
+ \li \l{ISO 2022-JP (JIS) Text Codec}{ISO 2022-JP}
+ \li ISO 8859-1 to 10
+ \li ISO 8859-13 to 16
+ \li Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
+ \li JIS X 0201
+ \li JIS X 0208
+ \li KOI8-R
+ \li KOI8-U
+ \li MuleLao-1
+ \li ROMAN8
+ \li \l{Shift-JIS Text Codec}{Shift-JIS}
+ \li TIS-620
+ \li \l{TSCII Text Codec}{TSCII}
+ \li UTF-8
+ \li UTF-16
+ \li UTF-16BE
+ \li UTF-16LE
+ \li UTF-32
+ \li UTF-32BE
+ \li UTF-32LE
+ \li Windows-1250 to 1258
+ \li WINSAMI2
\endlist
QTextCodecs can be used as follows to convert some locally encoded
@@ -871,29 +869,29 @@ QTextCodec::ConverterState::~ConverterState()
QTextCodec and implement the functions listed in the table below.
\table
- \header \o Function \o Description
+ \header \li Function \li Description
- \row \o name()
- \o Returns the official name for the encoding. If the
+ \row \li name()
+ \li Returns the official name for the encoding. If the
encoding is listed in the
\l{IANA character-sets encoding file}, the name
should be the preferred MIME name for the encoding.
- \row \o aliases()
- \o Returns a list of alternative names for the encoding.
+ \row \li aliases()
+ \li Returns a list of alternative names for the encoding.
QTextCodec provides a default implementation that returns
an empty list. For example, "ISO-8859-1" has "latin1",
"CP819", "IBM819", and "iso-ir-100" as aliases.
- \row \o mibEnum()
- \o Return the MIB enum for the encoding if it is listed in
+ \row \li mibEnum()
+ \li Return the MIB enum for the encoding if it is listed in
the \l{IANA character-sets encoding file}.
- \row \o convertToUnicode()
- \o Converts an 8-bit character string to Unicode.
+ \row \li convertToUnicode()
+ \li Converts an 8-bit character string to Unicode.
- \row \o convertFromUnicode()
- \o Converts a Unicode string to an 8-bit character string.
+ \row \li convertFromUnicode()
+ \li Converts a Unicode string to an 8-bit character string.
\endtable
\sa QTextStream, QTextDecoder, QTextEncoder, {Codecs Example}
@@ -1463,41 +1461,6 @@ QString QTextDecoder::toUnicode(const QByteArray &ba)
return c->toUnicode(ba.constData(), ba.length(), &state);
}
-
-/*!
- \fn QTextCodec* QTextCodec::codecForTr()
-
- Returns the codec used by QObject::tr() on its argument. If this
- function returns 0 (the default), tr() assumes Latin-1.
-
- \sa setCodecForTr()
-*/
-
-/*!
- \fn void QTextCodec::setCodecForTr(QTextCodec *c)
- \nonreentrant
-
- Sets the codec used by QObject::tr() on its argument to \a c. If
- \a c is 0 (the default), tr() assumes Latin-1.
-
- If the literal quoted text in the program is not in the Latin-1
- encoding, this function can be used to set the appropriate
- encoding. For example, software developed by Korean programmers
- might use eucKR for all the text in the program, in which case the
- main() function might look like this:
-
- \snippet doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp 3
-
- Note that this is not the way to select the encoding that the \e
- user has chosen. For example, to convert an application containing
- literal English strings to Korean, all that is needed is for the
- English strings to be passed through tr() and for translation
- files to be loaded. For details of internationalization, see
- \l{Internationalization with Qt}.
-
- \sa codecForTr()
-*/
-
/*!
\since 4.4
diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h
index ad37005e927..b4b170f7d72 100644
--- a/src/corelib/codecs/qtextcodec.h
+++ b/src/corelib/codecs/qtextcodec.h
@@ -72,9 +72,6 @@ public:
static QTextCodec* codecForLocale();
static void setCodecForLocale(QTextCodec *c);
- static QTextCodec* codecForTr();
- static void setCodecForTr(QTextCodec *c);
-
static QTextCodec *codecForHtml(const QByteArray &ba);
static QTextCodec *codecForHtml(const QByteArray &ba, QTextCodec *defaultCodec);
@@ -129,14 +126,10 @@ protected:
private:
friend class QTextCodecCleanup;
- static QTextCodec *cftr;
static bool validCodecs();
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTextCodec::ConversionFlags)
- inline QTextCodec* QTextCodec::codecForTr() { return validCodecs() ? cftr : 0; }
-inline void QTextCodec::setCodecForTr(QTextCodec *c) { cftr = c; }
-
class Q_CORE_EXPORT QTextEncoder {
Q_DISABLE_COPY(QTextEncoder)
public:
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 6257376b621..09d178639d9 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -892,13 +892,13 @@ bool qSharedBuild()
\brief The QSysInfo class provides information about the system.
\list
- \o \l WordSize specifies the size of a pointer for the platform
+ \li \l WordSize specifies the size of a pointer for the platform
on which the application is compiled.
- \o \l ByteOrder specifies whether the platform is big-endian or
+ \li \l ByteOrder specifies whether the platform is big-endian or
little-endian.
- \o \l WindowsVersion specifies the version of the Windows operating
+ \li \l WindowsVersion specifies the version of the Windows operating
system on which the application is run (Windows only)
- \o \l MacintoshVersion specifies the version of the Macintosh
+ \li \l MacintoshVersion specifies the version of the Macintosh
operating system on which the application is run (Mac only).
\endlist
@@ -2233,9 +2233,7 @@ int qrand()
The macro QT_TR_NOOP_UTF8() is identical except that it tells lupdate
that the source string is encoded in UTF-8. Corresponding variants
- exist in the QT_TRANSLATE_NOOP() family of macros, too. Note that
- using these macros is not required if \c CODECFORTR is already set to
- UTF-8 in the qmake project file.
+ exist in the QT_TRANSLATE_NOOP() family of macros, too.
\sa QT_TRANSLATE_NOOP(), {Internationalization with Qt}
*/
@@ -2462,12 +2460,12 @@ int qrand()
\a Flags can be one of the following:
\list
- \o \c Q_PRIMITIVE_TYPE specifies that \a Type is a POD (plain old
+ \li \c Q_PRIMITIVE_TYPE specifies that \a Type is a POD (plain old
data) type with no constructor or destructor.
- \o \c Q_MOVABLE_TYPE specifies that \a Type has a constructor
+ \li \c Q_MOVABLE_TYPE specifies that \a Type has a constructor
and/or a destructor but can be moved in memory using \c
memcpy().
- \o \c Q_COMPLEX_TYPE (the default) specifies that \a Type has
+ \li \c Q_COMPLEX_TYPE (the default) specifies that \a Type has
constructors and/or a destructor and that it may not be moved
in memory.
\endlist
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 5fbc8cdd199..99328d52acc 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -578,16 +578,6 @@ class QDataStream;
# else
# define Q_SVG_EXPORT Q_DECL_IMPORT
# endif
-# if defined(QT_BUILD_QTQUICK1_LIB)
-# define Q_QTQUICK1_EXPORT Q_DECL_EXPORT
-# else
-# define Q_QTQUICK1_EXPORT Q_DECL_IMPORT
-# endif
-# if defined(QT_BUILD_DECLARATIVE_LIB)
-# define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
-# else
-# define Q_DECLARATIVE_EXPORT Q_DECL_IMPORT
-# endif
# if defined(QT_BUILD_OPENGL_LIB)
# define Q_OPENGL_EXPORT Q_DECL_EXPORT
# else
@@ -648,8 +638,6 @@ class QDataStream;
# define Q_SQL_EXPORT Q_DECL_IMPORT
# define Q_NETWORK_EXPORT Q_DECL_IMPORT
# define Q_SVG_EXPORT Q_DECL_IMPORT
-# define Q_DECLARATIVE_EXPORT Q_DECL_IMPORT
-# define Q_QTQUICK1_EXPORT Q_DECL_IMPORT
# define Q_CANVAS_EXPORT Q_DECL_IMPORT
# define Q_OPENGL_EXPORT Q_DECL_IMPORT
# define Q_MULTIMEDIA_EXPORT Q_DECL_IMPORT
@@ -682,8 +670,6 @@ class QDataStream;
# define Q_SQL_EXPORT Q_DECL_EXPORT
# define Q_NETWORK_EXPORT Q_DECL_EXPORT
# define Q_SVG_EXPORT Q_DECL_EXPORT
-# define Q_DECLARATIVE_EXPORT Q_DECL_EXPORT
-# define Q_QTQUICK1_EXPORT Q_DECL_EXPORT
# define Q_OPENGL_EXPORT Q_DECL_EXPORT
# define Q_MULTIMEDIA_EXPORT Q_DECL_EXPORT
# define Q_OPENVG_EXPORT Q_DECL_EXPORT
@@ -702,8 +688,6 @@ class QDataStream;
# define Q_SQL_EXPORT
# define Q_NETWORK_EXPORT
# define Q_SVG_EXPORT
-# define Q_DECLARATIVE_EXPORT
-# define Q_QTQUICK1_EXPORT
# define Q_OPENGL_EXPORT
# define Q_MULTIMEDIA_EXPORT
# define Q_OPENVG_EXPORT
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index c8716753345..cb4e0e753f6 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -46,11 +46,7 @@
#include "qlibraryinfo.h"
#include "qscopedpointer.h"
-#if defined(QT_BUILD_QMAKE) || defined(QT_BOOTSTRAPPED)
-# define BOOTSTRAPPING
-#endif
-
-#ifdef BOOTSTRAPPING
+#ifdef QT_BUILD_QMAKE
QT_BEGIN_NAMESPACE
extern QString qmake_libraryInfoFile();
QT_END_NAMESPACE
@@ -97,7 +93,7 @@ public:
QLibrarySettings::QLibrarySettings()
: settings(QLibraryInfoPrivate::findConfiguration())
{
-#ifndef BOOTSTRAPPING
+#ifndef QT_BUILD_QMAKE
qAddPostRoutine(QLibraryInfoPrivate::cleanup);
#endif
}
@@ -105,7 +101,7 @@ QLibrarySettings::QLibrarySettings()
QSettings *QLibraryInfoPrivate::findConfiguration()
{
QString qtconfig = QLatin1String(":/qt/etc/qt.conf");
-#ifdef BOOTSTRAPPING
+#ifdef QT_BUILD_QMAKE
if(!QFile::exists(qtconfig))
qtconfig = qmake_libraryInfoFile();
#else
@@ -152,6 +148,8 @@ QSettings *QLibraryInfoPrivate::findConfiguration()
\sa QSysInfo, {Using qt.conf}
*/
+#ifndef QT_BUILD_QMAKE
+
/*! \internal
You cannot create a QLibraryInfo, instead only the static functions are available to query
@@ -214,135 +212,82 @@ QLibraryInfo::isDebugBuild()
return false;
}
+#endif // QT_BUILD_QMAKE
+
+static const struct {
+ char key[14], value[13];
+} qtConfEntries[] = {
+ { "Prefix", "" },
+ { "Documentation", "doc" },
+ { "Headers", "include" },
+ { "Libraries", "lib" },
+ { "Binaries", "bin" },
+ { "Plugins", "plugins" },
+ { "Imports", "imports" },
+ { "Data", "" },
+ { "Translations", "translations" },
+ { "Examples", "examples" },
+ { "Tests", "tests" },
+#ifdef QT_BUILD_QMAKE
+ { "Sysroot", "" },
+ { "HostPrefix", "" },
+ { "HostBinaries", "bin" },
+ { "HostData", "" },
+#endif
+};
+
/*!
Returns the location specified by \a loc.
*/
-
QString
QLibraryInfo::location(LibraryLocation loc)
{
+#ifdef QT_BUILD_QMAKE
+ QString ret = rawLocation(loc);
+
+ // Automatically prepend the sysroot to target paths
+ if (loc < SysrootPath || loc > LastHostPath) {
+ QString sysroot = rawLocation(SysrootPath);
+ if (!sysroot.isEmpty() && ret.length() > 2 && ret.at(1) == QLatin1Char(':')
+ && (ret.at(2) == QLatin1Char('/') || ret.at(2) == QLatin1Char('\\')))
+ ret.replace(0, 2, sysroot); // Strip out the drive on Windows targets
+ else
+ ret.prepend(sysroot);
+ }
+
+ return ret;
+}
+
+QString
+QLibraryInfo::rawLocation(LibraryLocation loc)
+{
+#else
+# define rawLocation location
+#endif
QString ret;
if(!QLibraryInfoPrivate::configuration()) {
const char *path = 0;
- switch (loc) {
-#ifdef QT_CONFIGURE_PREFIX_PATH
- case PrefixPath:
- path = QT_CONFIGURE_PREFIX_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_DOCUMENTATION_PATH
- case DocumentationPath:
- path = QT_CONFIGURE_DOCUMENTATION_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_HEADERS_PATH
- case HeadersPath:
- path = QT_CONFIGURE_HEADERS_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_LIBRARIES_PATH
- case LibrariesPath:
- path = QT_CONFIGURE_LIBRARIES_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_BINARIES_PATH
- case BinariesPath:
- path = QT_CONFIGURE_BINARIES_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_PLUGINS_PATH
- case PluginsPath:
- path = QT_CONFIGURE_PLUGINS_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_IMPORTS_PATH
- case ImportsPath:
- path = QT_CONFIGURE_IMPORTS_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_DATA_PATH
- case DataPath:
- path = QT_CONFIGURE_DATA_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_TRANSLATIONS_PATH
- case TranslationsPath:
- path = QT_CONFIGURE_TRANSLATIONS_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_SETTINGS_PATH
- case SettingsPath:
+ if (loc >= 0 && loc < sizeof(qt_configure_prefix_path_strs)/sizeof(qt_configure_prefix_path_strs[0]))
+ path = qt_configure_prefix_path_strs[loc] + 12;
+#ifndef Q_OS_WIN // On Windows we use the registry
+ else if (loc == SettingsPath)
path = QT_CONFIGURE_SETTINGS_PATH;
- break;
#endif
-#ifdef QT_CONFIGURE_EXAMPLES_PATH
- case ExamplesPath:
- path = QT_CONFIGURE_EXAMPLES_PATH;
- break;
-#endif
-#ifdef QT_CONFIGURE_TESTS_PATH
- case TestsPath:
- path = QT_CONFIGURE_TESTS_PATH;
- break;
-#endif
- default:
- break;
- }
if (path)
ret = QString::fromLocal8Bit(path);
} else {
QString key;
QString defaultValue;
- switch(loc) {
- case PrefixPath:
- key = QLatin1String("Prefix");
- break;
- case DocumentationPath:
- key = QLatin1String("Documentation");
- defaultValue = QLatin1String("doc");
- break;
- case HeadersPath:
- key = QLatin1String("Headers");
- defaultValue = QLatin1String("include");
- break;
- case LibrariesPath:
- key = QLatin1String("Libraries");
- defaultValue = QLatin1String("lib");
- break;
- case BinariesPath:
- key = QLatin1String("Binaries");
- defaultValue = QLatin1String("bin");
- break;
- case PluginsPath:
- key = QLatin1String("Plugins");
- defaultValue = QLatin1String("plugins");
- break;
- case ImportsPath:
- key = QLatin1String("Imports");
- defaultValue = QLatin1String("imports");
- break;
- case DataPath:
- key = QLatin1String("Data");
- break;
- case TranslationsPath:
- key = QLatin1String("Translations");
- defaultValue = QLatin1String("translations");
- break;
- case SettingsPath:
- key = QLatin1String("Settings");
- break;
- case ExamplesPath:
- key = QLatin1String("Examples");
- break;
- case TestsPath:
- key = QLatin1String("Tests");
- defaultValue = QLatin1String("tests");
- break;
- default:
- break;
+ if (loc >= 0 && loc < sizeof(qtConfEntries)/sizeof(qtConfEntries[0])) {
+ key = QLatin1String(qtConfEntries[loc].key);
+ defaultValue = QLatin1String(qtConfEntries[loc].value);
}
+#ifndef Q_OS_WIN // On Windows we use the registry
+ else if (loc == SettingsPath)
+ key = QLatin1String("Settings");
+#endif
if(!key.isNull()) {
QSettings *config = QLibraryInfoPrivate::configuration();
@@ -366,11 +311,19 @@ QLibraryInfo::location(LibraryLocation loc)
if (QDir::isRelativePath(ret)) {
QString baseDir;
- if (loc == PrefixPath) {
- // we make the prefix path absolute to the executable's directory
-#ifdef BOOTSTRAPPING
+#ifdef QT_BUILD_QMAKE
+ if (loc == HostPrefixPath || loc == PrefixPath) {
+ // We make the prefix path absolute to the executable's directory.
+ // loc == PrefixPath while a sysroot is set would make no sense here.
baseDir = QFileInfo(qmake_libraryInfoFile()).absolutePath();
+ } else if (loc == SysrootPath) {
+ // The sysroot is bare
+ return ret;
+ } else if (loc > SysrootPath && loc <= LastHostPath) {
+ // We make any other host path absolute to the host prefix directory.
+ baseDir = rawLocation(HostPrefixPath);
#else
+ if (loc == PrefixPath) {
if (QCoreApplication::instance()) {
#ifdef Q_OS_MAC
CFBundleRef bundleRef = CFBundleGetMainBundle();
@@ -382,6 +335,7 @@ QLibraryInfo::location(LibraryLocation loc)
}
}
#endif
+ // We make the prefix path absolute to the executable's directory.
baseDir = QCoreApplication::applicationDirPath();
} else {
baseDir = QDir::currentPath();
@@ -389,7 +343,7 @@ QLibraryInfo::location(LibraryLocation loc)
#endif
} else {
// we make any other path absolute to the prefix directory
- baseDir = location(PrefixPath);
+ baseDir = rawLocation(PrefixPath);
}
ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret);
}
@@ -413,9 +367,9 @@ QLibraryInfo::location(LibraryLocation loc)
\value ImportsPath The location of installed QML extensions to import.
\value DataPath The location of general Qt data.
\value TranslationsPath The location of translation information for Qt strings.
- \value SettingsPath The location for Qt settings.
\value ExamplesPath The location for examples upon install.
\value TestsPath The location of installed Qt testcases.
+ \value SettingsPath The location for Qt settings. Not applicable on Windows.
\sa location()
*/
@@ -443,9 +397,9 @@ void qt_core_boilerplate()
"Library path: %s\n"
"Include path: %s\n",
qt_configure_installation + 12,
- qt_configure_prefix_path_str + 12,
- qt_configure_libraries_path_str + 12,
- qt_configure_headers_path_str + 12);
+ qt_configure_prefix_path_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::PrefixPath] + 12,
+ qt_configure_prefix_path_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::LibrariesPath] + 12,
+ qt_configure_prefix_path_strs[QT_PREPEND_NAMESPACE(QLibraryInfo)::HeadersPath] + 12);
QT_PREPEND_NAMESPACE(qDumpCPUFeatures)();
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 66f3d407920..d180e631981 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -66,20 +66,32 @@ public:
enum LibraryLocation
{
- PrefixPath,
+ PrefixPath = 0,
DocumentationPath,
HeadersPath,
LibrariesPath,
BinariesPath,
PluginsPath,
+ ImportsPath,
DataPath,
TranslationsPath,
- SettingsPath,
ExamplesPath,
- ImportsPath,
- TestsPath
+ TestsPath,
+ // Insert new values above this line
+#ifdef QT_BUILD_QMAKE
+ // These are not subject to binary compatibility constraints
+ SysrootPath,
+ HostPrefixPath,
+ HostBinariesPath,
+ HostDataPath,
+ LastHostPath = HostDataPath,
+#endif
+ SettingsPath = 100
};
static QString location(LibraryLocation); // ### Qt 5: consider renaming it to path()
+#ifdef QT_BUILD_QMAKE
+ static QString rawLocation(LibraryLocation);
+#endif
private:
QLibraryInfo();
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index badccc947da..8cbd4528dc5 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -309,7 +309,7 @@ QDebug QMessageLogger::critical()
message handler has been installed, the message is printed to
stderr. Under Windows, the message is sent to the debugger.
- If you are using the \bold{default message handler} this function will
+ If you are using the \b{default message handler} this function will
abort on Unix systems to create a core dump. On Windows, for debug builds,
this function will report a _CRT_ERROR enabling you to connect a debugger
to the application.
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 895feb7f534..1df36f42e6f 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -266,7 +266,7 @@
This enum provides shorter names for the keyboard modifier keys
supported by Qt.
- \bold{Note:} On Mac OS X, the \c CTRL value corresponds to
+ \b{Note:} On Mac OS X, the \c CTRL value corresponds to
the Command keys on the Macintosh keyboard, and the \c META value
corresponds to the Control keys.
@@ -319,21 +319,21 @@
\table
\row
- \o \inlineimage qpen-solid.png
- \o \inlineimage qpen-dash.png
- \o \inlineimage qpen-dot.png
+ \li \inlineimage qpen-solid.png
+ \li \inlineimage qpen-dash.png
+ \li \inlineimage qpen-dot.png
\row
- \o Qt::SolidLine
- \o Qt::DashLine
- \o Qt::DotLine
+ \li Qt::SolidLine
+ \li Qt::DashLine
+ \li Qt::DotLine
\row
- \o \inlineimage qpen-dashdot.png
- \o \inlineimage qpen-dashdotdot.png
- \o \inlineimage qpen-custom.png
+ \li \inlineimage qpen-dashdot.png
+ \li \inlineimage qpen-dashdotdot.png
+ \li \inlineimage qpen-custom.png
\row
- \o Qt::DashDotLine
- \o Qt::DashDotDotLine
- \o Qt::CustomDashLine
+ \li Qt::DashDotLine
+ \li Qt::DashDotDotLine
+ \li Qt::CustomDashLine
\endtable
\value NoPen no line at all. For example, QPainter::drawRect()
@@ -360,13 +360,13 @@
\table
\row
- \o \inlineimage qpen-square.png
- \o \inlineimage qpen-flat.png
- \o \inlineimage qpen-roundcap.png
+ \li \inlineimage qpen-square.png
+ \li \inlineimage qpen-flat.png
+ \li \inlineimage qpen-roundcap.png
\row
- \o Qt::SquareCap
- \o Qt::FlatCap
- \o Qt::RoundCap
+ \li Qt::SquareCap
+ \li Qt::FlatCap
+ \li Qt::RoundCap
\endtable
\value FlatCap a square line end that does not cover the end
@@ -388,13 +388,13 @@
\table
\row
- \o \inlineimage qpen-bevel.png
- \o \inlineimage qpen-miter.png
- \o \inlineimage qpen-roundjoin.png
+ \li \inlineimage qpen-bevel.png
+ \li \inlineimage qpen-miter.png
+ \li \inlineimage qpen-roundjoin.png
\row
- \o Qt::BevelJoin
- \o Qt::MiterJoin
- \o Qt::RoundJoin
+ \li Qt::BevelJoin
+ \li Qt::MiterJoin
+ \li Qt::RoundJoin
\endtable
\value MiterJoin The outer edges of the lines are extended to
@@ -968,7 +968,7 @@
\value WA_NoSystemBackground Indicates that the widget has no background,
i.e. when the widget receives paint events, the background is not
automatically repainted. \note Unlike WA_OpaquePaintEvent, newly exposed
- areas are \bold never filled with the background (e.g., after showing a
+ areas are \b never filled with the background (e.g., after showing a
window for the first time the user can see "through" it until the
application processes the paint events). This flag is set or cleared by the
widget's author.
@@ -2653,7 +2653,7 @@
\value ElideNone Ellipsis should NOT appear in the text.
Qt::ElideMiddle is normally the most appropriate choice for URLs (e.g.,
- "\l{http://bugreports.qt.nokia.com/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"),
+ "\l{http://bugreports.qt-project.org/browse/QTWEBSITE-13}{http://bugreports.qt.../QTWEBSITE-13/}"),
whereas Qt::ElideRight is appropriate
for other strings (e.g.,
"\l{http://qt.nokia.com/doc/qq/qq09-mac-deployment.html}{Deploying Applications on Ma...}").
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 6b5ecf73e11..851c18203d4 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -61,63 +61,43 @@ QT_BEGIN_NAMESPACE
static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_inf_bytes = { { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } };
static inline double qt_inf()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_inf_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_inf_bytes.d
: qt_le_inf_bytes.d);
-#endif
}
// Signaling NAN
static const union { unsigned char c[8]; double d; } qt_be_snan_bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_snan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_snan_bytes = { { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 } };
static inline double qt_snan()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_snan_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_snan_bytes.d
: qt_le_snan_bytes.d);
-#endif
}
// Quiet NAN
static const union { unsigned char c[8]; double d; } qt_be_qnan_bytes = { { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 } };
static const union { unsigned char c[8]; double d; } qt_le_qnan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0xff } };
-static const union { unsigned char c[8]; double d; } qt_armfpa_qnan_bytes = { { 0, 0, 0xf8, 0xff, 0, 0, 0, 0 } };
static inline double qt_qnan()
{
-#ifdef QT_ARMFPA
- return qt_armfpa_qnan_bytes.d;
-#else
return (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_qnan_bytes.d
: qt_le_qnan_bytes.d);
-#endif
}
#else // Q_CC_MIPS
static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
-static const unsigned char qt_armfpa_inf_bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
static inline double qt_inf()
{
const unsigned char *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_inf_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_inf_bytes
: qt_le_inf_bytes);
-#endif
union { unsigned char c[8]; double d; } returnValue;
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
@@ -127,17 +107,12 @@ static inline double qt_inf()
// Signaling NAN
static const unsigned char qt_be_snan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_snan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
-static const unsigned char qt_armfpa_snan_bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
static inline double qt_snan()
{
const unsigned char *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_snan_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_snan_bytes
: qt_le_snan_bytes);
-#endif
union { unsigned char c[8]; double d; } returnValue;
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
@@ -147,17 +122,12 @@ static inline double qt_snan()
// Quiet NAN
static const unsigned char qt_be_qnan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 };
static const unsigned char qt_le_qnan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff };
-static const unsigned char qt_armfpa_qnan_bytes[] = { 0, 0, 0xf8, 0xff, 0, 0, 0, 0 };
static inline double qt_qnan()
{
const unsigned char *bytes;
-#ifdef QT_ARMFPA
- bytes = qt_armfpa_qnan_bytes;
-#else
bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian
? qt_be_qnan_bytes
: qt_le_qnan_bytes);
-#endif
union { unsigned char c[8]; double d; } returnValue;
qMemCopy(returnValue.c, bytes, sizeof(returnValue.c));
@@ -169,43 +139,31 @@ static inline double qt_qnan()
static inline bool qt_is_inf(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return (ch[3] & 0x7f) == 0x7f && ch[2] == 0xf0;
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return (ch[0] & 0x7f) == 0x7f && ch[1] == 0xf0;
} else {
return (ch[7] & 0x7f) == 0x7f && ch[6] == 0xf0;
}
-#endif
}
static inline bool qt_is_nan(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return (ch[3] & 0x7f) == 0x7f && ch[2] > 0xf0;
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return (ch[0] & 0x7f) == 0x7f && ch[1] > 0xf0;
} else {
return (ch[7] & 0x7f) == 0x7f && ch[6] > 0xf0;
}
-#endif
}
static inline bool qt_is_finite(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return (ch[3] & 0x7f) != 0x7f || (ch[2] & 0xf0) != 0xf0;
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return (ch[0] & 0x7f) != 0x7f || (ch[1] & 0xf0) != 0xf0;
} else {
return (ch[7] & 0x7f) != 0x7f || (ch[6] & 0xf0) != 0xf0;
}
-#endif
}
static inline bool qt_is_inf(float d)
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index fd02f0e4c52..1f16f090a91 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -53,16 +53,39 @@
The first is always defined. Defines for the various revisions/variants are
optional and usually dependent on how the compiler was invoked. Variants
that are a superset of another should have a define for the superset.
+
+ In addition to the procesor family, variants, and revisions, we also set
+ Q_BYTE_ORDER appropriately for the target processor. For bi-endian
+ processors, we try to auto-detect the byte order using the __BIG_ENDIAN__,
+ __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros.
*/
+/* Machine byte-order, reuse preprocessor provided macros when available */
+#if defined(__ORDER_BIG_ENDIAN__)
+# define Q_BIG_ENDIAN __ORDER_BIG_ENDIAN__
+#else
+# define Q_BIG_ENDIAN 4321
+#endif
+#if defined(__ORDER_LITTLE_ENDIAN__)
+# define Q_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
+#else
+# define Q_LITTLE_ENDIAN 1234
+#endif
+
/*
Alpha family, no revisions or variants
+
+ Alpha is bi-endian, use endianness auto-detection described above.
*/
// #elif defined(__alpha__) || defined(_M_ALPHA)
// # define Q_PROCESSOR_ALPHA
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
- ARM family, known revisions: V5, V6, and V7
+ ARM family, known revisions: V5, V6, and V7
+
+ ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to
+ auto-detection described above.
*/
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
# define Q_PROCESSOR_ARM
@@ -70,7 +93,7 @@
|| defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) \
|| defined(__ARM_ARCH_7M__) \
- || (__TARGET_ARCH_ARM-0 >= 7)
+ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
# define Q_PROCESSOR_ARM_V7
# define Q_PROCESSOR_ARM_V6
# define Q_PROCESSOR_ARM_V5
@@ -81,44 +104,66 @@
|| defined(__ARM_ARCH_6K__) \
|| defined(__ARM_ARCH_6ZK__) \
|| defined(__ARM_ARCH_6M__) \
- || (__TARGET_ARCH_ARM-0 >= 6)
+ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
# define Q_PROCESSOR_ARM_V6
# define Q_PROCESSOR_ARM_V5
# elif defined(__ARM_ARCH_5TEJ__) \
- || (__TARGET_ARCH_ARM-0 >= 5)
+ || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
# define Q_PROCESSOR_ARM_V5
# endif
+# if defined(__ARMEL__)
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+# elif defined(__ARMEB__)
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
+# else
+// Q_BYTE_ORDER not defined, use endianness auto-detection
+#endif
/*
AVR32 family, no revisions or variants
+
+ AVR32 is big-endian.
*/
// #elif defined(__avr32__)
// # define Q_PROCESSOR_AVR32
+// # define Q_BYTE_ORDER Q_BIG_ENDIAN
/*
Blackfin family, no revisions or variants
+
+ Blackfin is little-endian.
*/
// #elif defined(__bfin__)
// # define Q_PROCESSOR_BLACKFIN
+// # define Q_BYTE_ORDER Q_LITTLE_ENDIAN
/*
X86 family, known variants: 32- and 64-bit
+
+ X86 is little-endian.
*/
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
# define Q_PROCESSOR_X86
# define Q_PROCESSOR_X86_32
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
# define Q_PROCESSOR_X86
# define Q_PROCESSOR_X86_64
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
/*
Itanium (IA-64) family, no revisions or variants
+
+ Itanium is bi-endian, use endianness auto-detection described above.
*/
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
# define Q_PROCESSOR_IA64
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
MIPS family, known revisions: I, II, III, IV, 32, 64
+
+ MIPS is bi-endian, use endianness auto-detection described above.
*/
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
# define Q_PROCESSOR_MIPS
@@ -143,6 +188,7 @@
# if defined(_MIPS_ARCH_MIPS64) || defined(__mips64)
# define Q_PROCESSOR_MIPS_64
# endif
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
Power family, known variants: 32- and 64-bit
@@ -150,6 +196,8 @@
There are many more known variants/revisions that we do not handle/detect.
See http://en.wikipedia.org/wiki/Power_Architecture
and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg
+
+ Power is bi-endian, use endianness auto-detection described above.
*/
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \
@@ -160,34 +208,60 @@
# else
# define Q_PROCESSOR_POWER_32
# endif
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
S390 family, known variant: S390X (64-bit)
+
+ S390 is big-endian.
*/
// #elif defined(__s390__)
// # define Q_PROCESSOR_S390
// # if defined(__s390x__)
// # define Q_PROCESSOR_S390_X
// # endif
+// # define Q_BYTE_ORDER Q_BIG_ENDIAN
/*
SuperH family, optional revision: SH-4A
+
+ SuperH is bi-endian, use endianness auto-detection descrived above.
*/
// #elif defined(__sh__)
// # define Q_PROCESSOR_SH
// # if defined(__sh4a__)
// # define Q_PROCESSOR_SH_4A
// # endif
+// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
SPARC family, optional revision: V9
+
+ SPARC is big-endian only prior to V9, while V9 is bi-endian with big-endian
+ as the default byte order. Assume all SPARC systems are big-endian.
*/
// #elif defined(__sparc__)
// # define Q_PROCESSOR_SPARC
// # if defined(__sparc_v9__)
// # define Q_PROCESSOR_SPARC_V9
// # endif
+// # define Q_BYTE_ORDER Q_BIG_ENDIAN
#endif
+// Some processors support either endian format, try to detect which we are using.
+#if !defined(Q_BYTE_ORDER)
+# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN)
+// Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults
+# define Q_BYTE_ORDER __BYTE_ORDER__
+# elif defined(__BIG_ENDIAN__)
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
+# elif defined(__LITTLE_ENDIAN__) \
+ || defined(Q_OS_WINCE) // Windows CE is always little-endian according to MSDN.
+# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+# else
+# error "Unable to determine byte order!"
+# endif
+#endif
+
#endif // QPROCESSORDETECTION_H
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 6297b35b9ce..1c08bbe1cf7 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -49,15 +49,12 @@ QT_BEGIN_NAMESPACE
/*
QTypeInfo - type trait functionality
- qIsDetached - data sharing functionality
*/
/*
The catch-all template.
*/
-template inline bool qIsDetached(T &) { return true; }
-
template
class QTypeInfo
{
@@ -161,6 +158,10 @@ public: \
template<> \
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
+/* Specialize QTypeInfo for QFlags */
+template class QFlags;
+template
+Q_DECLARE_TYPEINFO_BODY(QFlags, Q_PRIMITIVE_TYPE);
/*
Specialize a shared type with:
@@ -184,7 +185,6 @@ QT_BEGIN_NAMESPACE
#endif
#define Q_DECLARE_SHARED(TYPE) \
-template <> inline bool qIsDetached(TYPE &t) { return t.isDetached(); } \
template <> inline void qSwap(TYPE &value1, TYPE &value2) \
{ qSwap(value1.data_ptr(), value2.data_ptr()); } \
Q_DECLARE_SHARED_STL(TYPE)
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 29599295ad1..9c117abe037 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -11,6 +11,8 @@ HEADERS += \
io/qdir_p.h \
io/qdiriterator.h \
io/qfile.h \
+ io/qfiledevice.h \
+ io/qfiledevice_p.h \
io/qfileinfo.h \
io/qfileinfo_p.h \
io/qiodevice.h \
@@ -49,6 +51,7 @@ SOURCES += \
io/qdir.cpp \
io/qdiriterator.cpp \
io/qfile.cpp \
+ io/qfiledevice.cpp \
io/qfileinfo.cpp \
io/qiodevice.cpp \
io/qnoncontiguousbytedevice.cpp \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 7920d881b42..1fe2a793a65 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -184,7 +184,7 @@ QT_BEGIN_NAMESPACE
\endcode
To see if your favorite Qt class has similar stream operators
- defined, check the \bold {Related Non-Members} section of the
+ defined, check the \b {Related Non-Members} section of the
class's documentation page.
\sa QTextStream QVariant
@@ -571,19 +571,19 @@ void QDataStream::setByteOrder(ByteOrder bo)
serialization format used by QDataStream.
\table
- \header \i Qt Version \i QDataStream Version
- \row \i Qt 4.6 \i 12
- \row \i Qt 4.5 \i 11
- \row \i Qt 4.4 \i 10
- \row \i Qt 4.3 \i 9
- \row \i Qt 4.2 \i 8
- \row \i Qt 4.0, 4.1 \i 7
- \row \i Qt 3.3 \i 6
- \row \i Qt 3.1, 3.2 \i 5
- \row \i Qt 3.0 \i 4
- \row \i Qt 2.1, 2.2, 2.3 \i 3
- \row \i Qt 2.0 \i 2
- \row \i Qt 1.x \i 1
+ \header \li Qt Version \li QDataStream Version
+ \row \li Qt 4.6 \li 12
+ \row \li Qt 4.5 \li 11
+ \row \li Qt 4.4 \li 10
+ \row \li Qt 4.3 \li 9
+ \row \li Qt 4.2 \li 8
+ \row \li Qt 4.0, 4.1 \li 7
+ \row \li Qt 3.3 \li 6
+ \row \li Qt 3.1, 3.2 \li 5
+ \row \li Qt 3.0 \li 4
+ \row \li Qt 2.1, 2.2, 2.3 \li 3
+ \row \li Qt 2.0 \li 2
+ \row \li Qt 1.x \li 1
\endtable
The \l Version enum provides symbolic constants for the different
@@ -771,10 +771,6 @@ QDataStream &QDataStream::operator>>(float &f)
return *this;
}
-#if defined(Q_DOUBLE_FORMAT)
-#define Q_DF(x) Q_DOUBLE_FORMAT[(x)] - '0'
-#endif
-
/*!
\overload
@@ -797,7 +793,6 @@ QDataStream &QDataStream::operator>>(double &f)
f = 0.0;
CHECK_STREAM_PRECOND(*this)
-#ifndef Q_DOUBLE_FORMAT
if (dev->read((char *)&f, 8) != 8) {
f = 0.0;
setStatus(ReadPastEnd);
@@ -811,39 +806,6 @@ QDataStream &QDataStream::operator>>(double &f)
f = x.val1;
}
}
-#else
- //non-standard floating point format
- union {
- double val1;
- char val2[8];
- } x;
- char *p = x.val2;
- char b[8];
- if (dev->read(b, 8) == 8) {
- if (noswap) {
- *p++ = b[Q_DF(0)];
- *p++ = b[Q_DF(1)];
- *p++ = b[Q_DF(2)];
- *p++ = b[Q_DF(3)];
- *p++ = b[Q_DF(4)];
- *p++ = b[Q_DF(5)];
- *p++ = b[Q_DF(6)];
- *p = b[Q_DF(7)];
- } else {
- *p++ = b[Q_DF(7)];
- *p++ = b[Q_DF(6)];
- *p++ = b[Q_DF(5)];
- *p++ = b[Q_DF(4)];
- *p++ = b[Q_DF(3)];
- *p++ = b[Q_DF(2)];
- *p++ = b[Q_DF(1)];
- *p = b[Q_DF(0)];
- }
- f = x.val1;
- } else {
- setStatus(ReadPastEnd);
- }
-#endif
return *this;
}
@@ -1112,7 +1074,6 @@ QDataStream &QDataStream::operator<<(double f)
}
CHECK_STREAM_WRITE_PRECOND(*this)
-#ifndef Q_DOUBLE_FORMAT
if (noswap) {
if (dev->write((char *)&f, sizeof(double)) != sizeof(double))
q_status = WriteFailed;
@@ -1126,36 +1087,6 @@ QDataStream &QDataStream::operator<<(double f)
if (dev->write((char *)&x.val2, sizeof(double)) != sizeof(double))
q_status = WriteFailed;
}
-#else
- union {
- double val1;
- char val2[8];
- } x;
- x.val1 = f;
- char *p = x.val2;
- char b[8];
- if (noswap) {
- b[Q_DF(0)] = *p++;
- b[Q_DF(1)] = *p++;
- b[Q_DF(2)] = *p++;
- b[Q_DF(3)] = *p++;
- b[Q_DF(4)] = *p++;
- b[Q_DF(5)] = *p++;
- b[Q_DF(6)] = *p++;
- b[Q_DF(7)] = *p;
- } else {
- b[Q_DF(7)] = *p++;
- b[Q_DF(6)] = *p++;
- b[Q_DF(5)] = *p++;
- b[Q_DF(4)] = *p++;
- b[Q_DF(3)] = *p++;
- b[Q_DF(2)] = *p++;
- b[Q_DF(1)] = *p++;
- b[Q_DF(0)] = *p;
- }
- if (dev->write(b, 8) != 8)
- q_status = WriteFailed;
-#endif
return *this;
}
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index afd402d0191..1dedc7c5c88 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -451,11 +451,11 @@ inline void QDirPrivate::initFileEngine()
for these that return strings:
\table
- \header \o QDir \o QString \o Return Value
- \row \o current() \o currentPath() \o The application's working directory
- \row \o home() \o homePath() \o The user's home directory
- \row \o root() \o rootPath() \o The root directory
- \row \o temp() \o tempPath() \o The system's temporary directory
+ \header \li QDir \li QString \li Return Value
+ \row \li current() \li currentPath() \li The application's working directory
+ \row \li home() \li homePath() \li The user's home directory
+ \row \li root() \li rootPath() \li The root directory
+ \row \li temp() \li tempPath() \li The system's temporary directory
\endtable
The setCurrent() static function can also be used to set the application's
@@ -1878,13 +1878,13 @@ QString QDir::currentPath()
the given order) until an existing and available path is found:
\list 1
- \o The path specified by the \c USERPROFILE environment variable.
- \o The path formed by concatenating the \c HOMEDRIVE and \c HOMEPATH
+ \li The path specified by the \c USERPROFILE environment variable.
+ \li The path formed by concatenating the \c HOMEDRIVE and \c HOMEPATH
environment variables.
- \o The path specified by the \c HOME environment variable.
- \o The path returned by the rootPath() function (which uses the \c SystemDrive
+ \li The path specified by the \c HOME environment variable.
+ \li The path returned by the rootPath() function (which uses the \c SystemDrive
environment variable)
- \o The \c{C:/} directory.
+ \li The \c{C:/} directory.
\endlist
Under non-Windows operating systems the \c HOME environment
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index fc0c90cf69f..433d4493e52 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE
-static const int QFILE_WRITEBUFFER_SIZE = 16384;
-
static QByteArray locale_encode(const QString &f)
{
#if defined(Q_OS_DARWIN)
@@ -86,16 +84,11 @@ QFile::EncoderFn QFilePrivate::encoder = locale_encode;
QFile::DecoderFn QFilePrivate::decoder = locale_decode;
QFilePrivate::QFilePrivate()
- : fileEngine(0), lastWasWrite(false),
- writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
- cachedSize(0)
{
}
QFilePrivate::~QFilePrivate()
{
- delete fileEngine;
- fileEngine = 0;
}
bool
@@ -137,39 +130,6 @@ QAbstractFileEngine *QFilePrivate::engine() const
return fileEngine;
}
-inline bool QFilePrivate::ensureFlushed() const
-{
- // This function ensures that the write buffer has been flushed (const
- // because certain const functions need to call it.
- if (lastWasWrite) {
- const_cast(this)->lastWasWrite = false;
- if (!const_cast(q_func())->flush())
- return false;
- }
- return true;
-}
-
-void
-QFilePrivate::setError(QFile::FileError err)
-{
- error = err;
- errorString.clear();
-}
-
-void
-QFilePrivate::setError(QFile::FileError err, const QString &errStr)
-{
- error = err;
- errorString = errStr;
-}
-
-void
-QFilePrivate::setError(QFile::FileError err, int errNum)
-{
- error = err;
- errorString = qt_error_string(errNum);
-}
-
//************* QFile
/*!
@@ -278,98 +238,18 @@ QFilePrivate::setError(QFile::FileError err, int errNum)
\sa QTextStream, QDataStream, QFileInfo, QDir, {The Qt Resource System}
*/
-/*!
- \enum QFile::FileError
-
- This enum describes the errors that may be returned by the error()
- function.
-
- \value NoError No error occurred.
- \value ReadError An error occurred when reading from the file.
- \value WriteError An error occurred when writing to the file.
- \value FatalError A fatal error occurred.
- \value ResourceError
- \value OpenError The file could not be opened.
- \value AbortError The operation was aborted.
- \value TimeOutError A timeout occurred.
- \value UnspecifiedError An unspecified error occurred.
- \value RemoveError The file could not be removed.
- \value RenameError The file could not be renamed.
- \value PositionError The position in the file could not be changed.
- \value ResizeError The file could not be resized.
- \value PermissionsError The file could not be accessed.
- \value CopyError The file could not be copied.
-
- \omitvalue ConnectError
-*/
-
-/*!
- \enum QFile::Permission
-
- This enum is used by the permission() function to report the
- permissions and ownership of a file. The values may be OR-ed
- together to test multiple permissions and ownership values.
-
- \value ReadOwner The file is readable by the owner of the file.
- \value WriteOwner The file is writable by the owner of the file.
- \value ExeOwner The file is executable by the owner of the file.
- \value ReadUser The file is readable by the user.
- \value WriteUser The file is writable by the user.
- \value ExeUser The file is executable by the user.
- \value ReadGroup The file is readable by the group.
- \value WriteGroup The file is writable by the group.
- \value ExeGroup The file is executable by the group.
- \value ReadOther The file is readable by anyone.
- \value WriteOther The file is writable by anyone.
- \value ExeOther The file is executable by anyone.
-
- \warning Because of differences in the platforms supported by Qt,
- the semantics of ReadUser, WriteUser and ExeUser are
- platform-dependent: On Unix, the rights of the owner of the file
- are returned and on Windows the rights of the current user are
- returned. This behavior might change in a future Qt version.
-
- Note that Qt does not by default check for permissions on NTFS
- file systems, as this may decrease the performance of file
- handling considerably. It is possible to force permission checking
- on NTFS by including the following code in your source:
-
- \snippet doc/src/snippets/ntfsp.cpp 0
-
- Permission checking is then turned on and off by incrementing and
- decrementing \c qt_ntfs_permission_lookup by 1.
-
- \snippet doc/src/snippets/ntfsp.cpp 1
-*/
-
-/*!
- \enum QFile::FileHandleFlag
-
- This enum is used when opening a file to specify additional
- options which only apply to files and not to a generic
- QIODevice.
-
- \value AutoCloseHandle The file handle passed into open() should be
- closed by close(), the default behavior is that close just flushes
- the file and the application is responsible for closing the file handle.
- When opening a file by name, this flag is ignored as Qt always owns the
- file handle and must close it.
- \value DontCloseHandle If not explicitly closed, the underlying file
- handle is left open when the QFile object is destroyed.
- */
-
#ifdef QT_NO_QOBJECT
QFile::QFile()
- : QIODevice(*new QFilePrivate)
+ : QFileDevice(*new QFilePrivate)
{
}
QFile::QFile(const QString &name)
- : QIODevice(*new QFilePrivate)
+ : QFileDevice(*new QFilePrivate)
{
d_func()->fileName = name;
}
QFile::QFile(QFilePrivate &dd)
- : QIODevice(dd)
+ : QFileDevice(dd)
{
}
#else
@@ -377,21 +257,21 @@ QFile::QFile(QFilePrivate &dd)
\internal
*/
QFile::QFile()
- : QIODevice(*new QFilePrivate, 0)
+ : QFileDevice(*new QFilePrivate, 0)
{
}
/*!
Constructs a new file object with the given \a parent.
*/
QFile::QFile(QObject *parent)
- : QIODevice(*new QFilePrivate, parent)
+ : QFileDevice(*new QFilePrivate, parent)
{
}
/*!
Constructs a new file object to represent the file with the given \a name.
*/
QFile::QFile(const QString &name)
- : QIODevice(*new QFilePrivate, 0)
+ : QFileDevice(*new QFilePrivate, 0)
{
Q_D(QFile);
d->fileName = name;
@@ -401,7 +281,7 @@ QFile::QFile(const QString &name)
file with the specified \a name.
*/
QFile::QFile(const QString &name, QObject *parent)
- : QIODevice(*new QFilePrivate, parent)
+ : QFileDevice(*new QFilePrivate, parent)
{
Q_D(QFile);
d->fileName = name;
@@ -410,7 +290,7 @@ QFile::QFile(const QString &name, QObject *parent)
\internal
*/
QFile::QFile(QFilePrivate &dd, QObject *parent)
- : QIODevice(dd, parent)
+ : QFileDevice(dd, parent)
{
}
#endif
@@ -420,7 +300,6 @@ QFile::QFile(QFilePrivate &dd, QObject *parent)
*/
QFile::~QFile()
{
- close();
}
/*!
@@ -961,20 +840,6 @@ QFile::copy(const QString &fileName, const QString &newName)
return QFile(fileName).copy(newName);
}
-/*!
- Returns true if the file can only be manipulated sequentially;
- otherwise returns false.
-
- Most files support random-access, but some special files may not.
-
- \sa QIODevice::isSequential()
-*/
-bool QFile::isSequential() const
-{
- Q_D(const QFile);
- return d->fileEngine && d->fileEngine->isSequential();
-}
-
/*!
Opens the file using OpenMode \a mode, returning true if successful;
otherwise false.
@@ -1034,13 +899,13 @@ bool QFile::open(OpenMode mode)
then calling close() closes the adopted handle.
Otherwise, close() does not actually close the file, but only flushes it.
- \bold{Warning:}
+ \b{Warning:}
\list 1
- \o If \a fh does not refer to a regular file, e.g., it is \c stdin,
+ \li If \a fh does not refer to a regular file, e.g., it is \c stdin,
\c stdout, or \c stderr, you may not be able to seek(). size()
returns \c 0 in those cases. See QIODevice::isSequential() for
more information.
- \o Since this function opens the file without specifying the file name,
+ \li Since this function opens the file without specifying the file name,
you cannot use this QFile with a QFileInfo.
\endlist
@@ -1048,7 +913,7 @@ bool QFile::open(OpenMode mode)
\sa close(), {qmake Variable Reference#CONFIG}{qmake Variable Reference}
- \bold{Note for the Windows Platform}
+ \b{Note for the Windows Platform}
\a fh must be opened in binary mode (i.e., the mode string must contain
'b', as in "rb" or "wb") when accessing files and other random-access
@@ -1149,119 +1014,11 @@ bool QFile::open(int fd, OpenMode mode, FileHandleFlags handleFlags)
}
/*!
- Returns the file handle of the file.
-
- This is a small positive integer, suitable for use with C library
- functions such as fdopen() and fcntl(). On systems that use file
- descriptors for sockets (i.e. Unix systems, but not Windows) the handle
- can be used with QSocketNotifier as well.
-
- If the file is not open, or there is an error, handle() returns -1.
-
- This function is not supported on Windows CE.
-
- \sa QSocketNotifier
+ \reimp
*/
-
-int
-QFile::handle() const
+bool QFile::resize(qint64 sz)
{
- Q_D(const QFile);
- if (!isOpen() || !d->fileEngine)
- return -1;
-
- return d->fileEngine->handle();
-}
-
-/*!
- \enum QFile::MemoryMapFlags
- \since 4.4
-
- This enum describes special options that may be used by the map()
- function.
-
- \value NoOptions No options.
-*/
-
-/*!
- \since 4.4
- Maps \a size bytes of the file into memory starting at \a offset. A file
- should be open for a map to succeed but the file does not need to stay
- open after the memory has been mapped. When the QFile is destroyed
- or a new file is opened with this object, any maps that have not been
- unmapped will automatically be unmapped.
-
- Any mapping options can be passed through \a flags.
-
- Returns a pointer to the memory or 0 if there is an error.
-
- \note On Windows CE 5.0 the file will be closed before mapping occurs.
-
- \sa unmap()
- */
-uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags)
-{
- Q_D(QFile);
- if (d->engine()
- && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
- unsetError();
- uchar *address = d->fileEngine->map(offset, size, flags);
- if (address == 0)
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- return address;
- }
- return 0;
-}
-
-/*!
- \since 4.4
- Unmaps the memory \a address.
-
- Returns true if the unmap succeeds; false otherwise.
-
- \sa map()
- */
-bool QFile::unmap(uchar *address)
-{
- Q_D(QFile);
- if (d->engine()
- && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
- unsetError();
- bool success = d->fileEngine->unmap(address);
- if (!success)
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- return success;
- }
- d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
- return false;
-}
-
-/*!
- Sets the file size (in bytes) \a sz. Returns true if the file if the
- resize succeeds; false otherwise. If \a sz is larger than the file
- currently is the new bytes will be set to 0, if \a sz is smaller the
- file is simply truncated.
-
- \sa size(), setFileName()
-*/
-
-bool
-QFile::resize(qint64 sz)
-{
- Q_D(QFile);
- if (!d->ensureFlushed())
- return false;
- d->engine();
- if (isOpen() && d->fileEngine->pos() > sz)
- seek(sz);
- if(d->fileEngine->setSize(sz)) {
- unsetError();
- d->cachedSize = sz;
- return true;
- }
- d->cachedSize = 0;
- d->setError(QFile::ResizeError, d->fileEngine->errorString());
- return false;
+ return QFileDevice::resize(sz); // for now
}
/*!
@@ -1282,18 +1039,11 @@ QFile::resize(const QString &fileName, qint64 sz)
}
/*!
- Returns the complete OR-ed together combination of
- QFile::Permission for the file.
-
- \sa setPermissions(), setFileName()
+ \reimp
*/
-
-QFile::Permissions
-QFile::permissions() const
+QFile::Permissions QFile::permissions() const
{
- Q_D(const QFile);
- QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
- return QFile::Permissions((int)perms); //ewww
+ return QFileDevice::permissions(); // for now
}
/*!
@@ -1317,16 +1067,9 @@ QFile::permissions(const QString &fileName)
\sa permissions(), setFileName()
*/
-bool
-QFile::setPermissions(Permissions permissions)
+bool QFile::setPermissions(Permissions permissions)
{
- Q_D(QFile);
- if (d->engine()->setPermissions(permissions)) {
- unsetError();
- return true;
- }
- d->setError(QFile::PermissionsError, d->fileEngine->errorString());
- return false;
+ return QFileDevice::setPermissions(permissions); // for now
}
/*!
@@ -1341,354 +1084,12 @@ QFile::setPermissions(const QString &fileName, Permissions permissions)
return QFile(fileName).setPermissions(permissions);
}
-static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
-{
- qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
- if (ret > 0)
- buffer->free(ret);
- return ret;
-}
-
/*!
- Flushes any buffered data to the file. Returns true if successful;
- otherwise returns false.
+ \reimp
*/
-
-bool
-QFile::flush()
-{
- Q_D(QFile);
- if (!d->fileEngine) {
- qWarning("QFile::flush: No file engine. Is IODevice open?");
- return false;
- }
-
- if (!d->writeBuffer.isEmpty()) {
- qint64 size = d->writeBuffer.size();
- if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::WriteError;
- d->setError(err, d->fileEngine->errorString());
- return false;
- }
- }
-
- if (!d->fileEngine->flush()) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::WriteError;
- d->setError(err, d->fileEngine->errorString());
- return false;
- }
- return true;
-}
-
-/*!
- Calls QFile::flush() and closes the file. Errors from flush are ignored.
-
- \sa QIODevice::close()
-*/
-void
-QFile::close()
-{
- Q_D(QFile);
- if(!isOpen())
- return;
- bool flushed = flush();
- QIODevice::close();
-
- // reset write buffer
- d->lastWasWrite = false;
- d->writeBuffer.clear();
-
- // keep earlier error from flush
- if (d->fileEngine->close() && flushed)
- unsetError();
- else if (flushed)
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
-}
-
-/*!
- Returns the size of the file.
-
- For regular empty files on Unix (e.g. those in \c /proc), this function
- returns 0; the contents of such a file are generated on demand in response
- to you calling read().
-*/
-
qint64 QFile::size() const
{
- Q_D(const QFile);
- if (!d->ensureFlushed())
- return 0;
- d->cachedSize = d->engine()->size();
- return d->cachedSize;
-}
-
-/*!
- \reimp
-*/
-
-qint64 QFile::pos() const
-{
- return QIODevice::pos();
-}
-
-/*!
- Returns true if the end of the file has been reached; otherwise returns
- false.
-
- For regular empty files on Unix (e.g. those in \c /proc), this function
- returns true, since the file system reports that the size of such a file is
- 0. Therefore, you should not depend on atEnd() when reading data from such a
- file, but rather call read() until no more data can be read.
-*/
-
-bool QFile::atEnd() const
-{
- Q_D(const QFile);
-
- // If there's buffered data left, we're not at the end.
- if (!d->buffer.isEmpty())
- return false;
-
- if (!isOpen())
- return true;
-
- if (!d->ensureFlushed())
- return false;
-
- // If the file engine knows best, say what it says.
- if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
- // Check if the file engine supports AtEndExtension, and if it does,
- // check if the file engine claims to be at the end.
- return d->fileEngine->atEnd();
- }
-
- // if it looks like we are at the end, or if size is not cached,
- // fall through to bytesAvailable() to make sure.
- if (pos() < d->cachedSize)
- return false;
-
- // Fall back to checking how much is available (will stat files).
- return bytesAvailable() == 0;
-}
-
-/*!
- \fn bool QFile::seek(qint64 pos)
-
- For random-access devices, this function sets the current position
- to \a pos, returning true on success, or false if an error occurred.
- For sequential devices, the default behavior is to do nothing and
- return false.
-
- Seeking beyond the end of a file:
- If the position is beyond the end of a file, then seek() shall not
- immediately extend the file. If a write is performed at this position,
- then the file shall be extended. The content of the file between the
- previous end of file and the newly written data is UNDEFINED and
- varies between platforms and file systems.
-*/
-
-bool QFile::seek(qint64 off)
-{
- Q_D(QFile);
- if (!isOpen()) {
- qWarning("QFile::seek: IODevice is not open");
- return false;
- }
-
- if (!d->ensureFlushed())
- return false;
-
- if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::PositionError;
- d->setError(err, d->fileEngine->errorString());
- return false;
- }
- unsetError();
- return true;
-}
-
-/*!
- \reimp
-*/
-qint64 QFile::readLineData(char *data, qint64 maxlen)
-{
- Q_D(QFile);
- if (!d->ensureFlushed())
- return -1;
-
- qint64 read;
- if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
- read = d->fileEngine->readLine(data, maxlen);
- } else {
- // Fall back to QIODevice's readLine implementation if the engine
- // cannot do it faster.
- read = QIODevice::readLineData(data, maxlen);
- }
-
- if (read < maxlen) {
- // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
- d->cachedSize = 0;
- }
-
- return read;
-}
-
-/*!
- \reimp
-*/
-
-qint64 QFile::readData(char *data, qint64 len)
-{
- Q_D(QFile);
- unsetError();
- if (!d->ensureFlushed())
- return -1;
-
- qint64 read = d->fileEngine->read(data, len);
- if(read < 0) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::ReadError;
- d->setError(err, d->fileEngine->errorString());
- }
-
- if (read < len) {
- // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
- d->cachedSize = 0;
- }
-
- return read;
-}
-
-/*!
- \internal
-*/
-bool QFilePrivate::putCharHelper(char c)
-{
-#ifdef QT_NO_QOBJECT
- return QIODevicePrivate::putCharHelper(c);
-#else
-
- // Cutoff for code that doesn't only touch the buffer.
- int writeBufferSize = writeBuffer.size();
- if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
-#ifdef Q_OS_WIN
- || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
-#endif
- ) {
- return QIODevicePrivate::putCharHelper(c);
- }
-
- if (!(openMode & QIODevice::WriteOnly)) {
- if (openMode == QIODevice::NotOpen)
- qWarning("QIODevice::putChar: Closed device");
- else
- qWarning("QIODevice::putChar: ReadOnly device");
- return false;
- }
-
- // Make sure the device is positioned correctly.
- const bool sequential = isSequential();
- if (pos != devicePos && !sequential && !q_func()->seek(pos))
- return false;
-
- lastWasWrite = true;
-
- int len = 1;
-#ifdef Q_OS_WIN
- if ((openMode & QIODevice::Text) && c == '\n') {
- ++len;
- *writeBuffer.reserve(1) = '\r';
- }
-#endif
-
- // Write to buffer.
- *writeBuffer.reserve(1) = c;
-
- if (!sequential) {
- pos += len;
- devicePos += len;
- if (!buffer.isEmpty())
- buffer.skip(len);
- }
-
- return true;
-#endif
-}
-
-/*!
- \reimp
-*/
-
-qint64
-QFile::writeData(const char *data, qint64 len)
-{
- Q_D(QFile);
- unsetError();
- d->lastWasWrite = true;
- bool buffered = !(d->openMode & Unbuffered);
-
- // Flush buffered data if this read will overflow.
- if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
- if (!flush())
- return -1;
- }
-
- // Write directly to the engine if the block size is larger than
- // the write buffer size.
- if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
- qint64 ret = d->fileEngine->write(data, len);
- if(ret < 0) {
- QFile::FileError err = d->fileEngine->error();
- if(err == QFile::UnspecifiedError)
- err = QFile::WriteError;
- d->setError(err, d->fileEngine->errorString());
- }
- return ret;
- }
-
- // Write to the buffer.
- char *writePointer = d->writeBuffer.reserve(len);
- if (len == 1)
- *writePointer = *data;
- else
- ::memcpy(writePointer, data, len);
- return len;
-}
-
-/*!
- Returns the file error status.
-
- The I/O device status returns an error code. For example, if open()
- returns false, or a read/write operation returns -1, this function can
- be called to find out the reason why the operation failed.
-
- \sa unsetError()
-*/
-
-QFile::FileError
-QFile::error() const
-{
- Q_D(const QFile);
- return d->error;
-}
-
-/*!
- Sets the file's error to QFile::NoError.
-
- \sa error()
-*/
-void
-QFile::unsetError()
-{
- Q_D(QFile);
- d->setError(QFile::NoError);
+ return QFileDevice::size(); // for now
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index 7f370d42141..0ee8f39d957 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -42,7 +42,7 @@
#ifndef QFILE_H
#define QFILE_H
-#include
+#include
#include
#include
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
class QTemporaryFile;
class QFilePrivate;
-class Q_CORE_EXPORT QFile : public QIODevice
+class Q_CORE_EXPORT QFile : public QFileDevice
{
#ifndef QT_NO_QOBJECT
Q_OBJECT
@@ -65,39 +65,6 @@ class Q_CORE_EXPORT QFile : public QIODevice
Q_DECLARE_PRIVATE(QFile)
public:
-
- enum FileError {
- NoError = 0,
- ReadError = 1,
- WriteError = 2,
- FatalError = 3,
- ResourceError = 4,
- OpenError = 5,
- AbortError = 6,
- TimeOutError = 7,
- UnspecifiedError = 8,
- RemoveError = 9,
- RenameError = 10,
- PositionError = 11,
- ResizeError = 12,
- PermissionsError = 13,
- CopyError = 14
- };
-
- enum Permission {
- ReadOwner = 0x4000, WriteOwner = 0x2000, ExeOwner = 0x1000,
- ReadUser = 0x0400, WriteUser = 0x0200, ExeUser = 0x0100,
- ReadGroup = 0x0040, WriteGroup = 0x0020, ExeGroup = 0x0010,
- ReadOther = 0x0004, WriteOther = 0x0002, ExeOther = 0x0001
- };
- Q_DECLARE_FLAGS(Permissions, Permission)
-
- enum FileHandleFlag {
- AutoCloseHandle = 0x0001,
- DontCloseHandle = 0
- };
- Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)
-
QFile();
QFile(const QString &name);
#ifndef QT_NO_QOBJECT
@@ -106,9 +73,6 @@ public:
#endif
~QFile();
- FileError error() const;
- void unsetError();
-
QString fileName() const;
void setFileName(const QString &name);
@@ -141,18 +105,11 @@ public:
bool copy(const QString &newName);
static bool copy(const QString &fileName, const QString &newName);
- bool isSequential() const;
-
bool open(OpenMode flags);
bool open(FILE *f, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
bool open(int fd, OpenMode ioFlags, FileHandleFlags handleFlags=DontCloseHandle);
- virtual void close();
qint64 size() const;
- qint64 pos() const;
- bool seek(qint64 offset);
- bool atEnd() const;
- bool flush();
bool resize(qint64 sz);
static bool resize(const QString &filename, qint64 sz);
@@ -162,15 +119,6 @@ public:
bool setPermissions(Permissions permissionSpec);
static bool setPermissions(const QString &filename, Permissions permissionSpec);
- int handle() const;
-
- enum MemoryMapFlags {
- NoOptions = 0
- };
-
- uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
- bool unmap(uchar *address);
-
protected:
#ifdef QT_NO_QOBJECT
QFile(QFilePrivate &dd);
@@ -178,17 +126,11 @@ protected:
QFile(QFilePrivate &dd, QObject *parent = 0);
#endif
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
- qint64 readLineData(char *data, qint64 maxlen);
-
private:
friend class QTemporaryFile;
Q_DISABLE_COPY(QFile)
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QFile::Permissions)
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/io/qfile_p.h b/src/corelib/io/qfile_p.h
index 3d2d3d678bb..575d7d14b9c 100644
--- a/src/corelib/io/qfile_p.h
+++ b/src/corelib/io/qfile_p.h
@@ -53,15 +53,13 @@
// We mean it.
//
-#include "private/qabstractfileengine_p.h"
-#include "private/qiodevice_p.h"
-#include "private/qringbuffer_p.h"
+#include "private/qfiledevice_p.h"
QT_BEGIN_NAMESPACE
class QTemporaryFile;
-class QFilePrivate : public QIODevicePrivate
+class QFilePrivate : public QFileDevicePrivate
{
Q_DECLARE_PUBLIC(QFile)
friend class QTemporaryFile;
@@ -76,20 +74,6 @@ protected:
virtual QAbstractFileEngine *engine() const;
QString fileName;
- mutable QAbstractFileEngine *fileEngine;
-
- bool lastWasWrite;
- QRingBuffer writeBuffer;
- inline bool ensureFlushed() const;
-
- bool putCharHelper(char c);
-
- QFile::FileError error;
- void setError(QFile::FileError err);
- void setError(QFile::FileError err, const QString &errorString);
- void setError(QFile::FileError err, int errNum);
-
- mutable qint64 cachedSize;
private:
static QFile::EncoderFn encoder;
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
new file mode 100644
index 00000000000..17eedb0bdd6
--- /dev/null
+++ b/src/corelib/io/qfiledevice.cpp
@@ -0,0 +1,736 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qfiledevice.h"
+#include "qfiledevice_p.h"
+#include "qfsfileengine_p.h"
+
+#ifdef QT_NO_QOBJECT
+#define tr(X) QString::fromLatin1(X)
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static const int QFILE_WRITEBUFFER_SIZE = 16384;
+
+QFileDevicePrivate::QFileDevicePrivate()
+ : fileEngine(0), lastWasWrite(false),
+ writeBuffer(QFILE_WRITEBUFFER_SIZE), error(QFile::NoError),
+ cachedSize(0)
+{
+}
+
+QFileDevicePrivate::~QFileDevicePrivate()
+{
+ delete fileEngine;
+ fileEngine = 0;
+}
+
+QAbstractFileEngine * QFileDevicePrivate::engine() const
+{
+ if (!fileEngine)
+ fileEngine = new QFSFileEngine;
+ return fileEngine;
+}
+
+void QFileDevicePrivate::setError(QFileDevice::FileError err)
+{
+ error = err;
+ errorString.clear();
+}
+
+void QFileDevicePrivate::setError(QFileDevice::FileError err, const QString &errStr)
+{
+ error = err;
+ errorString = errStr;
+}
+
+void QFileDevicePrivate::setError(QFileDevice::FileError err, int errNum)
+{
+ error = err;
+ errorString = qt_error_string(errNum);
+}
+
+/*!
+ \enum QFileDevice::FileError
+
+ This enum describes the errors that may be returned by the error()
+ function.
+
+ \value NoError No error occurred.
+ \value ReadError An error occurred when reading from the file.
+ \value WriteError An error occurred when writing to the file.
+ \value FatalError A fatal error occurred.
+ \value ResourceError
+ \value OpenError The file could not be opened.
+ \value AbortError The operation was aborted.
+ \value TimeOutError A timeout occurred.
+ \value UnspecifiedError An unspecified error occurred.
+ \value RemoveError The file could not be removed.
+ \value RenameError The file could not be renamed.
+ \value PositionError The position in the file could not be changed.
+ \value ResizeError The file could not be resized.
+ \value PermissionsError The file could not be accessed.
+ \value CopyError The file could not be copied.
+
+ \omitvalue ConnectError
+*/
+
+/*!
+ \enum QFileDevice::Permission
+
+ This enum is used by the permission() function to report the
+ permissions and ownership of a file. The values may be OR-ed
+ together to test multiple permissions and ownership values.
+
+ \value ReadOwner The file is readable by the owner of the file.
+ \value WriteOwner The file is writable by the owner of the file.
+ \value ExeOwner The file is executable by the owner of the file.
+ \value ReadUser The file is readable by the user.
+ \value WriteUser The file is writable by the user.
+ \value ExeUser The file is executable by the user.
+ \value ReadGroup The file is readable by the group.
+ \value WriteGroup The file is writable by the group.
+ \value ExeGroup The file is executable by the group.
+ \value ReadOther The file is readable by anyone.
+ \value WriteOther The file is writable by anyone.
+ \value ExeOther The file is executable by anyone.
+
+ \warning Because of differences in the platforms supported by Qt,
+ the semantics of ReadUser, WriteUser and ExeUser are
+ platform-dependent: On Unix, the rights of the owner of the file
+ are returned and on Windows the rights of the current user are
+ returned. This behavior might change in a future Qt version.
+
+ Note that Qt does not by default check for permissions on NTFS
+ file systems, as this may decrease the performance of file
+ handling considerably. It is possible to force permission checking
+ on NTFS by including the following code in your source:
+
+ \snippet doc/src/snippets/ntfsp.cpp 0
+
+ Permission checking is then turned on and off by incrementing and
+ decrementing \c qt_ntfs_permission_lookup by 1.
+
+ \snippet doc/src/snippets/ntfsp.cpp 1
+*/
+
+//************* QFileDevice
+
+/*!
+ \class QFileDevice
+ \since 5.0
+
+ \brief The QFileDevice class provides an interface for reading from and writing to open files.
+
+ \ingroup io
+
+ \reentrant
+
+ QFileDevice is the base class for I/O devices that can read and write text and binary files
+ and \l{The Qt Resource System}{resources}. QFile offers the main functionality,
+ QFileDevice serves as a base class for sharing functionality with other file devices such
+ as QTemporaryFile, by providing all the operations that can be done on files that have
+ been opened by QFile or QTemporaryFile.
+
+ \sa QFile, QTemporaryFile
+*/
+
+/*!
+ \enum QFileDevice::FileHandleFlag
+
+ This enum is used when opening a file to specify additional
+ options which only apply to files and not to a generic
+ QIODevice.
+
+ \value AutoCloseHandle The file handle passed into open() should be
+ closed by close(), the default behavior is that close just flushes
+ the file and the application is responsible for closing the file handle.
+ When opening a file by name, this flag is ignored as Qt always owns the
+ file handle and must close it.
+ \value DontCloseHandle If not explicitly closed, the underlying file
+ handle is left open when the QFile object is destroyed.
+ */
+
+#ifdef QT_NO_QOBJECT
+QFileDevice::QFileDevice()
+ : QIODevice(*new QFileDevicePrivate)
+{
+}
+QFileDevice::QFileDevice(QFileDevicePrivate &dd)
+ : QIODevice(dd)
+{
+}
+#else
+/*!
+ \internal
+*/
+QFileDevice::QFileDevice()
+ : QIODevice(*new QFileDevicePrivate, 0)
+{
+}
+/*!
+ \internal
+*/
+QFileDevice::QFileDevice(QObject *parent)
+ : QIODevice(*new QFileDevicePrivate, parent)
+{
+}
+/*!
+ \internal
+*/
+QFileDevice::QFileDevice(QFileDevicePrivate &dd, QObject *parent)
+ : QIODevice(dd, parent)
+{
+}
+#endif
+
+/*!
+ Destroys the file device, closing it if necessary.
+*/
+QFileDevice::~QFileDevice()
+{
+ close();
+}
+
+/*!
+ Returns true if the file can only be manipulated sequentially;
+ otherwise returns false.
+
+ Most files support random-access, but some special files may not.
+
+ \sa QIODevice::isSequential()
+*/
+bool QFileDevice::isSequential() const
+{
+ Q_D(const QFileDevice);
+ return d->fileEngine && d->fileEngine->isSequential();
+}
+
+/*!
+ Returns the file handle of the file.
+
+ This is a small positive integer, suitable for use with C library
+ functions such as fdopen() and fcntl(). On systems that use file
+ descriptors for sockets (i.e. Unix systems, but not Windows) the handle
+ can be used with QSocketNotifier as well.
+
+ If the file is not open, or there is an error, handle() returns -1.
+
+ This function is not supported on Windows CE.
+
+ \sa QSocketNotifier
+*/
+int QFileDevice::handle() const
+{
+ Q_D(const QFileDevice);
+ if (!isOpen() || !d->fileEngine)
+ return -1;
+
+ return d->fileEngine->handle();
+}
+
+/*!
+ Returns the name of the file.
+ The default implementation in QFileDevice returns QString().
+*/
+QString QFileDevice::fileName() const
+{
+ return QString();
+}
+
+static inline qint64 _qfile_writeData(QAbstractFileEngine *engine, QRingBuffer *buffer)
+{
+ qint64 ret = engine->write(buffer->readPointer(), buffer->nextDataBlockSize());
+ if (ret > 0)
+ buffer->free(ret);
+ return ret;
+}
+
+/*!
+ Flushes any buffered data to the file. Returns true if successful;
+ otherwise returns false.
+*/
+bool QFileDevice::flush()
+{
+ Q_D(QFileDevice);
+ if (!d->fileEngine) {
+ qWarning("QFileDevice::flush: No file engine. Is IODevice open?");
+ return false;
+ }
+
+ if (!d->writeBuffer.isEmpty()) {
+ qint64 size = d->writeBuffer.size();
+ if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) {
+ QFileDevice::FileError err = d->fileEngine->error();
+ if (err == QFileDevice::UnspecifiedError)
+ err = QFileDevice::WriteError;
+ d->setError(err, d->fileEngine->errorString());
+ return false;
+ }
+ }
+
+ if (!d->fileEngine->flush()) {
+ QFileDevice::FileError err = d->fileEngine->error();
+ if (err == QFileDevice::UnspecifiedError)
+ err = QFileDevice::WriteError;
+ d->setError(err, d->fileEngine->errorString());
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Calls QFileDevice::flush() and closes the file. Errors from flush are ignored.
+
+ \sa QIODevice::close()
+*/
+void QFileDevice::close()
+{
+ Q_D(QFileDevice);
+ if (!isOpen())
+ return;
+ bool flushed = flush();
+ QIODevice::close();
+
+ // reset write buffer
+ d->lastWasWrite = false;
+ d->writeBuffer.clear();
+
+ // keep earlier error from flush
+ if (d->fileEngine->close() && flushed)
+ unsetError();
+ else if (flushed)
+ d->setError(d->fileEngine->error(), d->fileEngine->errorString());
+}
+
+/*!
+ \reimp
+*/
+qint64 QFileDevice::pos() const
+{
+ return QIODevice::pos();
+}
+
+/*!
+ Returns true if the end of the file has been reached; otherwise returns
+ false.
+
+ For regular empty files on Unix (e.g. those in \c /proc), this function
+ returns true, since the file system reports that the size of such a file is
+ 0. Therefore, you should not depend on atEnd() when reading data from such a
+ file, but rather call read() until no more data can be read.
+*/
+bool QFileDevice::atEnd() const
+{
+ Q_D(const QFileDevice);
+
+ // If there's buffered data left, we're not at the end.
+ if (!d->buffer.isEmpty())
+ return false;
+
+ if (!isOpen())
+ return true;
+
+ if (!d->ensureFlushed())
+ return false;
+
+ // If the file engine knows best, say what it says.
+ if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) {
+ // Check if the file engine supports AtEndExtension, and if it does,
+ // check if the file engine claims to be at the end.
+ return d->fileEngine->atEnd();
+ }
+
+ // if it looks like we are at the end, or if size is not cached,
+ // fall through to bytesAvailable() to make sure.
+ if (pos() < d->cachedSize)
+ return false;
+
+ // Fall back to checking how much is available (will stat files).
+ return bytesAvailable() == 0;
+}
+
+/*!
+ \fn bool QFileDevice::seek(qint64 pos)
+
+ For random-access devices, this function sets the current position
+ to \a pos, returning true on success, or false if an error occurred.
+ For sequential devices, the default behavior is to do nothing and
+ return false.
+
+ Seeking beyond the end of a file:
+ If the position is beyond the end of a file, then seek() shall not
+ immediately extend the file. If a write is performed at this position,
+ then the file shall be extended. The content of the file between the
+ previous end of file and the newly written data is UNDEFINED and
+ varies between platforms and file systems.
+*/
+bool QFileDevice::seek(qint64 off)
+{
+ Q_D(QFileDevice);
+ if (!isOpen()) {
+ qWarning("QFileDevice::seek: IODevice is not open");
+ return false;
+ }
+
+ if (!d->ensureFlushed())
+ return false;
+
+ if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) {
+ QFileDevice::FileError err = d->fileEngine->error();
+ if (err == QFileDevice::UnspecifiedError)
+ err = QFileDevice::PositionError;
+ d->setError(err, d->fileEngine->errorString());
+ return false;
+ }
+ unsetError();
+ return true;
+}
+
+/*!
+ \reimp
+*/
+qint64 QFileDevice::readLineData(char *data, qint64 maxlen)
+{
+ Q_D(QFileDevice);
+ if (!d->ensureFlushed())
+ return -1;
+
+ qint64 read;
+ if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) {
+ read = d->fileEngine->readLine(data, maxlen);
+ } else {
+ // Fall back to QIODevice's readLine implementation if the engine
+ // cannot do it faster.
+ read = QIODevice::readLineData(data, maxlen);
+ }
+
+ if (read < maxlen) {
+ // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
+ d->cachedSize = 0;
+ }
+
+ return read;
+}
+
+/*!
+ \reimp
+*/
+qint64 QFileDevice::readData(char *data, qint64 len)
+{
+ Q_D(QFileDevice);
+ unsetError();
+ if (!d->ensureFlushed())
+ return -1;
+
+ const qint64 read = d->fileEngine->read(data, len);
+ if (read < 0) {
+ QFileDevice::FileError err = d->fileEngine->error();
+ if (err == QFileDevice::UnspecifiedError)
+ err = QFileDevice::ReadError;
+ d->setError(err, d->fileEngine->errorString());
+ }
+
+ if (read < len) {
+ // failed to read all requested, may be at the end of file, stop caching size so that it's rechecked
+ d->cachedSize = 0;
+ }
+
+ return read;
+}
+
+/*!
+ \internal
+*/
+bool QFileDevicePrivate::putCharHelper(char c)
+{
+#ifdef QT_NO_QOBJECT
+ return QIODevicePrivate::putCharHelper(c);
+#else
+
+ // Cutoff for code that doesn't only touch the buffer.
+ int writeBufferSize = writeBuffer.size();
+ if ((openMode & QIODevice::Unbuffered) || writeBufferSize + 1 >= QFILE_WRITEBUFFER_SIZE
+#ifdef Q_OS_WIN
+ || ((openMode & QIODevice::Text) && c == '\n' && writeBufferSize + 2 >= QFILE_WRITEBUFFER_SIZE)
+#endif
+ ) {
+ return QIODevicePrivate::putCharHelper(c);
+ }
+
+ if (!(openMode & QIODevice::WriteOnly)) {
+ if (openMode == QIODevice::NotOpen)
+ qWarning("QIODevice::putChar: Closed device");
+ else
+ qWarning("QIODevice::putChar: ReadOnly device");
+ return false;
+ }
+
+ // Make sure the device is positioned correctly.
+ const bool sequential = isSequential();
+ if (pos != devicePos && !sequential && !q_func()->seek(pos))
+ return false;
+
+ lastWasWrite = true;
+
+ int len = 1;
+#ifdef Q_OS_WIN
+ if ((openMode & QIODevice::Text) && c == '\n') {
+ ++len;
+ *writeBuffer.reserve(1) = '\r';
+ }
+#endif
+
+ // Write to buffer.
+ *writeBuffer.reserve(1) = c;
+
+ if (!sequential) {
+ pos += len;
+ devicePos += len;
+ if (!buffer.isEmpty())
+ buffer.skip(len);
+ }
+
+ return true;
+#endif
+}
+
+/*!
+ \reimp
+*/
+qint64 QFileDevice::writeData(const char *data, qint64 len)
+{
+ Q_D(QFileDevice);
+ unsetError();
+ d->lastWasWrite = true;
+ bool buffered = !(d->openMode & Unbuffered);
+
+ // Flush buffered data if this read will overflow.
+ if (buffered && (d->writeBuffer.size() + len) > QFILE_WRITEBUFFER_SIZE) {
+ if (!flush())
+ return -1;
+ }
+
+ // Write directly to the engine if the block size is larger than
+ // the write buffer size.
+ if (!buffered || len > QFILE_WRITEBUFFER_SIZE) {
+ const qint64 ret = d->fileEngine->write(data, len);
+ if (ret < 0) {
+ QFileDevice::FileError err = d->fileEngine->error();
+ if (err == QFileDevice::UnspecifiedError)
+ err = QFileDevice::WriteError;
+ d->setError(err, d->fileEngine->errorString());
+ }
+ return ret;
+ }
+
+ // Write to the buffer.
+ char *writePointer = d->writeBuffer.reserve(len);
+ if (len == 1)
+ *writePointer = *data;
+ else
+ ::memcpy(writePointer, data, len);
+ return len;
+}
+
+/*!
+ Returns the file error status.
+
+ The I/O device status returns an error code. For example, if open()
+ returns false, or a read/write operation returns -1, this function can
+ be called to find out the reason why the operation failed.
+
+ \sa unsetError()
+*/
+QFileDevice::FileError QFileDevice::error() const
+{
+ Q_D(const QFileDevice);
+ return d->error;
+}
+
+/*!
+ Sets the file's error to QFileDevice::NoError.
+
+ \sa error()
+*/
+void QFileDevice::unsetError()
+{
+ Q_D(QFileDevice);
+ d->setError(QFileDevice::NoError);
+}
+
+/*!
+ Returns the size of the file.
+
+ For regular empty files on Unix (e.g. those in \c /proc), this function
+ returns 0; the contents of such a file are generated on demand in response
+ to you calling read().
+*/
+qint64 QFileDevice::size() const
+{
+ Q_D(const QFileDevice);
+ if (!d->ensureFlushed())
+ return 0;
+ d->cachedSize = d->engine()->size();
+ return d->cachedSize;
+}
+
+/*!
+ Sets the file size (in bytes) \a sz. Returns true if the file if the
+ resize succeeds; false otherwise. If \a sz is larger than the file
+ currently is the new bytes will be set to 0, if \a sz is smaller the
+ file is simply truncated.
+
+ \sa size()
+*/
+bool QFileDevice::resize(qint64 sz)
+{
+ Q_D(QFileDevice);
+ if (!d->ensureFlushed())
+ return false;
+ d->engine();
+ if (isOpen() && d->fileEngine->pos() > sz)
+ seek(sz);
+ if (d->fileEngine->setSize(sz)) {
+ unsetError();
+ d->cachedSize = sz;
+ return true;
+ }
+ d->cachedSize = 0;
+ d->setError(QFile::ResizeError, d->fileEngine->errorString());
+ return false;
+}
+
+/*!
+ Returns the complete OR-ed together combination of
+ QFile::Permission for the file.
+
+ \sa setPermissions()
+*/
+QFile::Permissions QFileDevice::permissions() const
+{
+ Q_D(const QFileDevice);
+ QAbstractFileEngine::FileFlags perms = d->engine()->fileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask;
+ return QFile::Permissions((int)perms); //ewww
+}
+
+/*!
+ Sets the permissions for the file to the \a permissions specified.
+ Returns true if successful, or false if the permissions cannot be
+ modified.
+
+ \sa permissions()
+*/
+bool QFileDevice::setPermissions(Permissions permissions)
+{
+ Q_D(QFileDevice);
+ if (d->engine()->setPermissions(permissions)) {
+ unsetError();
+ return true;
+ }
+ d->setError(QFile::PermissionsError, d->fileEngine->errorString());
+ return false;
+}
+
+/*!
+ \enum QFileDevice::MemoryMapFlags
+ \since 4.4
+
+ This enum describes special options that may be used by the map()
+ function.
+
+ \value NoOptions No options.
+*/
+
+/*!
+ Maps \a size bytes of the file into memory starting at \a offset. A file
+ should be open for a map to succeed but the file does not need to stay
+ open after the memory has been mapped. When the QFile is destroyed
+ or a new file is opened with this object, any maps that have not been
+ unmapped will automatically be unmapped.
+
+ Any mapping options can be passed through \a flags.
+
+ Returns a pointer to the memory or 0 if there is an error.
+
+ \note On Windows CE 5.0 the file will be closed before mapping occurs.
+
+ \sa unmap()
+ */
+uchar *QFileDevice::map(qint64 offset, qint64 size, MemoryMapFlags flags)
+{
+ Q_D(QFileDevice);
+ if (d->engine()
+ && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) {
+ unsetError();
+ uchar *address = d->fileEngine->map(offset, size, flags);
+ if (address == 0)
+ d->setError(d->fileEngine->error(), d->fileEngine->errorString());
+ return address;
+ }
+ return 0;
+}
+
+/*!
+ Unmaps the memory \a address.
+
+ Returns true if the unmap succeeds; false otherwise.
+
+ \sa map()
+ */
+bool QFileDevice::unmap(uchar *address)
+{
+ Q_D(QFileDevice);
+ if (d->engine()
+ && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) {
+ unsetError();
+ bool success = d->fileEngine->unmap(address);
+ if (!success)
+ d->setError(d->fileEngine->error(), d->fileEngine->errorString());
+ return success;
+ }
+ d->setError(PermissionsError, tr("No file engine available or engine does not support UnMapExtension"));
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h
new file mode 100644
index 00000000000..bbde91842c0
--- /dev/null
+++ b/src/corelib/io/qfiledevice.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILEDEVICE_H
+#define QFILEDEVICE_H
+
+#include
+#include
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QFileDevicePrivate;
+
+class Q_CORE_EXPORT QFileDevice : public QIODevice
+{
+#ifndef QT_NO_QOBJECT
+ Q_OBJECT
+#endif
+ Q_DECLARE_PRIVATE(QFileDevice)
+
+public:
+ enum FileError {
+ NoError = 0,
+ ReadError = 1,
+ WriteError = 2,
+ FatalError = 3,
+ ResourceError = 4,
+ OpenError = 5,
+ AbortError = 6,
+ TimeOutError = 7,
+ UnspecifiedError = 8,
+ RemoveError = 9,
+ RenameError = 10,
+ PositionError = 11,
+ ResizeError = 12,
+ PermissionsError = 13,
+ CopyError = 14
+ };
+
+ enum Permission {
+ ReadOwner = 0x4000, WriteOwner = 0x2000, ExeOwner = 0x1000,
+ ReadUser = 0x0400, WriteUser = 0x0200, ExeUser = 0x0100,
+ ReadGroup = 0x0040, WriteGroup = 0x0020, ExeGroup = 0x0010,
+ ReadOther = 0x0004, WriteOther = 0x0002, ExeOther = 0x0001
+ };
+ Q_DECLARE_FLAGS(Permissions, Permission)
+
+ enum FileHandleFlag {
+ AutoCloseHandle = 0x0001,
+ DontCloseHandle = 0
+ };
+ Q_DECLARE_FLAGS(FileHandleFlags, FileHandleFlag)
+
+ ~QFileDevice();
+
+ FileError error() const;
+ void unsetError();
+
+ virtual void close();
+
+ bool isSequential() const;
+
+ int handle() const;
+ virtual QString fileName() const;
+
+ qint64 pos() const;
+ bool seek(qint64 offset);
+ bool atEnd() const;
+ bool flush();
+
+ qint64 size() const;
+
+ virtual bool resize(qint64 sz);
+ virtual Permissions permissions() const;
+ virtual bool setPermissions(Permissions permissionSpec);
+
+ enum MemoryMapFlags {
+ NoOptions = 0
+ };
+
+ uchar *map(qint64 offset, qint64 size, MemoryMapFlags flags = NoOptions);
+ bool unmap(uchar *address);
+
+protected:
+ QFileDevice();
+#ifdef QT_NO_QOBJECT
+ QFileDevice(QFileDevicePrivate &dd);
+#else
+ explicit QFileDevice(QObject *parent);
+ QFileDevice(QFileDevicePrivate &dd, QObject *parent = 0);
+#endif
+
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+ qint64 readLineData(char *data, qint64 maxlen);
+
+private:
+ Q_DISABLE_COPY(QFileDevice)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QFileDevice::Permissions)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFILEDEVICE_H
diff --git a/src/gui/image/qvolatileimage_p.h b/src/corelib/io/qfiledevice_p.h
similarity index 59%
rename from src/gui/image/qvolatileimage_p.h
rename to src/corelib/io/qfiledevice_p.h
index 808def7c32c..2550cd73a22 100644
--- a/src/gui/image/qvolatileimage_p.h
+++ b/src/corelib/io/qfiledevice_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QVOLATILEIMAGE_P_H
-#define QVOLATILEIMAGE_P_H
+#ifndef QFILEDEVICE_P_H
+#define QFILEDEVICE_P_H
//
// W A R N I N G
@@ -53,48 +53,52 @@
// We mean it.
//
-#include
-#include
+#include "private/qiodevice_p.h"
+#include "private/qringbuffer_p.h"
QT_BEGIN_NAMESPACE
-class QVolatileImageData;
+class QAbstractFileEngine;
+class QFSFileEngine;
-class Q_GUI_EXPORT QVolatileImage
+class QFileDevicePrivate : public QIODevicePrivate
{
-public:
- QVolatileImage();
- QVolatileImage(int w, int h, QImage::Format format);
- explicit QVolatileImage(const QImage &sourceImage);
- explicit QVolatileImage(void *nativeImage, void *nativeMask = 0);
- QVolatileImage(const QVolatileImage &other);
- ~QVolatileImage();
- QVolatileImage &operator=(const QVolatileImage &rhs);
+ Q_DECLARE_PUBLIC(QFileDevice)
+protected:
+ QFileDevicePrivate();
+ ~QFileDevicePrivate();
- bool isNull() const;
- QImage::Format format() const;
- int width() const;
- int height() const;
- int bytesPerLine() const;
- int byteCount() const;
- int depth() const;
- bool hasAlphaChannel() const;
- void beginDataAccess() const;
- void endDataAccess(bool readOnly = false) const;
- uchar *bits();
- const uchar *constBits() const;
- bool ensureFormat(QImage::Format format);
- QImage toImage() const;
- QImage &imageRef();
- QPaintEngine *paintEngine();
- void fill(uint pixelValue);
- void *duplicateNativeImage() const;
- void copyFrom(QVolatileImage *source, const QRect &rect);
+ virtual QAbstractFileEngine *engine() const;
-private:
- QSharedDataPointer d;
+ QFileDevice::FileHandleFlags handleFlags;
+
+ mutable QAbstractFileEngine *fileEngine;
+ bool lastWasWrite;
+ QRingBuffer writeBuffer;
+ inline bool ensureFlushed() const;
+
+ bool putCharHelper(char c);
+
+ QFileDevice::FileError error;
+ void setError(QFileDevice::FileError err);
+ void setError(QFileDevice::FileError err, const QString &errorString);
+ void setError(QFileDevice::FileError err, int errNum);
+
+ mutable qint64 cachedSize;
};
+inline bool QFileDevicePrivate::ensureFlushed() const
+{
+ // This function ensures that the write buffer has been flushed (const
+ // because certain const functions need to call it.
+ if (lastWasWrite) {
+ const_cast(this)->lastWasWrite = false;
+ if (!const_cast(q_func())->flush())
+ return false;
+ }
+ return true;
+}
+
QT_END_NAMESPACE
-#endif // QVOLATILEIMAGE_P_H
+#endif // QFILEDEVICE_P_H
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index a7fb0fb6c7b..044c71d00a9 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -812,7 +812,7 @@ QString QFileInfo::suffix() const
/*!
Returns the path of the object's parent directory as a QDir object.
- \bold{Note:} The QDir returned always corresponds to the object's
+ \b{Note:} The QDir returned always corresponds to the object's
parent directory, even if the QFileInfo represents a directory.
For each of the following, dir() returns a QDir for
@@ -901,7 +901,7 @@ bool QFileInfo::isExecutable() const
/*!
Returns true if this is a `hidden' file; otherwise returns false.
- \bold{Note:} This function returns true for the special entries
+ \b{Note:} This function returns true for the special entries
"." and ".." on Unix, even though QDir::entryList threats them as shown.
*/
bool QFileInfo::isHidden() const
@@ -923,7 +923,7 @@ bool QFileInfo::isHidden() const
Returns false if the file is otherwise supported by a virtual file system
inside Qt, such as \l{the Qt Resource System}.
- \bold{Note:} Native paths may still require conversion of path separators
+ \b{Note:} Native paths may still require conversion of path separators
and character encoding, depending on platform and input requirements of the
native API.
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 5e466e480db..e8ff6107ce4 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -476,12 +476,12 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
slash = dirName.length();
}
if (slash) {
- QByteArray chunk = QFile::encodeName(dirName.left(slash));
+ const QByteArray chunk = QFile::encodeName(dirName.left(slash));
QT_STATBUF st;
- if (QT_STAT(chunk, &st) != -1) {
+ if (QT_STAT(chunk.constData(), &st) != -1) {
if ((st.st_mode & S_IFMT) != S_IFDIR)
return false;
- } else if (QT_MKDIR(chunk, 0777) != 0) {
+ } else if (QT_MKDIR(chunk.constData(), 0777) != 0) {
return false;
}
}
@@ -492,7 +492,7 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
if (dirName.endsWith(QLatin1Char('/')))
dirName.chop(1);
#endif
- return (QT_MKDIR(QFile::encodeName(dirName), 0777) == 0);
+ return (QT_MKDIR(QFile::encodeName(dirName).constData(), 0777) == 0);
}
//static
@@ -501,12 +501,12 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo
if (removeEmptyParents) {
QString dirName = QDir::cleanPath(entry.filePath());
for (int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) {
- QByteArray chunk = QFile::encodeName(dirName.left(slash));
+ const QByteArray chunk = QFile::encodeName(dirName.left(slash));
QT_STATBUF st;
- if (QT_STAT(chunk, &st) != -1) {
+ if (QT_STAT(chunk.constData(), &st) != -1) {
if ((st.st_mode & S_IFMT) != S_IFDIR)
return false;
- if (::rmdir(chunk) != 0)
+ if (::rmdir(chunk.constData()) != 0)
return oldslash != 0;
} else {
return false;
@@ -515,7 +515,7 @@ bool QFileSystemEngine::removeDirectory(const QFileSystemEntry &entry, bool remo
}
return true;
}
- return rmdir(QFile::encodeName(entry.filePath())) == 0;
+ return rmdir(QFile::encodeName(entry.filePath()).constData()) == 0;
}
//static
@@ -623,7 +623,7 @@ QString QFileSystemEngine::tempPath()
bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &path)
{
int r;
- r = QT_CHDIR(path.nativeFilePath());
+ r = QT_CHDIR(path.nativeFilePath().constData());
return r >= 0;
}
diff --git a/src/corelib/io/qfilesystemwatcher_polling_p.h b/src/corelib/io/qfilesystemwatcher_polling_p.h
index 14f6345412a..e50082c6d32 100644
--- a/src/corelib/io/qfilesystemwatcher_polling_p.h
+++ b/src/corelib/io/qfilesystemwatcher_polling_p.h
@@ -58,6 +58,7 @@
#include
#include
#include
+#include
#include "qfilesystemwatcher_p.h"
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 3d9391ebaa7..1cdfc61627b 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -163,12 +163,12 @@ QIODevicePrivate::~QIODevicePrivate()
random-access devices and sequential devices.
\list
- \o Random-access devices support seeking to arbitrary
+ \li Random-access devices support seeking to arbitrary
positions using seek(). The current position in the file is
available by calling pos(). QFile and QBuffer are examples of
random-access devices.
- \o Sequential devices don't support seeking to arbitrary
+ \li Sequential devices don't support seeking to arbitrary
positions. The data must be read in one pass. The functions
pos() and size() don't work for sequential devices.
QTcpSocket and QProcess are examples of sequential devices.
@@ -199,14 +199,14 @@ QIODevicePrivate::~QIODevicePrivate()
a separate thread:
\list
- \o waitForReadyRead() - This function suspends operation in the
+ \li waitForReadyRead() - This function suspends operation in the
calling thread until new data is available for reading.
- \o waitForBytesWritten() - This function suspends operation in the
+ \li waitForBytesWritten() - This function suspends operation in the
calling thread until one payload of data has been written to the
device.
- \o waitFor....() - Subclasses of QIODevice implement blocking
+ \li waitFor....() - Subclasses of QIODevice implement blocking
functions for device-specific operations. For example, QProcess
has a function called waitForStarted() which suspends operation in
the calling thread until the process has started.
@@ -1038,9 +1038,9 @@ QByteArray QIODevice::readAll()
Data is read until either of the following conditions are met:
\list
- \o The first '\n' character is read.
- \o \a maxSize - 1 bytes are read.
- \o The end of the device data is detected.
+ \li The first '\n' character is read.
+ \li \a maxSize - 1 bytes are read.
+ \li The end of the device data is detected.
\endlist
For example, the following code reads a line of characters from a
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 7a81313fa06..640704ec86f 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -532,15 +532,15 @@ void QProcessPrivate::Channel::clear()
certain signals are emitted:
\list
- \o waitForStarted() blocks until the process has started.
+ \li waitForStarted() blocks until the process has started.
- \o waitForReadyRead() blocks until new data is
+ \li waitForReadyRead() blocks until new data is
available for reading on the current read channel.
- \o waitForBytesWritten() blocks until one payload of
+ \li waitForBytesWritten() blocks until one payload of
data has been written to the process.
- \o waitForFinished() blocks until the process has finished.
+ \li waitForFinished() blocks until the process has finished.
\endlist
Calling these functions from the main thread (the thread that
@@ -1910,7 +1910,7 @@ QByteArray QProcess::readAllStandardError()
\note No further splitting of the arguments is performed.
- \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
\sa pid(), started(), waitForStarted()
*/
@@ -2149,10 +2149,10 @@ int QProcess::execute(const QString &program)
Note that arguments that contain spaces are not passed to the
process as separate arguments.
- \bold{Unix:} The started process will run in its own session and act
+ \b{Unix:} The started process will run in its own session and act
like a daemon.
- \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
The started process will run as a regular standalone process.
The process will be started in the directory \a workingDirectory.
@@ -2183,10 +2183,10 @@ bool QProcess::startDetached(const QString &program,
\note Arguments that contain spaces are not passed to the
process as separate arguments.
- \bold{Unix:} The started process will run in its own session and act
+ \b{Unix:} The started process will run in its own session and act
like a daemon.
- \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
+ \b{Windows:} Arguments that contain spaces are wrapped in quotes.
The started process will run as a regular standalone process.
*/
bool QProcess::startDetached(const QString &program,
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index a52fd46c97f..f7c2f965d5d 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -530,8 +530,6 @@ void QProcessPrivate::startProcess()
notifier->start(NOTIFYTIMEOUT);
}
- // give the process a chance to start ...
- Sleep(SLEEPMIN * 2);
_q_startupNotification();
}
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index e46ab260b0b..fb3a24b940f 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -114,7 +114,7 @@ class QResourceRoot
};
const uchar *tree, *names, *payloads;
inline int findOffset(int node) const { return node * 14; } //sizeof each tree element
- int hash(int node) const;
+ uint hash(int node) const;
QString name(int node) const;
short flags(int node) const;
public:
@@ -594,7 +594,7 @@ QResource::searchPaths()
return *resourceSearchPaths();
}
-inline int QResourceRoot::hash(int node) const
+inline uint QResourceRoot::hash(int node) const
{
if(!node) //root
return 0;
@@ -673,13 +673,13 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const
qDebug() << " " << child+j << " :: " << name(child+j);
}
#endif
- const int h = qHash(segment);
+ const uint h = qHash(segment);
//do the binary search for the hash
int l = 0, r = child_count-1;
int sub_node = (l+r+1)/2;
while(r != l) {
- const int sub_node_hash = hash(child+sub_node);
+ const uint sub_node_hash = hash(child+sub_node);
if(h == sub_node_hash)
break;
else if(h < sub_node_hash)
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 2021c42c4d2..1ec0390235c 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1752,10 +1752,10 @@ bool QConfFileSettingsPrivate::readIniFile(const QByteArray &data,
iniSection = iniSection.trimmed();
- if (qstricmp(iniSection, "general") == 0) {
+ if (qstricmp(iniSection.constData(), "general") == 0) {
currentSection.clear();
} else {
- if (qstricmp(iniSection, "%general") == 0) {
+ if (qstricmp(iniSection.constData(), "%general") == 0) {
currentSection = QLatin1String(iniSection.constData() + 1);
} else {
currentSection.clear();
@@ -1912,7 +1912,7 @@ bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const ParsedSetti
if (realSection.isEmpty()) {
realSection = "[General]";
- } else if (qstricmp(realSection, "general") == 0) {
+ } else if (qstricmp(realSection.constData(), "general") == 0) {
realSection = "[%General]";
} else {
realSection.prepend('[');
@@ -2112,15 +2112,15 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
avoid portability problems, follow these simple rules:
\list 1
- \o Always refer to the same key using the same case. For example,
+ \li Always refer to the same key using the same case. For example,
if you refer to a key as "text fonts" in one place in your
code, don't refer to it as "Text Fonts" somewhere else.
- \o Avoid key names that are identical except for the case. For
+ \li Avoid key names that are identical except for the case. For
example, if you have a key called "MainWindow", don't try to
save another key as "mainwindow".
- \o Do not use slashes ('/' and '\\') in section or key names; the
+ \li Do not use slashes ('/' and '\\') in section or key names; the
backslash character is used to separate sub keys (see below). On
windows '\\' are converted by QSettings to '/', which makes
them identical.
@@ -2156,10 +2156,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
that order:
\list 1
- \o a user-specific location for the Star Runner application
- \o a user-specific location for all applications by MySoft
- \o a system-wide location for the Star Runner application
- \o a system-wide location for all applications by MySoft
+ \li a user-specific location for the Star Runner application
+ \li a user-specific location for all applications by MySoft
+ \li a system-wide location for the Star Runner application
+ \li a system-wide location for all applications by MySoft
\endlist
(See \l{Platform-Specific Notes} below for information on what
@@ -2184,17 +2184,17 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet doc/src/snippets/settings/settings.cpp 14
The table below summarizes which QSettings objects access
- which location. "\bold{X}" means that the location is the main
+ which location. "\b{X}" means that the location is the main
location associated to the QSettings object and is used both
for reading and for writing; "o" means that the location is used
as a fallback when reading.
\table
- \header \o Locations \o \c{obj1} \o \c{obj2} \o \c{obj3} \o \c{obj4}
- \row \o 1. User, Application \o \bold{X} \o \o \o
- \row \o 2. User, Organization \o o \o \bold{X} \o \o
- \row \o 3. System, Application \o o \o \o \bold{X} \o
- \row \o 4. System, Organization \o o \o o \o o \o \bold{X}
+ \header \li Locations \li \c{obj1} \li \c{obj2} \li \c{obj3} \li \c{obj4}
+ \row \li 1. User, Application \li \b{X} \li \li \li
+ \row \li 2. User, Organization \li o \li \b{X} \li \li
+ \row \li 3. System, Application \li o \li \li \b{X} \li
+ \row \li 4. System, Organization \li o \li o \li o \li \b{X}
\endtable
The beauty of this mechanism is that it works on all platforms
@@ -2276,30 +2276,30 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
following files are used by default:
\list 1
- \o \c{$HOME/.config/MySoft/Star Runner.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.conf})
- \o \c{$HOME/.config/MySoft.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.conf})
- \o \c{/etc/xdg/MySoft/Star Runner.conf}
- \o \c{/etc/xdg/MySoft.conf}
+ \li \c{$HOME/.config/MySoft/Star Runner.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.conf})
+ \li \c{$HOME/.config/MySoft.conf} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.conf})
+ \li \c{/etc/xdg/MySoft/Star Runner.conf}
+ \li \c{/etc/xdg/MySoft.conf}
\endlist
On Mac OS X versions 10.2 and 10.3, these files are used by
default:
\list 1
- \o \c{$HOME/Library/Preferences/com.MySoft.Star Runner.plist}
- \o \c{$HOME/Library/Preferences/com.MySoft.plist}
- \o \c{/Library/Preferences/com.MySoft.Star Runner.plist}
- \o \c{/Library/Preferences/com.MySoft.plist}
+ \li \c{$HOME/Library/Preferences/com.MySoft.Star Runner.plist}
+ \li \c{$HOME/Library/Preferences/com.MySoft.plist}
+ \li \c{/Library/Preferences/com.MySoft.Star Runner.plist}
+ \li \c{/Library/Preferences/com.MySoft.plist}
\endlist
On Windows, NativeFormat settings are stored in the following
registry paths:
\list 1
- \o \c{HKEY_CURRENT_USER\Software\MySoft\Star Runner}
- \o \c{HKEY_CURRENT_USER\Software\MySoft}
- \o \c{HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner}
- \o \c{HKEY_LOCAL_MACHINE\Software\MySoft}
+ \li \c{HKEY_CURRENT_USER\Software\MySoft\Star Runner}
+ \li \c{HKEY_CURRENT_USER\Software\MySoft}
+ \li \c{HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner}
+ \li \c{HKEY_LOCAL_MACHINE\Software\MySoft}
\endlist
\note On Windows, for 32-bit programs running in WOW64 mode, settings are
@@ -2310,19 +2310,19 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
used on Unix and Mac OS X:
\list 1
- \o \c{$HOME/.config/MySoft/Star Runner.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.ini})
- \o \c{$HOME/.config/MySoft.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.ini})
- \o \c{/etc/xdg/MySoft/Star Runner.ini}
- \o \c{/etc/xdg/MySoft.ini}
+ \li \c{$HOME/.config/MySoft/Star Runner.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft/Star Runner.ini})
+ \li \c{$HOME/.config/MySoft.ini} (Qt for Embedded Linux: \c{$HOME/Settings/MySoft.ini})
+ \li \c{/etc/xdg/MySoft/Star Runner.ini}
+ \li \c{/etc/xdg/MySoft.ini}
\endlist
On Windows, the following files are used:
\list 1
- \o \c{%APPDATA%\MySoft\Star Runner.ini}
- \o \c{%APPDATA%\MySoft.ini}
- \o \c{%COMMON_APPDATA%\MySoft\Star Runner.ini}
- \o \c{%COMMON_APPDATA%\MySoft.ini}
+ \li \c{%APPDATA%\MySoft\Star Runner.ini}
+ \li \c{%APPDATA%\MySoft.ini}
+ \li \c{%COMMON_APPDATA%\MySoft\Star Runner.ini}
+ \li \c{%COMMON_APPDATA%\MySoft.ini}
\endlist
The \c %APPDATA% path is usually \tt{C:\\Documents and
@@ -2395,20 +2395,20 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
application:
\list
- \o The Windows system registry has the following limitations: A
+ \li The Windows system registry has the following limitations: A
subkey may not exceed 255 characters, an entry's value may
not exceed 16,383 characters, and all the values of a key may
not exceed 65,535 characters. One way to work around these
limitations is to store the settings using the IniFormat
instead of the NativeFormat.
- \o On Mac OS X, allKeys() will return some extra keys for global
+ \li On Mac OS X, allKeys() will return some extra keys for global
settings that apply to all applications. These keys can be
read using value() but cannot be changed, only shadowed.
Calling setFallbacksEnabled(false) will hide these global
settings.
- \o On Mac OS X, the CFPreferences API used by QSettings expects
+ \li On Mac OS X, the CFPreferences API used by QSettings expects
Internet domain names rather than organization names. To
provide a uniform API, QSettings derives a fake domain name
from the organization name (unless the organization name
@@ -2425,7 +2425,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet doc/src/snippets/code/src_corelib_io_qsettings.cpp 7
- \o On Unix and Mac OS X systems, the advisory file locking is disabled
+ \li On Unix and Mac OS X systems, the advisory file locking is disabled
if NFS (or AutoFS or CacheFS) is detected to work around a bug in the
NFS fcntl() implementation, which hangs forever if statd or lockd aren't
running. Also, the locking isn't performed when accessing \c .plist
@@ -2485,7 +2485,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
follow what Microsoft does, with the following exceptions:
\list
- \o If you store types that QVariant can't convert to QString
+ \li If you store types that QVariant can't convert to QString
(e.g., QPoint, QRect, and QSize), Qt uses an \c{@}-based
syntax to encode the type. For example:
@@ -2496,7 +2496,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
followed by a Qt type (\c Point, \c Rect, \c Size, etc.) is
treated as a normal character.
- \o Although backslash is a special character in INI files, most
+ \li Although backslash is a special character in INI files, most
Windows applications don't escape backslashes (\c{\}) in file
paths:
@@ -2505,7 +2505,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
QSettings always treats backslash as a special character and
provides no API for reading or writing such entries.
- \o The INI file format has severe restrictions on the syntax of
+ \li The INI file format has severe restrictions on the syntax of
a key. Qt works around this by using \c % as an escape
character in keys. In addition, if you save a top-level
setting (a key with no slashes in it, e.g., "someKey"), it
@@ -2514,7 +2514,7 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
such as "General/someKey", the key will be located in the
"%General" section, \e not in the "General" section.
- \o Following the philosophy that we should be liberal in what
+ \li Following the philosophy that we should be liberal in what
we accept and conservative in what we generate, QSettings
will accept Latin-1 encoded INI files, but generate pure
ASCII files, where non-ASCII values are encoded using standard
@@ -2632,10 +2632,10 @@ QSettings::QSettings(Format format, Scope scope, const QString &organization,
be aware of the following limitations:
\list
- \o QSettings provides no way of reading INI "path" entries, i.e., entries
+ \li QSettings provides no way of reading INI "path" entries, i.e., entries
with unescaped slash characters. (This is because these entries are
ambiguous and cannot be resolved automatically.)
- \o In INI files, QSettings uses the \c @ character as a metacharacter in some
+ \li In INI files, QSettings uses the \c @ character as a metacharacter in some
contexts, to encode Qt-specific data types (e.g., \c @Rect), and might
therefore misinterpret it when it occurs in pure INI files.
\endlist
@@ -2933,9 +2933,9 @@ QSettings::Status QSettings::status() const
This will set the value of three settings:
\list
- \o \c mainwindow/size
- \o \c mainwindow/fullScreen
- \o \c outputpanel/visible
+ \li \c mainwindow/size
+ \li \c mainwindow/fullScreen
+ \li \c outputpanel/visible
\endlist
Call endGroup() to reset the current group to what it was before
@@ -3021,14 +3021,14 @@ int QSettings::beginReadArray(const QString &prefix)
The generated keys will have the form
\list
- \o \c logins/size
- \o \c logins/1/userName
- \o \c logins/1/password
- \o \c logins/2/userName
- \o \c logins/2/password
- \o \c logins/3/userName
- \o \c logins/3/password
- \o ...
+ \li \c logins/size
+ \li \c logins/1/userName
+ \li \c logins/1/password
+ \li \c logins/2/userName
+ \li \c logins/2/password
+ \li \c logins/3/userName
+ \li \c logins/3/password
+ \li ...
\endlist
To read back an array, use beginReadArray().
@@ -3412,15 +3412,15 @@ void QSettings::setUserIniPath(const QString &dir)
The table below summarizes the default values:
\table
- \header \o Platform \o Format \o Scope \o Path
- \row \o{1,2} Windows \o{1,2} IniFormat \o UserScope \o \c %APPDATA%
- \row \o SystemScope \o \c %COMMON_APPDATA%
- \row \o{1,2} Unix \o{1,2} NativeFormat, IniFormat \o UserScope \o \c $HOME/.config
- \row \o SystemScope \o \c /etc/xdg
- \row \o{1,2} Qt for Embedded Linux \o{1,2} NativeFormat, IniFormat \o UserScope \o \c $HOME/Settings
- \row \o SystemScope \o \c /etc/xdg
- \row \o{1,2} Mac OS X \o{1,2} IniFormat \o UserScope \o \c $HOME/.config
- \row \o SystemScope \o \c /etc/xdg
+ \header \li Platform \li Format \li Scope \li Path
+ \row \li{1,2} Windows \li{1,2} IniFormat \li UserScope \li \c %APPDATA%
+ \row \li SystemScope \li \c %COMMON_APPDATA%
+ \row \li{1,2} Unix \li{1,2} NativeFormat, IniFormat \li UserScope \li \c $HOME/.config
+ \row \li SystemScope \li \c /etc/xdg
+ \row \li{1,2} Qt for Embedded Linux \li{1,2} NativeFormat, IniFormat \li UserScope \li \c $HOME/Settings
+ \row \li SystemScope \li \c /etc/xdg
+ \row \li{1,2} Mac OS X \li{1,2} IniFormat \li UserScope \li \c $HOME/.config
+ \row \li SystemScope \li \c /etc/xdg
\endtable
The default UserScope paths on Unix and Mac OS X (\c
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index 62c846738e2..54997517517 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -42,6 +42,7 @@
#include "qstandardpaths.h"
#include
#include
+#include
#include
#include
#include
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index dd0ab851191..cb703df8c6f 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -90,13 +90,13 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
\list
- \o Chunk by chunk, by calling readLine() or readAll().
+ \li Chunk by chunk, by calling readLine() or readAll().
- \o Word by word. QTextStream supports streaming into QStrings,
+ \li Word by word. QTextStream supports streaming into QStrings,
QByteArrays and char* buffers. Words are delimited by space, and
leading white space is automatically skipped.
- \o Character by character, by streaming into QChar or char types.
+ \li Character by character, by streaming into QChar or char types.
This method is often used for convenient input handling when
parsing files, independent of character encoding and end-of-line
semantics. To skip white space, call skipWhiteSpace().
@@ -134,31 +134,31 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
defines several global manipulator functions:
\table
- \header \o Manipulator \o Description
- \row \o \c bin \o Same as setIntegerBase(2).
- \row \o \c oct \o Same as setIntegerBase(8).
- \row \o \c dec \o Same as setIntegerBase(10).
- \row \o \c hex \o Same as setIntegerBase(16).
- \row \o \c showbase \o Same as setNumberFlags(numberFlags() | ShowBase).
- \row \o \c forcesign \o Same as setNumberFlags(numberFlags() | ForceSign).
- \row \o \c forcepoint \o Same as setNumberFlags(numberFlags() | ForcePoint).
- \row \o \c noshowbase \o Same as setNumberFlags(numberFlags() & ~ShowBase).
- \row \o \c noforcesign \o Same as setNumberFlags(numberFlags() & ~ForceSign).
- \row \o \c noforcepoint \o Same as setNumberFlags(numberFlags() & ~ForcePoint).
- \row \o \c uppercasebase \o Same as setNumberFlags(numberFlags() | UppercaseBase).
- \row \o \c uppercasedigits \o Same as setNumberFlags(numberFlags() | UppercaseDigits).
- \row \o \c lowercasebase \o Same as setNumberFlags(numberFlags() & ~UppercaseBase).
- \row \o \c lowercasedigits \o Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
- \row \o \c fixed \o Same as setRealNumberNotation(FixedNotation).
- \row \o \c scientific \o Same as setRealNumberNotation(ScientificNotation).
- \row \o \c left \o Same as setFieldAlignment(AlignLeft).
- \row \o \c right \o Same as setFieldAlignment(AlignRight).
- \row \o \c center \o Same as setFieldAlignment(AlignCenter).
- \row \o \c endl \o Same as operator<<('\n') and flush().
- \row \o \c flush \o Same as flush().
- \row \o \c reset \o Same as reset().
- \row \o \c ws \o Same as skipWhiteSpace().
- \row \o \c bom \o Same as setGenerateByteOrderMark(true).
+ \header \li Manipulator \li Description
+ \row \li \c bin \li Same as setIntegerBase(2).
+ \row \li \c oct \li Same as setIntegerBase(8).
+ \row \li \c dec \li Same as setIntegerBase(10).
+ \row \li \c hex \li Same as setIntegerBase(16).
+ \row \li \c showbase \li Same as setNumberFlags(numberFlags() | ShowBase).
+ \row \li \c forcesign \li Same as setNumberFlags(numberFlags() | ForceSign).
+ \row \li \c forcepoint \li Same as setNumberFlags(numberFlags() | ForcePoint).
+ \row \li \c noshowbase \li Same as setNumberFlags(numberFlags() & ~ShowBase).
+ \row \li \c noforcesign \li Same as setNumberFlags(numberFlags() & ~ForceSign).
+ \row \li \c noforcepoint \li Same as setNumberFlags(numberFlags() & ~ForcePoint).
+ \row \li \c uppercasebase \li Same as setNumberFlags(numberFlags() | UppercaseBase).
+ \row \li \c uppercasedigits \li Same as setNumberFlags(numberFlags() | UppercaseDigits).
+ \row \li \c lowercasebase \li Same as setNumberFlags(numberFlags() & ~UppercaseBase).
+ \row \li \c lowercasedigits \li Same as setNumberFlags(numberFlags() & ~UppercaseDigits).
+ \row \li \c fixed \li Same as setRealNumberNotation(FixedNotation).
+ \row \li \c scientific \li Same as setRealNumberNotation(ScientificNotation).
+ \row \li \c left \li Same as setFieldAlignment(AlignLeft).
+ \row \li \c right \li Same as setFieldAlignment(AlignRight).
+ \row \li \c center \li Same as setFieldAlignment(AlignCenter).
+ \row \li \c endl \li Same as operator<<('\n') and flush().
+ \row \li \c flush \li Same as flush().
+ \row \li \c reset \li Same as reset().
+ \row \li \c ws \li Same as skipWhiteSpace().
+ \row \li \c bom \li Same as setGenerateByteOrderMark(true).
\endtable
In addition, Qt provides three global manipulators that take a
@@ -2065,12 +2065,12 @@ QTextStream &QTextStream::operator>>(char &c)
number using the following rules:
\table
- \header \o Prefix \o Base
- \row \o "0b" or "0B" \o 2 (binary)
- \row \o "0" followed by "0-7" \o 8 (octal)
- \row \o "0" otherwise \o 10 (decimal)
- \row \o "0x" or "0X" \o 16 (hexadecimal)
- \row \o "1" to "9" \o 10 (decimal)
+ \header \li Prefix \li Base
+ \row \li "0b" or "0B" \li 2 (binary)
+ \row \li "0" followed by "0-7" \li 8 (octal)
+ \row \li "0" otherwise \li 10 (decimal)
+ \row \li "0x" or "0X" \li 16 (hexadecimal)
+ \row \li "1" to "9" \li 10 (decimal)
\endtable
By calling setIntegerBase(), you can specify the integer base
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index eeeca1bf77f..9b15c1fd98c 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -112,7 +112,7 @@
dealing with URLs and strings:
\list
- \o When creating an QString to contain a URL from a QByteArray or a
+ \li When creating an QString to contain a URL from a QByteArray or a
char*, always use QString::fromUtf8().
\endlist
@@ -135,15 +135,15 @@
\list
- \o Spaces and "%20": If an encoded URL contains a space, this will be
+ \li Spaces and "%20": If an encoded URL contains a space, this will be
replaced with "%20". If a decoded URL contains "%20", this will be
replaced with a single space before the URL is parsed.
- \o Single "%" characters: Any occurrences of a percent character "%" not
+ \li Single "%" characters: Any occurrences of a percent character "%" not
followed by exactly two hexadecimal characters (e.g., "13% coverage.html")
will be replaced by "%25".
- \o Reserved and unreserved characters: An encoded URL should only
+ \li Reserved and unreserved characters: An encoded URL should only
contain a few characters as literals; all other characters should
be percent-encoded. In TolerantMode, these characters will be
automatically percent-encoded where they are not allowed:
@@ -170,6 +170,8 @@
\value RemoveQuery The query part of the URL (following a '?' character)
is removed.
\value RemoveFragment
+ \value PreferLocalFile If the URL is a local file according to isLocalFile()
+ and contains no query or fragment, a local file path is returned.
\value StripTrailingSlash The trailing slash is removed if one is present.
Note that the case folding rules in \l{RFC 3491}{Nameprep}, which QUrl
@@ -331,6 +333,7 @@ public:
void clear();
QByteArray toEncoded(QUrl::FormattingOptions options = QUrl::None) const;
+ bool isLocalFile() const;
QAtomicInt ref;
@@ -3953,6 +3956,9 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
if (options==0x100) // private - see qHash(QUrl)
return normalized();
+ if ((options & QUrl::PreferLocalFile) && isLocalFile() && !hasQuery && !hasFragment)
+ return encodedPath;
+
QByteArray url;
if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) {
@@ -5695,9 +5701,12 @@ QString QUrl::toString(FormattingOptions options) const
QString url;
+ const QString ourPath = path();
+ if ((options & QUrl::PreferLocalFile) && isLocalFile() && !d->hasQuery && !d->hasFragment)
+ return ourPath;
+
if (!(options & QUrl::RemoveScheme) && !d->scheme.isEmpty())
url += d->scheme + QLatin1Char(':');
- QString ourPath = path();
if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority) {
bool doFileScheme = d->scheme == QLatin1String("file") && ourPath.startsWith(QLatin1Char('/'));
QString tmp = d->authority(options);
@@ -5733,6 +5742,7 @@ QString QUrl::toString(FormattingOptions options) const
}
/*!
+ \since 5.0
Returns a string representation of the URL.
The output can be customized by passing flags with \a options.
@@ -5748,13 +5758,16 @@ QString QUrl::url(FormattingOptions options) const
}
/*!
+ \since 5.0
+
Returns a human-displayable string representation of the URL.
The output can be customized by passing flags with \a options.
The option RemovePassword is always enabled, since passwords
should never be shown back to users.
- The resulting QString can be passed back to a QUrl later on,
- but any password that was present initially will be lost.
+ With the default options, the resulting QString can be passed back
+ to a QUrl later on, but any password that was present initially will
+ be lost.
\sa FormattingOptions, toEncoded(), toString()
*/
@@ -6171,6 +6184,13 @@ QString QUrl::toLocalFile() const
return tmp;
}
+bool QUrlPrivate::isLocalFile() const
+{
+ if (scheme.compare(QLatin1String("file"), Qt::CaseInsensitive) != 0)
+ return false; // not file
+ return true;
+}
+
/*!
\since 4.7
Returns true if this URL is pointing to a local file path. A URL is a
@@ -6186,10 +6206,7 @@ bool QUrl::isLocalFile() const
{
if (!d) return false;
if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
-
- if (d->scheme.compare(QLatin1String("file"), Qt::CaseInsensitive) != 0)
- return false; // not file
- return true;
+ return d->isLocalFile();
}
/*!
@@ -6335,10 +6352,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\section1 Examples:
\list
- \o qt.nokia.com becomes http://qt.nokia.com
- \o ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com
- \o hostname becomes http://hostname
- \o /home/user/test.html becomes file:///home/user/test.html
+ \li qt.nokia.com becomes http://qt.nokia.com
+ \li ftp.qt.nokia.com becomes ftp://ftp.qt.nokia.com
+ \li hostname becomes http://hostname
+ \li /home/user/test.html becomes file:///home/user/test.html
\endlist
*/
QUrl QUrl::fromUserInput(const QString &userInput)
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 3e5c62cd7c7..fc492315941 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -76,6 +76,7 @@ public:
RemoveQuery = 0x40,
RemoveFragment = 0x80,
// 0x100: private: normalized
+ PreferLocalFile = 0x200,
StripTrailingSlash = 0x10000
};
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index a8c3921f453..7a1357959eb 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1161,16 +1161,16 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
\e before and \e after they occur:
\list
- \o An insertRows() implementation must call beginInsertRows() \e before
+ \li An insertRows() implementation must call beginInsertRows() \e before
inserting new rows into the data structure, and endInsertRows()
\e{immediately afterwards}.
- \o An insertColumns() implementation must call beginInsertColumns()
+ \li An insertColumns() implementation must call beginInsertColumns()
\e before inserting new columns into the data structure, and
endInsertColumns() \e{immediately afterwards}.
- \o A removeRows() implementation must call beginRemoveRows() \e before
+ \li A removeRows() implementation must call beginRemoveRows() \e before
the rows are removed from the data structure, and endRemoveRows()
\e{immediately afterwards}.
- \o A removeColumns() implementation must call beginRemoveColumns()
+ \li A removeColumns() implementation must call beginRemoveColumns()
\e before the columns are removed from the data structure, and
endRemoveColumns() \e{immediately afterwards}.
\endlist
@@ -1179,7 +1179,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
the chance to take action before any data becomes unavailable. The
encapsulation of the insert and remove operations with these begin and end
functions also enables the model to manage \l{QPersistentModelIndex}
- {persistent model indexes} correctly. \bold{If you want selections to be
+ {persistent model indexes} correctly. \b{If you want selections to be
handled properly, you must ensure that you call these functions.} If you
insert or remove an item with children, you do not need to call these
functions for the child items. In other words, the parent item will take
@@ -1338,11 +1338,11 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
layoutChanged(). In other words, when the structure changes:
\list
- \o emit layoutAboutToBeChanged
- \o Remember the QModelIndex that will change
- \o Update your internal data
- \o Call changePersistentIndex()
- \o emit layoutChanged
+ \li emit layoutAboutToBeChanged
+ \li Remember the QModelIndex that will change
+ \li Update your internal data
+ \li Call changePersistentIndex()
+ \li emit layoutChanged
\endlist
\sa layoutAboutToBeChanged(), dataChanged(), headerDataChanged(), modelReset(),
@@ -1500,7 +1500,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item have been moved to \a destinationParent
starting at the row \a destinationRow.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1516,7 +1516,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
starting at the row \a destinationRow.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1532,7 +1532,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item have been moved to \a destinationParent
starting at the column \a destinationColumn.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1548,7 +1548,7 @@ QAbstractItemModel::~QAbstractItemModel()
inclusive, under the given \a sourceParent item. They will be moved to \a destinationParent
starting at the column \a destinationColumn.
- \bold{Note:} Components connected to this signal use it to adapt to changes
+ \b{Note:} Components connected to this signal use it to adapt to changes
in the model's dimensions. It can only be emitted by the QAbstractItemModel
implementation, and cannot be explicitly emitted in subclass code.
@@ -1683,7 +1683,7 @@ bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value
Returns the data stored under the given \a role for the item referred to
by the \a index.
- \note If you do not have a value to return, return an \bold invalid
+ \note If you do not have a value to return, return an \b invalid
QVariant instead of returning 0.
\sa Qt::ItemDataRole, setData(), headerData()
@@ -2437,8 +2437,8 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare
\table 80%
\row
- \o \inlineimage modelview-begin-insert-rows.png Inserting rows
- \o Specify the first and last row numbers for the span of rows you
+ \li \inlineimage modelview-begin-insert-rows.png Inserting rows
+ \li Specify the first and last row numbers for the span of rows you
want to insert into an item in a model.
For example, as shown in the diagram, we insert three rows before
@@ -2448,8 +2448,8 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare
This inserts the three new rows as rows 2, 3, and 4.
\row
- \o \inlineimage modelview-begin-append-rows.png Appending rows
- \o To append rows, insert them after the last row.
+ \li \inlineimage modelview-begin-append-rows.png Appending rows
+ \li To append rows, insert them after the last row.
For example, as shown in the diagram, we append two rows to a
collection of 4 existing rows (ending in row 3), so \a first is 4
@@ -2503,8 +2503,8 @@ void QAbstractItemModel::endInsertRows()
\table 80%
\row
- \o \inlineimage modelview-begin-remove-rows.png Removing rows
- \o Specify the first and last row numbers for the span of rows you
+ \li \inlineimage modelview-begin-remove-rows.png Removing rows
+ \li Specify the first and last row numbers for the span of rows you
want to remove from an item in a model.
For example, as shown in the diagram, we remove the two rows from
@@ -2616,8 +2616,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
\table 80%
\row
- \o \inlineimage modelview-move-rows-1.png Moving rows to another parent
- \o Specify the first and last row numbers for the span of rows in
+ \li \inlineimage modelview-move-rows-1.png Moving rows to another parent
+ \li Specify the first and last row numbers for the span of rows in
the source parent you want to move in the model. Also specify
the row in the destination parent to move the span to.
@@ -2630,8 +2630,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in
the destination. Other affected siblings are displaced accordingly.
\row
- \o \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
- \o To append rows to another parent, move them to after the last row.
+ \li \inlineimage modelview-move-rows-2.png Moving rows to append to another parent
+ \li To append rows to another parent, move them to after the last row.
For example, as shown in the diagram, we move three rows to a
collection of 6 existing rows (ending in row 5), so \a destinationChild is 6:
@@ -2640,8 +2640,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
This moves the target rows to the end of the target parent as 6, 7 and 8.
\row
- \o \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
- \o To move rows within the same parent, specify the row to move them to.
+ \li \inlineimage modelview-move-rows-3.png Moving rows in the same parent up
+ \li To move rows within the same parent, specify the row to move them to.
For example, as shown in the diagram, we move one item from row 2 to row 0,
so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 0.
@@ -2655,8 +2655,8 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
it is already)
\row
- \o \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
- \o To move rows within the same parent, specify the row to move them to.
+ \li \inlineimage modelview-move-rows-4.png Moving rows in the same parent down
+ \li To move rows within the same parent, specify the row to move them to.
For example, as shown in the diagram, we move one item from row 2 to row 4,
so \a sourceFirst and \a sourceLast are 2 and \a destinationChild is 4.
@@ -2737,8 +2737,8 @@ void QAbstractItemModel::endMoveRows()
\table 80%
\row
- \o \inlineimage modelview-begin-insert-columns.png Inserting columns
- \o Specify the first and last column numbers for the span of columns
+ \li \inlineimage modelview-begin-insert-columns.png Inserting columns
+ \li Specify the first and last column numbers for the span of columns
you want to insert into an item in a model.
For example, as shown in the diagram, we insert three columns
@@ -2748,8 +2748,8 @@ void QAbstractItemModel::endMoveRows()
This inserts the three new columns as columns 4, 5, and 6.
\row
- \o \inlineimage modelview-begin-append-columns.png Appending columns
- \o To append columns, insert them after the last column.
+ \li \inlineimage modelview-begin-append-columns.png Appending columns
+ \li To append columns, insert them after the last column.
For example, as shown in the diagram, we append three columns to a
collection of six existing columns (ending in column 5), so
@@ -2805,8 +2805,8 @@ void QAbstractItemModel::endInsertColumns()
\table 80%
\row
- \o \inlineimage modelview-begin-remove-columns.png Removing columns
- \o Specify the first and last column numbers for the span of columns
+ \li \inlineimage modelview-begin-remove-columns.png Removing columns
+ \li Specify the first and last column numbers for the span of columns
you want to remove from an item in a model.
For example, as shown in the diagram, we remove the three columns
@@ -3135,16 +3135,16 @@ QModelIndexList QAbstractItemModel::persistentIndexList() const
are aware of any changes:
\list
- \o An insertRows() implementation must call beginInsertRows()
+ \li An insertRows() implementation must call beginInsertRows()
\e before inserting new rows into the data structure, and it must
call endInsertRows() \e{immediately afterwards}.
- \o An insertColumns() implementation must call beginInsertColumns()
+ \li An insertColumns() implementation must call beginInsertColumns()
\e before inserting new columns into the data structure, and it must
call endInsertColumns() \e{immediately afterwards}.
- \o A removeRows() implementation must call beginRemoveRows()
+ \li A removeRows() implementation must call beginRemoveRows()
\e before the rows are removed from the data structure, and it must
call endRemoveRows() \e{immediately afterwards}.
- \o A removeColumns() implementation must call beginRemoveColumns()
+ \li A removeColumns() implementation must call beginRemoveColumns()
\e before the columns are removed from the data structure, and it must
call endRemoveColumns() \e{immediately afterwards}.
\endlist
@@ -3271,10 +3271,10 @@ bool QAbstractTableModel::hasChildren(const QModelIndex &parent) const
functions so that all connected views are aware of any changes:
\list
- \o An insertRows() implementation must call beginInsertRows()
+ \li An insertRows() implementation must call beginInsertRows()
\e before inserting new rows into the data structure, and it must
call endInsertRows() \e{immediately afterwards}.
- \o A removeRows() implementation must call beginRemoveRows()
+ \li A removeRows() implementation must call beginRemoveRows()
\e before the rows are removed from the data structure, and it must
call endRemoveRows() \e{immediately afterwards}.
\endlist
diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h
index 3c821990380..d80fcb683ce 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.h
+++ b/src/corelib/itemmodels/qabstractproxymodel.h
@@ -59,7 +59,7 @@ class Q_CORE_EXPORT QAbstractProxyModel : public QAbstractItemModel
Q_OBJECT
public:
- QAbstractProxyModel(QObject *parent = 0);
+ explicit QAbstractProxyModel(QObject *parent = 0);
~QAbstractProxyModel();
virtual void setSourceModel(QAbstractItemModel *sourceModel);
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index b7ef69423f1..ae9affb8627 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -2531,16 +2531,16 @@ void QSortFilterProxyModel::invalidateFilter()
the following QVariant types:
\list
- \o QVariant::Int
- \o QVariant::UInt
- \o QVariant::LongLong
- \o QVariant::ULongLong
- \o QVariant::Double
- \o QVariant::Char
- \o QVariant::Date
- \o QVariant::Time
- \o QVariant::DateTime
- \o QVariant::String
+ \li QVariant::Int
+ \li QVariant::UInt
+ \li QVariant::LongLong
+ \li QVariant::ULongLong
+ \li QVariant::Double
+ \li QVariant::Char
+ \li QVariant::Date
+ \li QVariant::Time
+ \li QVariant::DateTime
+ \li QVariant::String
\endlist
Any other type will be converted to a QString using
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h
index 8c7433d3076..f18b1fccb1d 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.h
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.h
@@ -73,7 +73,7 @@ class Q_CORE_EXPORT QSortFilterProxyModel : public QAbstractProxyModel
Q_PROPERTY(int filterRole READ filterRole WRITE setFilterRole)
public:
- QSortFilterProxyModel(QObject *parent = 0);
+ explicit QSortFilterProxyModel(QObject *parent = 0);
~QSortFilterProxyModel();
void setSourceModel(QAbstractItemModel *sourceModel);
diff --git a/src/corelib/itemmodels/qstringlistmodel.h b/src/corelib/itemmodels/qstringlistmodel.h
index d8b3f87f4a9..a6bc4e7bd36 100644
--- a/src/corelib/itemmodels/qstringlistmodel.h
+++ b/src/corelib/itemmodels/qstringlistmodel.h
@@ -57,7 +57,7 @@ class Q_CORE_EXPORT QStringListModel : public QAbstractListModel
Q_OBJECT
public:
explicit QStringListModel(QObject *parent = 0);
- QStringListModel(const QStringList &strings, QObject *parent = 0);
+ explicit QStringListModel(const QStringList &strings, QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index 55c37988e2d..0742ced39ba 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -309,6 +309,7 @@ public:
{
d->length = str.length();
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ const qle_ushort *uc = (const qle_ushort *)str.unicode();
for (int i = 0; i < str.length(); ++i)
d->utf16[i] = uc[i];
#else
@@ -359,7 +360,7 @@ public:
QString str(l, Qt::Uninitialized);
QChar *ch = str.data();
for (int i = 0; i < l; ++i)
- ch[i] = d->utf16[i];
+ ch[i] = QChar(d->utf16[i]);
return str;
#endif
}
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index 0eb1974147b..433a68105d0 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include "qjsonwriter_p.h"
@@ -559,7 +560,7 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
/*! \typedef QJsonArray::iterator::iterator_category
- A synonym for \i {std::random_access_iterator_tag} indicating
+ A synonym for \e {std::random_access_iterator_tag} indicating
this iterator is a random access iterator.
*/
@@ -793,7 +794,7 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
/*! \typedef QJsonArray::const_iterator::iterator_category
- A synonym for \i {std::random_access_iterator_tag} indicating
+ A synonym for \e {std::random_access_iterator_tag} indicating
this iterator is a random access iterator.
*/
diff --git a/src/corelib/json/qjsondocument.cpp b/src/corelib/json/qjsondocument.cpp
index 8a7fa760ae9..c2204bf6960 100644
--- a/src/corelib/json/qjsondocument.cpp
+++ b/src/corelib/json/qjsondocument.cpp
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include
#include "qjsonwriter_p.h"
#include "qjsonparser_p.h"
diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp
index b7af8c22cf0..cfe71e8959e 100644
--- a/src/corelib/json/qjsonobject.cpp
+++ b/src/corelib/json/qjsonobject.cpp
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
#include "qjson_p.h"
#include "qjsonwriter_p.h"
@@ -568,7 +569,7 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
/*! \typedef QJsonObject::iterator::iterator_category
- A synonym for \i {std::bidirectional_iterator_tag} indicating
+ A synonym for \e {std::bidirectional_iterator_tag} indicating
this iterator is a bidirectional iterator.
*/
@@ -757,7 +758,7 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const
/*! \typedef QJsonObject::const_iterator::iterator_category
- A synonym for \i {std::bidirectional_iterator_tag} indicating
+ A synonym for \e {std::bidirectional_iterator_tag} indicating
this iterator is a bidirectional iterator.
*/
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index 16eedadf1ae..a83685da227 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -584,9 +584,9 @@ static inline bool addHexDigit(char digit, uint *result)
if (digit >= '0' && digit <= '9')
*result |= (digit - '0');
else if (digit >= 'a' && digit <= 'f')
- *result |= (digit - 'a');
+ *result |= (digit - 'a') + 10;
else if (digit >= 'A' && digit <= 'F')
- *result |= (digit - 'A');
+ *result |= (digit - 'A') + 10;
else
return false;
return true;
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index ec63db79f5a..2eedef67ce3 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -64,12 +64,12 @@ QT_BEGIN_NAMESPACE
JSON is a format to store structured data. It has 6 basic data types:
\list
- \o bool QJsonValue::Bool
- \o double QJsonValue::Double
- \o string QJsonValue::String
- \o array QJsonValue::Array
- \o object QJsonValue::Object
- \o null QJsonValue::Null
+ \li bool QJsonValue::Bool
+ \li double QJsonValue::Double
+ \li string QJsonValue::String
+ \li array QJsonValue::Array
+ \li object QJsonValue::Object
+ \li null QJsonValue::Null
\endlist
A value can represent any of the above data types. In addition, QJsonValue has one special
@@ -260,16 +260,16 @@ QJsonValue &QJsonValue::operator =(const QJsonValue &other)
The conversion will convert QVariant types as follows:
\list
- \o QVariant::Bool to Bool
- \o QVariant::Int
- \o QVariant::Double
- \o QVariant::LongLong
- \o QVariant::ULongLong
- \o QVariant::UInt to Double
- \o QVariant::String to String
- \o QVariant::StringList
- \o QVariant::VariantList to Array
- \o QVariant::VariantMap to Object
+ \li QVariant::Bool to Bool
+ \li QVariant::Int
+ \li QVariant::Double
+ \li QVariant::LongLong
+ \li QVariant::ULongLong
+ \li QVariant::UInt to Double
+ \li QVariant::String to String
+ \li QVariant::StringList
+ \li QVariant::VariantList to Array
+ \li QVariant::VariantMap to Object
\endlist
For all other QVariant types a conversion to a QString will be attempted. If the returned string
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 3075eab7530..b98f3f4a308 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -167,7 +167,7 @@ QAbstractEventDispatcher::~QAbstractEventDispatcher()
event dispatcher exists for the specified thread, this function
returns 0.
- \bold{Note:} If Qt is built without thread support, the \a thread
+ \b{Note:} If Qt is built without thread support, the \a thread
argument is ignored.
*/
QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
@@ -192,10 +192,10 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
\list
- \i If events are available, this function returns after processing
+ \li If events are available, this function returns after processing
them.
- \i If no events are available, this function will wait until more
+ \li If no events are available, this function will wait until more
are available and return after processing newly available events.
\endlist
@@ -204,7 +204,7 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
and no events are available, this function will return
immediately.
- \bold{Note:} This function does not process events continuously; it
+ \b{Note:} This function does not process events continuously; it
returns after all available events are processed.
\sa hasPendingEvents()
@@ -349,17 +349,17 @@ void QAbstractEventDispatcher::closingDown()
\table
\header
- \o Platform
- \o type
+ \li Platform
+ \li type
\row
- \o Windows
- \o MSG
+ \li Windows
+ \li MSG
\row
- \o X11
- \o XEvent
+ \li X11
+ \li XEvent
\row
- \o Mac
- \o NSEvent
+ \li Mac
+ \li NSEvent
\endtable
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 78cb0eff3bc..048d7461833 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -57,17 +57,6 @@
# define __IMAGECAPTURE__
#endif
-#undef OLD_DEBUG
-#ifdef DEBUG
-# define OLD_DEBUG DEBUG
-# undef DEBUG
-#endif
-#define DEBUG 0
-#ifdef qDebug
-# define old_qDebug qDebug
-# undef qDebug
-#endif
-
#if defined(QT_BUILD_QMAKE) || defined(QT_BOOTSTRAPPED)
#include
#else
@@ -82,18 +71,6 @@
#include
#endif
-#undef DEBUG
-#ifdef OLD_DEBUG
-# define DEBUG OLD_DEBUG
-# undef OLD_DEBUG
-#endif
-
-#ifdef old_qDebug
-# undef qDebug
-# define qDebug QT_NO_QDEBUG_MACRO
-# undef old_qDebug
-#endif
-
#include "qstring.h"
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 2d49b271ce3..967ed447d53 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -543,10 +543,6 @@ void QCoreApplication::init()
Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = this;
-#ifndef QT_NO_THREAD
- QThread::initialize();
-#endif
-
// use the event dispatcher created by the app programmer (if any)
if (!QCoreApplicationPrivate::eventDispatcher)
QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
@@ -602,7 +598,6 @@ QCoreApplication::~QCoreApplication()
}
if (globalThreadPool)
globalThreadPool->waitForDone();
- QThread::cleanup();
#endif
d_func()->threadData->eventDispatcher = 0;
@@ -715,13 +710,13 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
reimplementing this virtual function is just one of them. All five
approaches are listed below:
\list 1
- \i Reimplementing paintEvent(), mousePressEvent() and so
+ \li Reimplementing paintEvent(), mousePressEvent() and so
on. This is the commonest, easiest and least powerful way.
- \i Reimplementing this function. This is very powerful, providing
+ \li Reimplementing this function. This is very powerful, providing
complete control; but only one subclass can be active at a time.
- \i Installing an event filter on QCoreApplication::instance(). Such
+ \li Installing an event filter on QCoreApplication::instance(). Such
an event filter is able to process all events for all widgets, so
it's just as powerful as reimplementing notify(); furthermore, it's
possible to have more than one application-global event filter.
@@ -730,11 +725,11 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
event filters are only called for objects that live in the main
thread.
- \i Reimplementing QObject::event() (as QWidget does). If you do
+ \li Reimplementing QObject::event() (as QWidget does). If you do
this you get Tab key presses, and you get to see the events before
any widget-specific event filters.
- \i Installing an event filter on the object. Such an event filter gets all
+ \li Installing an event filter on the object. Such an event filter gets all
the events, including Tab and Shift+Tab key press events, as long as they
do not change the focus widget.
\endlist
@@ -1438,11 +1433,9 @@ bool QCoreApplication::event(QEvent *e)
This enum type defines the 8-bit encoding of character string
arguments to translate():
- \value CodecForTr The encoding specified by
- QTextCodec::codecForTr() (Latin-1 if none has
- been set).
- \value UnicodeUTF8 UTF-8.
- \value DefaultCodec (Obsolete) Use CodecForTr instead.
+ \value UnicodeUTF8 UTF-8.
+ \value Latin1 Latin-1.
+ \value DefaultCodec Latin-1.
\sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
*/
@@ -1617,7 +1610,7 @@ static void replacePercentN(QString *result, int n)
If none of the translation files contain a translation for \a
sourceText in \a context, this function returns a QString
equivalent of \a sourceText. The encoding of \a sourceText is
- specified by \e encoding; it defaults to CodecForTr.
+ specified by \e encoding; it defaults to DefaultCodec.
This function is not virtual. You can use alternative translation
techniques by subclassing \l QTranslator.
@@ -1628,7 +1621,7 @@ static void replacePercentN(QString *result, int n)
so will most likely result in crashes or other undesirable
behavior.
- \sa QObject::tr() installTranslator() QTextCodec::codecForTr()
+ \sa QObject::tr() installTranslator()
*/
@@ -1657,8 +1650,6 @@ QString QCoreApplication::translate(const char *context, const char *sourceText,
#else
if (encoding == UnicodeUTF8)
result = QString::fromUtf8(sourceText);
- else if (QTextCodec::codecForTr() != 0)
- result = QTextCodec::codecForTr()->toUnicode(sourceText);
else
#endif
result = QString::fromLatin1(sourceText);
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 18266a9a2c8..0a5181a508f 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -137,11 +137,11 @@ public:
static void installTranslator(QTranslator * messageFile);
static void removeTranslator(QTranslator * messageFile);
#endif
- enum Encoding { CodecForTr, UnicodeUTF8, DefaultCodec = CodecForTr };
+ enum Encoding { UnicodeUTF8, Latin1, DefaultCodec = Latin1 };
static QString translate(const char * context,
const char * key,
const char * disambiguation = 0,
- Encoding encoding = CodecForTr,
+ Encoding encoding = DefaultCodec,
int n = -1);
static void flush();
@@ -240,7 +240,7 @@ inline QString QCoreApplication::translate(const char *, const char *sourceText,
public: \
static inline QString tr(const char *sourceText, const char *disambiguation = 0, int n = -1) \
{ return QCoreApplication::translate(#context, sourceText, disambiguation, \
- QCoreApplication::CodecForTr, n); } \
+ QCoreApplication::DefaultCodec, n); } \
static inline QString trUtf8(const char *sourceText, const char *disambiguation = 0, int n = -1) \
{ return QCoreApplication::translate(#context, sourceText, disambiguation, \
QCoreApplication::UnicodeUTF8, n); } \
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 1f36f9c9c8c..1d54b32dfa6 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -127,7 +127,6 @@ public:
DeactivateControl = 81, // ActiveX deactivation
ContextMenu = 82, // context popup menu
InputMethod = 83, // input method
- AccessibilityPrepare = 86, // accessibility information is requested
TabletMove = 87, // Wacom tablet event
LocaleChange = 88, // the system locale changed
LanguageChange = 89, // the application language changed
@@ -288,7 +287,7 @@ public:
MaxUser = 65535 // last user event id
};
- QEvent(Type type);
+ explicit QEvent(Type type);
virtual ~QEvent();
inline Type type() const { return static_cast(t); }
inline bool spontaneous() const { return spont; }
@@ -330,7 +329,7 @@ private:
class Q_CORE_EXPORT QTimerEvent : public QEvent
{
public:
- QTimerEvent( int timerId );
+ explicit QTimerEvent( int timerId );
~QTimerEvent();
int timerId() const { return id; }
protected:
@@ -355,7 +354,7 @@ protected:
class Q_CORE_EXPORT QDynamicPropertyChangeEvent : public QEvent
{
public:
- QDynamicPropertyChangeEvent(const QByteArray &name);
+ explicit QDynamicPropertyChangeEvent(const QByteArray &name);
~QDynamicPropertyChangeEvent();
inline QByteArray propertyName() const { return n; }
diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp
index 4adcb7678c9..3f272a25126 100644
--- a/src/corelib/kernel/qeventdispatcher_glib.cpp
+++ b/src/corelib/kernel/qeventdispatcher_glib.cpp
@@ -42,7 +42,6 @@
#include "qeventdispatcher_glib_p.h"
#include "qeventdispatcher_unix_p.h"
-#include
#include
#include "qcoreapplication.h"
@@ -295,8 +294,8 @@ QEventDispatcherGlibPrivate::QEventDispatcherGlibPrivate(GMainContext *context)
: mainContext(context)
{
if (qgetenv("QT_NO_THREADED_GLIB").isEmpty()) {
- static int dummyValue = 0; // only used for its address
- QMutexLocker locker(QMutexPool::instance()->get(&dummyValue));
+ static QBasicMutex mutex;
+ QMutexLocker locker(&mutex);
if (!g_thread_supported())
g_thread_init(NULL);
}
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index c404967e6ad..565f1ef4b39 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -55,6 +55,7 @@
#include "QtCore/qabstracteventdispatcher.h"
#include "QtCore/qt_windows.h"
+#include "QtCore/qhash.h"
#include "qabstracteventdispatcher_p.h"
@@ -130,7 +131,7 @@ struct WinTimerInfo { // internal timer info
class QZeroTimerEvent : public QTimerEvent
{
public:
- inline QZeroTimerEvent(int timerId)
+ explicit inline QZeroTimerEvent(int timerId)
: QTimerEvent(timerId)
{ t = QEvent::ZeroTimerEvent; }
};
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index dfdd178c35a..58e2c5cd2f4 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -222,11 +222,11 @@ int QEventLoop::exec(ProcessEventsFlags flags)
operation and want to show its progress without allowing user
input, i.e. by using the \l ExcludeUserInputEvents flag.
- \bold{Notes:}
+ \b{Notes:}
\list
- \o This function does not process events continuously; it
+ \li This function does not process events continuously; it
returns after all available events are processed.
- \o Specifying the \l WaitForMoreEvents flag makes no sense
+ \li Specifying the \l WaitForMoreEvents flag makes no sense
and will be ignored.
\endlist
*/
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index e446d8b6bae..a8c21657cb2 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -86,16 +86,16 @@ QT_BEGIN_NAMESPACE
The functions you are most likely to find useful are these:
\list
- \o className() returns the name of a class.
- \o superClass() returns the superclass's meta-object.
- \o method() and methodCount() provide information
+ \li className() returns the name of a class.
+ \li superClass() returns the superclass's meta-object.
+ \li method() and methodCount() provide information
about a class's meta-methods (signals, slots and other
\l{Q_INVOKABLE}{invokable} member functions).
- \o enumerator() and enumeratorCount() and provide information about
+ \li enumerator() and enumeratorCount() and provide information about
a class's enumerators.
- \o propertyCount() and property() provide information about a
+ \li propertyCount() and property() provide information about a
class's properties.
- \o constructor() and constructorCount() provide information
+ \li constructor() and constructorCount() provide information
about a class's meta-constructors.
\endlist
@@ -393,7 +393,7 @@ const QObject *QMetaObject::cast(const QObject *obj) const
*/
QString QMetaObject::tr(const char *s, const char *c, int n) const
{
- return QCoreApplication::translate(rawStringData(this, 0), s, c, QCoreApplication::CodecForTr, n);
+ return QCoreApplication::translate(rawStringData(this, 0), s, c, QCoreApplication::DefaultCodec, n);
}
/*!
@@ -1414,18 +1414,18 @@ enum { MaximumParamCount = 11 }; // up to 10 arguments + 1 return value
depending on \a type:
\list
- \o If \a type is Qt::DirectConnection, the member will be invoked immediately.
+ \li If \a type is Qt::DirectConnection, the member will be invoked immediately.
- \o If \a type is Qt::QueuedConnection,
+ \li If \a type is Qt::QueuedConnection,
a QEvent will be sent and the member is invoked as soon as the application
enters the main event loop.
- \o If \a type is Qt::BlockingQueuedConnection, the method will be invoked in
+ \li If \a type is Qt::BlockingQueuedConnection, the method will be invoked in
the same way as for Qt::QueuedConnection, except that the current thread
will block until the event is delivered. Using this connection type to
communicate between objects in the same thread will lead to deadlocks.
- \o If \a type is Qt::AutoConnection, the member is invoked
+ \li If \a type is Qt::AutoConnection, the member is invoked
synchronously if \a obj lives in the same thread as the
caller; otherwise it will invoke the member asynchronously.
\endlist
@@ -2034,13 +2034,13 @@ QMetaMethod::MethodType QMetaMethod::methodType() const
\a connectionType:
\list
- \o If \a connectionType is Qt::DirectConnection, the member will be invoked immediately.
+ \li If \a connectionType is Qt::DirectConnection, the member will be invoked immediately.
- \o If \a connectionType is Qt::QueuedConnection,
+ \li If \a connectionType is Qt::QueuedConnection,
a QEvent will be posted and the member is invoked as soon as the application
enters the main event loop.
- \o If \a connectionType is Qt::AutoConnection, the member is invoked
+ \li If \a connectionType is Qt::AutoConnection, the member is invoked
synchronously if \a object lives in the same thread as the
caller; otherwise it will invoke the member asynchronously.
\endlist
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 6d5973a7d0d..a5dc179113a 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -454,7 +454,7 @@ static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
int QMetaType::registerType(const char *typeName, Deleter deleter,
Creator creator)
{
- return registerType(typeName, deleter, creator, 0, 0, 0, TypeFlags());
+ return registerType(typeName, deleter, creator, qMetaTypeDestructHelper, qMetaTypeConstructHelper, 0, TypeFlags());
}
/*! \internal
@@ -472,7 +472,7 @@ int QMetaType::registerType(const char *typeName, Deleter deleter,
int size, TypeFlags flags)
{
QVector *ct = customTypes();
- if (!ct || !typeName || !deleter || !creator)
+ if (!ct || !typeName || !deleter || !creator || !destructor || !constructor)
return -1;
#ifdef QT_NO_QOBJECT
@@ -1337,6 +1337,7 @@ private:
return;
deleter = ct->at(type - QMetaType::User).deleter;
}
+ Q_ASSERT_X(deleter, "void QMetaType::destroy(int type, void *data)", "The type was not properly registered");
deleter(where);
}
@@ -1400,6 +1401,7 @@ private:
return 0;
ctor = ct->at(type - QMetaType::User).constructor;
}
+ Q_ASSERT_X(ctor, "void *QMetaType::construct(int type, void *where, const void *copy)", "The type was not properly registered");
return ctor(where, copy);
}
@@ -1489,6 +1491,7 @@ private:
return;
dtor = ct->at(type - QMetaType::User).destructor;
}
+ Q_ASSERT_X(dtor, "void QMetaType::destruct(int type, void *where)", "The type was not properly registered");
dtor(where);
}
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 0f069dc45c8..fb2bce7d7b6 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -256,7 +256,7 @@ public:
static bool load(QDataStream &stream, int type, void *data);
#endif
- QMetaType(const int type);
+ explicit QMetaType(const int type);
inline ~QMetaType();
inline bool isValid() const;
@@ -365,33 +365,11 @@ void qMetaTypeLoadHelper(QDataStream &stream, void *t)
template <> inline void qMetaTypeLoadHelper(QDataStream &, void *) {}
#endif // QT_NO_DATASTREAM
-template
-struct QMetaTypeId
-{
- enum { Defined = 0 };
-};
-
-template
-struct QMetaTypeId2
-{
- enum { Defined = QMetaTypeId::Defined };
- static inline int qt_metatype_id() { return QMetaTypeId::qt_metatype_id(); }
-};
-
class QObject;
class QWidget;
-namespace QtPrivate {
- template ::Defined>
- struct QMetaTypeIdHelper {
- static inline int qt_metatype_id()
- { return QMetaTypeId2::qt_metatype_id(); }
- };
- template struct QMetaTypeIdHelper {
- static inline int qt_metatype_id()
- { return -1; }
- };
-
+namespace QtPrivate
+{
template
struct IsPointerToTypeDerivedFromQObject
{
@@ -428,6 +406,38 @@ namespace QtPrivate {
Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined");
enum { Value = sizeof(checkType(static_cast(0))) == sizeof(yes_type) };
};
+}
+
+template ::Value>
+struct QMetaTypeIdQObject
+{
+ enum {
+ Defined = 0
+ };
+};
+
+template
+struct QMetaTypeId : public QMetaTypeIdQObject
+{
+};
+
+template
+struct QMetaTypeId2
+{
+ enum { Defined = QMetaTypeId::Defined };
+ static inline int qt_metatype_id() { return QMetaTypeId::qt_metatype_id(); }
+};
+
+namespace QtPrivate {
+ template ::Defined>
+ struct QMetaTypeIdHelper {
+ static inline int qt_metatype_id()
+ { return QMetaTypeId2::qt_metatype_id(); }
+ };
+ template struct QMetaTypeIdHelper {
+ static inline int qt_metatype_id()
+ { return -1; }
+ };
// Function pointers don't derive from QObject
template struct IsPointerToTypeDerivedFromQObject { enum { Value = false }; };
@@ -485,6 +495,7 @@ inline int qMetaTypeId(
#endif
)
{
+ Q_STATIC_ASSERT_X(QMetaTypeId2::Defined, "Type is not registered, please use Q_DECLARE_METATYPE macro to make it know to Qt's meta-object system");
return QMetaTypeId2::qt_metatype_id();
}
@@ -502,6 +513,23 @@ inline int qRegisterMetaType(
#endif
}
+template
+struct QMetaTypeIdQObject
+{
+ enum {
+ Defined = 1
+ };
+
+ static int qt_metatype_id()
+ {
+ static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
+ if (!metatype_id.load())
+ metatype_id.storeRelease(qRegisterMetaType(QByteArray(T::staticMetaObject.className() + QByteArrayLiteral("*")).constData(),
+ reinterpret_cast(quintptr(-1))));
+ return metatype_id.loadAcquire();
+ }
+};
+
#ifndef QT_NO_DATASTREAM
template
inline int qRegisterMetaTypeStreamOperators()
@@ -566,6 +594,7 @@ template class QSet;
template class QSharedPointer;
template class QMap;
template class QHash;
+template struct QPair;
typedef QList QVariantList;
typedef QMap QVariantMap;
typedef QHash QVariantHash;
@@ -587,6 +616,23 @@ struct QMetaTypeId< SINGLE_ARG_TEMPLATE > \
} \
};
+#define Q_DECLARE_METATYPE_TEMPLATE_2ARG(DOUBLE_ARG_TEMPLATE) \
+template \
+struct QMetaTypeId< DOUBLE_ARG_TEMPLATE > \
+{ \
+ enum { \
+ Defined = QMetaTypeId2::Defined && QMetaTypeId2::Defined \
+ }; \
+ static int qt_metatype_id() \
+ { \
+ static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
+ if (!metatype_id.load()) \
+ metatype_id.storeRelease(qRegisterMetaType< DOUBLE_ARG_TEMPLATE >( QByteArray(QByteArray(#DOUBLE_ARG_TEMPLATE "<") + QMetaType::typeName(qMetaTypeId()) + ", " + QMetaType::typeName(qMetaTypeId()) + ">").constData(), \
+ reinterpret_cast< DOUBLE_ARG_TEMPLATE *>(quintptr(-1)))); \
+ return metatype_id.loadAcquire(); \
+ } \
+};
+
Q_DECLARE_METATYPE_TEMPLATE_1ARG(QList)
Q_DECLARE_METATYPE_TEMPLATE_1ARG(QVector)
Q_DECLARE_METATYPE_TEMPLATE_1ARG(QQueue)
@@ -595,6 +641,10 @@ Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSet)
Q_DECLARE_METATYPE_TEMPLATE_1ARG(QSharedPointer)
Q_DECLARE_METATYPE_TEMPLATE_1ARG(QLinkedList)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(QHash)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(QMap)
+Q_DECLARE_METATYPE_TEMPLATE_2ARG(QPair)
+
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
Creator creator,
Deleter deleter,
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index cfe985da26e..3a3464e43ed 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -246,12 +246,12 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
functions to access the data:
\table
- \header \o Tester \o Getter \o Setter \o MIME Types
- \row \o hasText() \o text() \o setText() \o \c text/plain
- \row \o hasHtml() \o html() \o setHtml() \o \c text/html
- \row \o hasUrls() \o urls() \o setUrls() \o \c text/uri-list
- \row \o hasImage() \o imageData() \o setImageData() \o \c image/ *
- \row \o hasColor() \o colorData() \o setColorData() \o \c application/x-color
+ \header \li Tester \li Getter \li Setter \li MIME Types
+ \row \li hasText() \li text() \li setText() \li \c text/plain
+ \row \li hasHtml() \li html() \li setHtml() \li \c text/html
+ \row \li hasUrls() \li urls() \li setUrls() \li \c text/uri-list
+ \row \li hasImage() \li imageData() \li setImageData() \li \c image/ *
+ \row \li hasColor() \li colorData() \li setColorData() \li \c application/x-color
\endtable
For example, if your write a widget that accepts URL drags, you
@@ -263,15 +263,15 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
object:
\list 1
- \o Custom data can be stored directly in a QMimeData object as a
+ \li Custom data can be stored directly in a QMimeData object as a
QByteArray using setData(). For example:
\snippet doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp 1
- \o We can subclass QMimeData and reimplement hasFormat(),
+ \li We can subclass QMimeData and reimplement hasFormat(),
formats(), and retrieveData().
- \o If the drag and drop operation occurs within a single
+ \li If the drag and drop operation occurs within a single
application, we can subclass QMimeData and add extra data in
it, and use a qobject_cast() in the receiver's drop event
handler. For example:
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 9977f96f99f..edbb84a6575 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -69,6 +69,16 @@
QT_BEGIN_NAMESPACE
+struct QObjectPrivate::ExtraData
+{
+ ExtraData() {}
+#ifndef QT_NO_USERDATA
+ QVector userData;
+#endif
+ QList propertyNames;
+ QList propertyValues;
+};
+
static int DIRECT_CONNECTION_ONLY = 0;
static int *queuedConnectionTypes(const QList &typeNames)
@@ -1829,7 +1839,7 @@ void QObject::removeEventFilter(QObject *obj)
deleted, the control must return to the event loop from which
deleteLater() was called.
- \bold{Note:} It is safe to call this function more than once; when the
+ \b{Note:} It is safe to call this function more than once; when the
first deferred deletion event is delivered, any pending events for the
object are removed from the event queue.
@@ -1873,7 +1883,7 @@ void QObject::deleteLater()
translators while performing translations is not supported. Doing
so will probably result in crashes or other undesirable behavior.
- \sa trUtf8(), QApplication::translate(), QTextCodec::setCodecForTr(), {Internationalization with Qt}
+ \sa trUtf8(), QApplication::translate(), {Internationalization with Qt}
*/
/*!
@@ -1885,11 +1895,6 @@ void QObject::deleteLater()
version. It is otherwise identical to tr(\a sourceText, \a
disambiguation, \a n).
- Note that using the Utf8 variants of the translation functions
- is not required if \c CODECFORTR is already set to UTF-8 in the
- qmake project file and QTextCodec::setCodecForTr("UTF-8") is
- used.
-
\warning This method is reentrant only if all translators are
installed \e before calling this method. Installing or removing
translators while performing translations is not supported. Doing
@@ -2147,9 +2152,9 @@ int QObject::receivers(const char *signal) const
member in the specified class.
\list
- \o If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
+ \li If member.mobj is 0 then both signalIndex and methodIndex are set to -1.
- \o If specified member is not a member of obj instance class (or one of
+ \li If specified member is not a member of obj instance class (or one of
its parent classes) then both signalIndex and methodIndex are set to -1.
\endlist
@@ -2598,7 +2603,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
disconnect() is typically used in three ways, as the following
examples demonstrate.
\list 1
- \i Disconnect everything connected to an object's signals:
+ \li Disconnect everything connected to an object's signals:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
@@ -2606,7 +2611,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 27
- \i Disconnect everything connected to a specific signal:
+ \li Disconnect everything connected to a specific signal:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 28
@@ -2614,7 +2619,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMetho
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 29
- \i Disconnect a specific receiver:
+ \li Disconnect a specific receiver:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
@@ -2775,11 +2780,11 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
if:
\list 1
- \i \a signal is not a member of sender class or one of its parent classes.
+ \li \a signal is not a member of sender class or one of its parent classes.
- \i \a method is not a member of receiver class or one of its parent classes.
+ \li \a method is not a member of receiver class or one of its parent classes.
- \i \a signal instance represents not a signal.
+ \li \a signal instance represents not a signal.
\endlist
@@ -3460,7 +3465,7 @@ int QObjectPrivate::signalIndex(const char *signalName) const
Changing the value of a dynamic property causes a QDynamicPropertyChangeEvent
to be sent to the object.
- \bold{Note:} Dynamic properties starting with "_q_" are reserved for internal
+ \b{Note:} Dynamic properties starting with "_q_" are reserved for internal
purposes.
\sa property(), metaObject(), dynamicPropertyNames()
@@ -4219,19 +4224,19 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
disconnect() is typically used in three ways, as the following
examples demonstrate.
\list 1
- \i Disconnect everything connected to an object's signals:
+ \li Disconnect everything connected to an object's signals:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 26
- \i Disconnect everything connected to a specific signal:
+ \li Disconnect everything connected to a specific signal:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 47
- \i Disconnect a specific receiver:
+ \li Disconnect a specific receiver:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 30
- \i Disconnect a connection from one specific signal to a specific slot:
+ \li Disconnect a connection from one specific signal to a specific slot:
\snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 48
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 5f43b52939b..9f096170716 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -198,6 +198,10 @@ public:
inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;
+#ifdef Q_QDOC
+ QMetaObject::Connection QObject::connect(const QObject *sender, (T::*signal)(...), const QObject *receiver, (T::*method)(...), Qt::ConnectionType type)
+ QMetaObject::Connection QObject::connect(const QObject *sender, (T::*signal)(...), Functor functor)
+#else
//Connect a signal to a pointer to qobject member function
template
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer::Object *sender, Func1 signal,
@@ -261,6 +265,7 @@ public:
new QFunctorSlotObject(slot),
Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
}
+#endif //Q_QDOC
static bool disconnect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member);
@@ -273,6 +278,9 @@ public:
{ return disconnect(this, 0, receiver, member); }
static bool disconnect(const QMetaObject::Connection &);
+#ifdef Q_QDOC
+ bool QObject::disconnect(const QObject *sender, (T::*signal)(...), const Qbject *receiver, (T::*method)(...))
+#else
template
static inline bool disconnect(const typename QtPrivate::FunctionPointer::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer::Object *receiver, Func2 slot)
@@ -300,6 +308,7 @@ public:
return disconnectImpl(sender, reinterpret_cast(&signal), receiver, zero,
&SignalType::Object::staticMetaObject);
}
+#endif //Q_QDOC
void dumpObjectTree();
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index fa1aee81730..c8edadce9db 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -60,7 +60,6 @@
#include "QtCore/qlist.h"
#include "QtCore/qvector.h"
#include "QtCore/qreadwritelock.h"
-#include "QtCore/qvariant.h"
QT_BEGIN_NAMESPACE
@@ -98,16 +97,8 @@ class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
+ struct ExtraData;
public:
- struct ExtraData
- {
- ExtraData() {}
-#ifndef QT_NO_USERDATA
- QVector userData;
-#endif
- QList propertyNames;
- QList propertyValues;
- };
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
struct Connection
@@ -284,8 +275,9 @@ private:
class QBoolBlocker
{
+ Q_DISABLE_COPY(QBoolBlocker)
public:
- inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
+ explicit inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;}
inline ~QBoolBlocker(){block = reset; }
private:
bool █
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 8751d0f5a19..4c98bad0f9c 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -66,8 +66,10 @@ class QString;
# if defined(QT_NO_KEYWORDS)
# define QT_NO_EMIT
# else
-# define slots
-# define signals public
+# ifndef QT_NO_SIGNALS_SLOTS_KEYWORDS
+# define slots
+# define signals public
+# endif
# endif
# define Q_SLOTS
# define Q_SIGNALS public
@@ -209,16 +211,16 @@ Q_CORE_EXPORT const char *qFlagLocation(const char *method);
#ifndef QT_NO_DEBUG
# define QLOCATION "\0" __FILE__ ":" QTOSTRING(__LINE__)
# ifndef QT_NO_KEYWORDS
-# define METHOD(a) qFlagLocation("0"#a QLOCATION)
+# define METHOD(a) qFlagLocation("0" QTOSTRING(a) QLOCATION)
# endif
-# define SLOT(a) qFlagLocation("1"#a QLOCATION)
-# define SIGNAL(a) qFlagLocation("2"#a QLOCATION)
+# define SLOT(a) qFlagLocation("1" QTOSTRING(a) QLOCATION)
+# define SIGNAL(a) qFlagLocation("2" QTOSTRING(a) QLOCATION)
#else
# ifndef QT_NO_KEYWORDS
-# define METHOD(a) "0"#a
+# define METHOD(a) "0" QTOSTRING(a)
# endif
-# define SLOT(a) "1"#a
-# define SIGNAL(a) "2"#a
+# define SLOT(a) "1" QTOSTRING(a)
+# define SIGNAL(a) "2" QTOSTRING(a)
#endif
#define QMETHOD_CODE 0 // member type codes
diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp
index 936a933d2d2..b983bef5fe5 100644
--- a/src/corelib/kernel/qpointer.cpp
+++ b/src/corelib/kernel/qpointer.cpp
@@ -61,13 +61,13 @@
\list
- \i When using QPointer on a QWidget (or a subclass of QWidget), previously
+ \li When using QPointer on a QWidget (or a subclass of QWidget), previously
the QPointer would be cleared by the QWidget destructor. Now, the QPointer
is cleared by the QObject destructor (since this is when QWeakPointers are
cleared). Any QPointers tracking a widget will \b NOT be cleared before the
QWidget destructor destroys the children for the widget being tracked.
- \i When constructing a QSharedPointer to take ownership of an object after a
+ \li When constructing a QSharedPointer to take ownership of an object after a
QPointer is already tracking the object. Previously, the shared pointer
construction would not be affected by the QPointer, but now that QPointer
is implemented using QWeakPoiner, constructing the QSharedPointer will
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 640dfc0f945..d8578a8059a 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -100,13 +100,13 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
\list
- \o Windows: QSharedMemory does not "own" the shared memory segment.
+ \li Windows: QSharedMemory does not "own" the shared memory segment.
When all threads or processes that have an instance of QSharedMemory
attached to a particular shared memory segment have either destroyed
their instance of QSharedMemory or exited, the Windows kernel
releases the shared memory segment automatically.
- \o Unix: QSharedMemory "owns" the shared memory segment. When the
+ \li Unix: QSharedMemory "owns" the shared memory segment. When the
last thread or process that has an instance of QSharedMemory
attached to a particular shared memory segment detaches from the
segment by destroying its instance of QSharedMemory, the Unix kernel
@@ -114,7 +114,7 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
process crashes without running the QSharedMemory destructor, the
shared memory segment survives the crash.
- \o HP-UX: Only one attach to a shared memory segment is allowed per
+ \li HP-UX: Only one attach to a shared memory segment is allowed per
process. This means that QSharedMemory should not be used across
multiple threads in the same process in HP-UX.
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index d7689bb7b1c..0a2a66b6b2a 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -111,9 +111,9 @@ QT_BEGIN_NAMESPACE
follow these steps when you receive a notification:
\list 1
- \o Disable the notifier.
- \o Read data from the socket.
- \o Re-enable the notifier if you are interested in more data (such as after
+ \li Disable the notifier.
+ \li Read data from the socket.
+ \li Re-enable the notifier if you are interested in more data (such as after
having written a new command to a remote server).
\endlist
@@ -121,12 +121,12 @@ QT_BEGIN_NAMESPACE
follow these steps when you receive a notification:
\list 1
- \o Disable the notifier.
- \o Write as much data as you can (before \c EWOULDBLOCK is returned).
- \o Re-enable notifier if you have more data to write.
+ \li Disable the notifier.
+ \li Write as much data as you can (before \c EWOULDBLOCK is returned).
+ \li Re-enable notifier if you have more data to write.
\endlist
- \bold{Further information:}
+ \b{Further information:}
On Windows, Qt always disables the notifier after getting a notification,
and only re-enables it if more data is expected. For example, if data is
read from the socket and it can be used to read more, or if reading or
@@ -162,7 +162,7 @@ QT_BEGIN_NAMESPACE
It is generally advisable to explicitly enable or disable the
socket notifier, especially for write notifiers.
- \bold{Note for Windows users:} The socket passed to QSocketNotifier
+ \b{Note for Windows users:} The socket passed to QSocketNotifier
will become non-blocking, even if it was created as a blocking socket.
\sa setEnabled(), isEnabled()
diff --git a/src/corelib/kernel/qsystemsemaphore.cpp b/src/corelib/kernel/qsystemsemaphore.cpp
index d0a67834dd9..0558f3cb59b 100644
--- a/src/corelib/kernel/qsystemsemaphore.cpp
+++ b/src/corelib/kernel/qsystemsemaphore.cpp
@@ -90,16 +90,16 @@ QT_BEGIN_NAMESPACE
When using this class, be aware of the following platform
differences:
- \bold{Windows:} QSystemSemaphore does not own its underlying system
+ \b{Windows:} QSystemSemaphore does not own its underlying system
semaphore. Windows owns it. This means that when all instances of
QSystemSemaphore for a particular key have been destroyed, either by
having their destructors called, or because one or more processes
crash, Windows removes the underlying system semaphore.
- \bold{Unix:}
+ \b{Unix:}
\list
- \o QSystemSemaphore owns the underlying system semaphore
+ \li QSystemSemaphore owns the underlying system semaphore
in Unix systems. This means that the last process having an instance of
QSystemSemaphore for a particular key must remove the underlying
system semaphore in its destructor. If the last process crashes
@@ -117,7 +117,7 @@ QT_BEGIN_NAMESPACE
{QSystemSemaphore::} {Create}, which will force Unix to reset the
resource count in the underlying system semaphore.
- \o When a process using QSystemSemaphore terminates for
+ \li When a process using QSystemSemaphore terminates for
any reason, Unix automatically reverses the effect of all acquire
operations that were not released. Thus if the process acquires a
resource and then exits without releasing it, Unix will release that
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index a11bcb26c99..dad33188709 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -279,9 +279,9 @@ public:
up to three parameters:
\list
- \o The \e context - usually the class name for the tr() caller.
- \o The \e {source text} - usually the argument to tr().
- \o The \e disambiguation - an optional string that helps disambiguate
+ \li The \e context - usually the class name for the tr() caller.
+ \li The \e {source text} - usually the argument to tr().
+ \li The \e disambiguation - an optional string that helps disambiguate
different uses of the same text in the same context.
\endlist
@@ -361,12 +361,12 @@ QTranslator::~QTranslator()
in the following order:
\list 1
- \o File name without \a suffix appended.
- \o File name with text after a character in \a search_delimiters
+ \li File name without \a suffix appended.
+ \li File name with text after a character in \a search_delimiters
stripped ("_." is the default for \a search_delimiters if it is
an empty string) and \a suffix.
- \o File name stripped without \a suffix appended.
- \o File name stripped further, etc.
+ \li File name stripped without \a suffix appended.
+ \li File name stripped further, etc.
\endlist
For example, an application running in the fr_CA locale
@@ -375,12 +375,12 @@ QTranslator::~QTranslator()
readable file from this list:
\list 1
- \o \c /opt/foolib/foo.fr_ca.qm
- \o \c /opt/foolib/foo.fr_ca
- \o \c /opt/foolib/foo.fr.qm
- \o \c /opt/foolib/foo.fr
- \o \c /opt/foolib/foo.qm
- \o \c /opt/foolib/foo
+ \li \c /opt/foolib/foo.fr_ca.qm
+ \li \c /opt/foolib/foo.fr_ca
+ \li \c /opt/foolib/foo.fr.qm
+ \li \c /opt/foolib/foo.fr
+ \li \c /opt/foolib/foo.qm
+ \li \c /opt/foolib/foo
\endlist
*/
@@ -599,10 +599,10 @@ static QString find_translation(const QLocale & locale,
in the following order:
\list 1
- \o File name without \a suffix appended.
- \o File name with ui language part after a "_" character stripped and \a suffix.
- \o File name with ui language part stripped without \a suffix appended.
- \o File name with ui language part stripped further, etc.
+ \li File name without \a suffix appended.
+ \li File name with ui language part after a "_" character stripped and \a suffix.
+ \li File name with ui language part stripped without \a suffix appended.
+ \li File name with ui language part stripped further, etc.
\endlist
For example, an application running in the locale with the following
@@ -612,17 +612,17 @@ static QString find_translation(const QLocale & locale,
open the first existing readable file from this list:
\list 1
- \o \c /opt/foolib/foo.es.qm
- \o \c /opt/foolib/foo.es
- \o \c /opt/foolib/foo.fr_CA.qm
- \o \c /opt/foolib/foo.fr_CA
- \o \c /opt/foolib/foo.de.qm
- \o \c /opt/foolib/foo.de
- \o \c /opt/foolib/foo.fr.qm
- \o \c /opt/foolib/foo.fr
- \o \c /opt/foolib/foo.qm
- \o \c /opt/foolib/foo.
- \o \c /opt/foolib/foo
+ \li \c /opt/foolib/foo.es.qm
+ \li \c /opt/foolib/foo.es
+ \li \c /opt/foolib/foo.fr_CA.qm
+ \li \c /opt/foolib/foo.fr_CA
+ \li \c /opt/foolib/foo.de.qm
+ \li \c /opt/foolib/foo.de
+ \li \c /opt/foolib/foo.fr.qm
+ \li \c /opt/foolib/foo.fr
+ \li \c /opt/foolib/foo.qm
+ \li \c /opt/foolib/foo.
+ \li \c /opt/foolib/foo
\endlist
On operating systems where file system is case sensitive, QTranslator also
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index ae51764c0ac..39e8b4360f4 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -1696,7 +1696,7 @@ void QVariant::load(QDataStream &s)
if (typeId == QVariant::UserType) {
QByteArray name;
s >> name;
- typeId = QMetaType::type(name);
+ typeId = QMetaType::type(name.constData());
if (typeId == QMetaType::UnknownType) {
s.setStatus(QDataStream::ReadCorruptData);
return;
@@ -2174,7 +2174,7 @@ inline T qNumVariantToHelper(const QVariant::Private &d,
If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
converted to an int; otherwise \c{*}\a{ok} is set to false.
- \bold{Warning:} If the value is convertible to a \l LongLong but is too
+ \b{Warning:} If the value is convertible to a \l LongLong but is too
large to be represented in an int, the resulting arithmetic overflow will
not be reflected in \a ok. A simple workaround is to use QString::toInt().
Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
@@ -2194,7 +2194,7 @@ int QVariant::toInt(bool *ok) const
If \a ok is non-null: \c{*}\a{ok} is set to true if the value could be
converted to an unsigned int; otherwise \c{*}\a{ok} is set to false.
- \bold{Warning:} If the value is convertible to a \l ULongLong but is too
+ \b{Warning:} If the value is convertible to a \l ULongLong but is too
large to be represented in an unsigned int, the resulting arithmetic overflow will
not be reflected in \a ok. A simple workaround is to use QString::toUInt().
Fixing this bug has been postponed to Qt 5 in order to avoid breaking existing code.
@@ -2411,28 +2411,28 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
The following casts are done automatically:
\table
- \header \o Type \o Automatically Cast To
- \row \o \l Bool \o \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l ByteArray \o \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l Char \o \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
- \row \o \l Color \o \l String
- \row \o \l Date \o \l DateTime, \l String
- \row \o \l DateTime \o \l Date, \l String, \l Time
- \row \o \l Double \o \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l Font \o \l String
- \row \o \l Int \o \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
- \row \o \l KeySequence \o \l Int, \l String
- \row \o \l List \o \l StringList (if the list's items can be converted to strings)
- \row \o \l LongLong \o \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
- \row \o \l Point \o PointF
- \row \o \l Rect \o RectF
- \row \o \l String \o \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
+ \header \li Type \li Automatically Cast To
+ \row \li \l Bool \li \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l ByteArray \li \l Double, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l Char \li \l Bool, \l Int, \l UInt, \l LongLong, \l ULongLong
+ \row \li \l Color \li \l String
+ \row \li \l Date \li \l DateTime, \l String
+ \row \li \l DateTime \li \l Date, \l String, \l Time
+ \row \li \l Double \li \l Bool, \l Int, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l Font \li \l String
+ \row \li \l Int \li \l Bool, \l Char, \l Double, \l LongLong, \l String, \l UInt, \l ULongLong
+ \row \li \l KeySequence \li \l Int, \l String
+ \row \li \l List \li \l StringList (if the list's items can be converted to strings)
+ \row \li \l LongLong \li \l Bool, \l ByteArray, \l Char, \l Double, \l Int, \l String, \l UInt, \l ULongLong
+ \row \li \l Point \li PointF
+ \row \li \l Rect \li RectF
+ \row \li \l String \li \l Bool, \l ByteArray, \l Char, \l Color, \l Date, \l DateTime, \l Double,
\l Font, \l Int, \l KeySequence, \l LongLong, \l StringList, \l Time, \l UInt,
\l ULongLong
- \row \o \l StringList \o \l List, \l String (if the list contains exactly one item)
- \row \o \l Time \o \l String
- \row \o \l UInt \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
- \row \o \l ULongLong \o \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
+ \row \li \l StringList \li \l List, \l String (if the list contains exactly one item)
+ \row \li \l Time \li \l String
+ \row \li \l UInt \li \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l ULongLong
+ \row \li \l ULongLong \li \l Bool, \l Char, \l Double, \l Int, \l LongLong, \l String, \l UInt
\endtable
\sa convert()
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index 11a2dc83f5a..58ca046d9d4 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -75,7 +75,7 @@ QT_BEGIN_NAMESPACE
Finally, you can use the setHandle() function to register a new event
object, and the handle() function to retrieve the event handle.
- \bold{Further information:}
+ \b{Further information:}
Although the class is called QWinEventNotifier, it can be used for
certain other objects which are so-called synchronization
objects, such as Processes, Threads, Waitable timers.
@@ -140,7 +140,7 @@ QWinEventNotifier::~QWinEventNotifier()
Register the HANDLE \a hEvent. The old HANDLE will be automatically
unregistered.
- \bold Note: The notifier will be disabled as a side effect and needs
+ \b Note: The notifier will be disabled as a side effect and needs
to be re-enabled.
\sa handle(), setEnabled()
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 8ef0ee88814..0c2f25a1f9d 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -283,6 +283,8 @@ QMimeType QMimeBinaryProvider::mimeTypeForName(const QString &name)
QStringList QMimeBinaryProvider::findByFileName(const QString &fileName, QString *foundSuffix)
{
checkCache();
+ if (fileName.isEmpty())
+ return QStringList();
const QString lowerFileName = fileName.toLower();
QMimeGlobMatchResult result;
// TODO this parses in the order (local, global). Check that it handles "NOGLOBS" correctly.
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 566ece77c9a..cdc72cf35d8 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -128,6 +128,7 @@ void QFactoryLoader::update()
QLibraryPrivate *library = 0;
for (int j = 0; j < plugins.count(); ++j) {
QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
+
if (qt_debug_component()) {
qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName;
}
@@ -140,7 +141,9 @@ void QFactoryLoader::update()
library->release();
continue;
}
+
QStringList keys;
+ bool metaDataOk = false;
if (library->compatPlugin) {
qWarning("Qt plugin loader: Compatibility plugin '%s', need to load for accessing meta data.",
qPrintable(QDir::toNativeSeparators(fileName)));
@@ -164,10 +167,17 @@ void QFactoryLoader::update()
QFactoryInterface *factory = qobject_cast(instance);
if (instance && factory && instance->qt_metacast(d->iid))
keys = factory->keys();
+
+ if (!keys.isEmpty())
+ metaDataOk = true;
+
} else {
QString iid = library->metaData.value(QLatin1String("IID")).toString();
if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
+ if (!object.isEmpty())
+ metaDataOk = true;
+
QJsonArray k = object.value(QLatin1String("Keys")).toArray();
for (int i = 0; i < k.size(); ++i) {
QString s = k.at(i).toString();
@@ -178,11 +188,12 @@ void QFactoryLoader::update()
qDebug() << "Got keys from plugin meta data" << keys;
}
- if (keys.isEmpty()) {
+ if (!metaDataOk) {
library->unload();
library->release();
continue;
}
+
d->libraryList += library;
for (int k = 0; k < keys.count(); ++k) {
// first come first serve, unless the first
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index b171577184e..216e6e1e7c9 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -596,12 +596,12 @@ bool QLibraryPrivate::loadPlugin()
library; otherwise returns false.
\table
- \header \i Platform \i Valid suffixes
- \row \i Windows \i \c .dll, \c .DLL
- \row \i Unix/Linux \i \c .so
- \row \i AIX \i \c .a
- \row \i HP-UX \i \c .sl, \c .so (HP-UXi)
- \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so
+ \header \li Platform \li Valid suffixes
+ \row \li Windows \li \c .dll, \c .DLL
+ \row \li Unix/Linux \li \c .so
+ \row \li AIX \li \c .a
+ \row \li HP-UX \li \c .sl, \c .so (HP-UXi)
+ \row \li Mac OS X \li \c .dylib, \c .bundle, \c .so
\endtable
Trailing versioning numbers on Unix are ignored.
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index d652b251f14..f198f108da5 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -66,9 +66,9 @@ QT_BEGIN_NAMESPACE
using QLibrary:
\list
- \o QPluginLoader checks that a plugin is linked against the same
+ \li QPluginLoader checks that a plugin is linked against the same
version of Qt as the application.
- \o QPluginLoader provides direct access to a root component object
+ \li QPluginLoader provides direct access to a root component object
(instance()), instead of forcing you to resolve a C function manually.
\endlist
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 3d7988a8fca..26032323e05 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -190,34 +190,34 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
\table
\header
- \o msb0
- \o msb1
- \o msb2
- \o Variant
+ \li msb0
+ \li msb1
+ \li msb2
+ \li Variant
\row
- \o 0
- \o x
- \o x
- \o NCS (Network Computing System)
+ \li 0
+ \li x
+ \li x
+ \li NCS (Network Computing System)
\row
- \o 1
- \o 0
- \o x
- \o DCE (Distributed Computing Environment)
+ \li 1
+ \li 0
+ \li x
+ \li DCE (Distributed Computing Environment)
\row
- \o 1
- \o 1
- \o 0
- \o Microsoft (GUID)
+ \li 1
+ \li 1
+ \li 0
+ \li Microsoft (GUID)
\row
- \o 1
- \o 1
- \o 1
- \o Reserved for future expansion
+ \li 1
+ \li 1
+ \li 1
+ \li Reserved for future expansion
\endtable
@@ -234,46 +234,46 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
\table
\header
- \o msb0
- \o msb1
- \o msb2
- \o msb3
- \o Version
+ \li msb0
+ \li msb1
+ \li msb2
+ \li msb3
+ \li Version
\row
- \o 0
- \o 0
- \o 0
- \o 1
- \o Time
+ \li 0
+ \li 0
+ \li 0
+ \li 1
+ \li Time
\row
- \o 0
- \o 0
- \o 1
- \o 0
- \o Embedded POSIX
+ \li 0
+ \li 0
+ \li 1
+ \li 0
+ \li Embedded POSIX
\row
- \o 0
- \o 0
- \o 1
- \o 1
- \o Md5(Name)
+ \li 0
+ \li 0
+ \li 1
+ \li 1
+ \li Md5(Name)
\row
- \o 0
- \o 1
- \o 0
- \o 0
- \o Random
+ \li 0
+ \li 1
+ \li 0
+ \li 0
+ \li Random
\row
- \o 0
- \o 1
- \o 0
- \o 1
- \o Sha1
+ \li 0
+ \li 1
+ \li 0
+ \li 1
+ \li Sha1
\endtable
@@ -516,28 +516,28 @@ QUuid QUuid::fromRfc4122(const QByteArray &bytes)
\table
\header
- \o Field #
- \o Source
+ \li Field #
+ \li Source
\row
- \o 1
- \o data1
+ \li 1
+ \li data1
\row
- \o 2
- \o data2
+ \li 2
+ \li data2
\row
- \o 3
- \o data3
+ \li 3
+ \li data3
\row
- \o 4
- \o data4[0] .. data4[1]
+ \li 4
+ \li data4[0] .. data4[1]
\row
- \o 5
- \o data4[2] .. data4[7]
+ \li 5
+ \li data4[2] .. data4[7]
\endtable
*/
@@ -560,28 +560,28 @@ QString QUuid::toString() const
\table
\header
- \o Field #
- \o Source
+ \li Field #
+ \li Source
\row
- \o 1
- \o data1
+ \li 1
+ \li data1
\row
- \o 2
- \o data2
+ \li 2
+ \li data2
\row
- \o 3
- \o data3
+ \li 3
+ \li data3
\row
- \o 4
- \o data4[0] .. data4[1]
+ \li 4
+ \li data4[0] .. data4[1]
\row
- \o 5
- \o data4[2] .. data4[7]
+ \li 5
+ \li data4[2] .. data4[7]
\endtable
@@ -607,24 +607,24 @@ QByteArray QUuid::toByteArray() const
\table
\header
- \o Field #
- \o Source
+ \li Field #
+ \li Source
\row
- \o 1
- \o data1
+ \li 1
+ \li data1
\row
- \o 2
- \o data2
+ \li 2
+ \li data2
\row
- \o 3
- \o data3
+ \li 3
+ \li data3
\row
- \o 4
- \o data4[0] .. data4[7]
+ \li 4
+ \li data4[0] .. data4[7]
\endtable
diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h
index c9c60976d1b..b3aeb410164 100644
--- a/src/corelib/statemachine/qstatemachine.h
+++ b/src/corelib/statemachine/qstatemachine.h
@@ -119,7 +119,7 @@ public:
NoCommonAncestorForTransitionError
};
- QStateMachine(QObject *parent = 0);
+ explicit QStateMachine(QObject *parent = 0);
~QStateMachine();
void addState(QAbstractState *state);
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 5443d6e1b6f..2e3029f3fa5 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -83,16 +83,16 @@
\list
- \o Relaxed - memory ordering is unspecified, leaving the compiler
+ \li Relaxed - memory ordering is unspecified, leaving the compiler
and processor to freely reorder memory accesses.
- \o Acquire - memory access following the atomic operation (in
+ \li Acquire - memory access following the atomic operation (in
program order) may not be re-ordered before the atomic operation.
- \o Release - memory access before the atomic operation (in program
+ \li Release - memory access before the atomic operation (in program
order) may not be re-ordered after the atomic operation.
- \o Ordered - the same Acquire and Release semantics combined.
+ \li Ordered - the same Acquire and Release semantics combined.
\endlist
@@ -180,25 +180,25 @@
\list
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
- \o Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
\endlist
@@ -658,16 +658,16 @@
\list
- \o Relaxed - memory ordering is unspecified, leaving the compiler
+ \li Relaxed - memory ordering is unspecified, leaving the compiler
and processor to freely reorder memory accesses.
- \o Acquire - memory access following the atomic operation (in
+ \li Acquire - memory access following the atomic operation (in
program order) may not be re-ordered before the atomic operation.
- \o Release - memory access before the atomic operation (in program
+ \li Release - memory access before the atomic operation (in program
order) may not be re-ordered after the atomic operation.
- \o Ordered - the same Acquire and Release semantics combined.
+ \li Ordered - the same Acquire and Release semantics combined.
\endlist
@@ -753,20 +753,20 @@
\list
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
- \o Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+ \li Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
- \o Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
+ \li Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
\endlist
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 96338c62dcf..01a69dbd8bf 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -136,7 +136,7 @@ public:
// Atomic API, implemented in qatomic_XXX.h
- T loadAcquire() { return Ops::loadAcquire(_q_value); }
+ T loadAcquire() const { return Ops::loadAcquire(_q_value); }
void storeRelease(T newValue) { Ops::storeRelease(_q_value, newValue); }
static bool isReferenceCountingNative() { return Ops::isReferenceCountingNative(); }
@@ -206,7 +206,7 @@ public:
void store(Type newValue) { _q_value = newValue; }
// Atomic API, implemented in qatomic_XXX.h
- Type loadAcquire() { return Ops::loadAcquire(_q_value); }
+ Type loadAcquire() const { return Ops::loadAcquire(_q_value); }
void storeRelease(Type newValue) { Ops::storeRelease(_q_value, newValue); }
static bool isTestAndSetNative() { return Ops::isTestAndSetNative(); }
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index f4d5e2f8d93..34c040c39b2 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -85,7 +85,7 @@ template struct QGenericAtomicOps
static void orderedMemoryFence() { }
template static inline always_inline
- T load(T &_q_value)
+ T load(const T &_q_value)
{
return _q_value;
}
@@ -97,9 +97,9 @@ template struct QGenericAtomicOps
}
template static inline always_inline
- T loadAcquire(T &_q_value)
+ T loadAcquire(const T &_q_value)
{
- T tmp = *static_cast(&_q_value);
+ T tmp = *static_cast(&_q_value);
BaseClass::acquireMemoryFence();
return tmp;
}
diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp
index b102770d23b..6b6674ccdfa 100644
--- a/src/corelib/thread/qmutexpool.cpp
+++ b/src/corelib/thread/qmutexpool.cpp
@@ -46,9 +46,6 @@
QT_BEGIN_NAMESPACE
-// qt_global_mutexpool is here for backwards compatibility only,
-// use QMutexpool::instance() in new clode.
-Q_CORE_EXPORT QMutexPool *qt_global_mutexpool = 0;
Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive))
/*!
diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h
index ce55a40bb87..f5428bed52d 100644
--- a/src/corelib/thread/qmutexpool_p.h
+++ b/src/corelib/thread/qmutexpool_p.h
@@ -84,8 +84,6 @@ private:
QMutex::RecursionMode recursionMode;
};
-extern Q_CORE_EXPORT QMutexPool *qt_global_mutexpool;
-
QT_END_NAMESPACE
#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 52f5a1d699a..08952eeaa3b 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -66,10 +66,10 @@ QT_BEGIN_NAMESPACE
release():
\list
- \o acquire(\e{n}) tries to acquire \e n resources. If there aren't
+ \li acquire(\e{n}) tries to acquire \e n resources. If there aren't
that many resources available, the call will block until this
is the case.
- \o release(\e{n}) releases \e n resources.
+ \li release(\e{n}) releases \e n resources.
\endlist
There's also a tryAcquire() function that returns immediately if
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index a0714631784..ea6760a1b9b 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -42,7 +42,6 @@
#include "qthread.h"
#include "qthreadstorage.h"
#include "qmutex.h"
-#include "qmutexpool_p.h"
#include "qreadwritelock.h"
#include "qabstracteventdispatcher.h"
@@ -537,33 +536,6 @@ void QThread::run()
(void) exec();
}
-/*! \internal
- Initializes the QThread system.
-*/
-#if defined (Q_OS_WIN)
-void qt_create_tls();
-#endif
-
-void QThread::initialize()
-{
- if (qt_global_mutexpool)
- return;
- qt_global_mutexpool = QMutexPool::instance();
-
-#if defined (Q_OS_WIN)
- qt_create_tls();
-#endif
-}
-
-
-/*! \internal
- Cleans up the QThread system.
-*/
-void QThread::cleanup()
-{
- qt_global_mutexpool = 0;
-}
-
/*! \fn void QThread::setPriority(Priority priority)
\since 4.1
@@ -658,11 +630,11 @@ QThread::Priority QThread::priority() const
Blocks the thread until either of these conditions is met:
\list
- \o The thread associated with this QThread object has finished
+ \li The thread associated with this QThread object has finished
execution (i.e. when it returns from \l{run()}). This function
will return true if the thread has finished. It also returns
true if the thread has not been started yet.
- \o \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
+ \li \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
default), then the wait will never timeout (the thread must
return from \l{run()}). This function will return false if the
wait timed out.
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index ba119afb5d4..953632c6fc6 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -128,9 +128,6 @@ private:
Q_OBJECT
Q_DECLARE_PRIVATE(QThread)
- static void initialize();
- static void cleanup();
-
friend class QCoreApplication;
friend class QThreadData;
};
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index d458ee94724..a0913e5dbcf 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -287,7 +287,7 @@ void *QThreadPrivate::start(void *arg)
else
createEventDispatcher(data);
-#if !defined(QT_NO_DEBUG) && (defined(Q_OS_LINUX) || defined(Q_OS_MAC))
+#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC))
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index af8c99197ec..b7021817c52 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -307,31 +307,6 @@ bool QThreadPoolPrivate::waitForDone(int msecs)
return queue.isEmpty() && activeThreads == 0;
}
-/*! \internal
- Pulls a runnable from the front queue and runs it in the current thread. Blocks
- until the runnable has completed. Returns true if a runnable was found.
-*/
-bool QThreadPoolPrivate::startFrontRunnable()
-{
- QMutexLocker locker(&mutex);
- if (queue.isEmpty())
- return false;
-
- QRunnable *runnable = queue.takeFirst().first;
- const bool autoDelete = runnable->autoDelete();
- bool del = autoDelete && !--runnable->ref;
-
- locker.unlock();
- runnable->run();
- locker.relock();
-
- if (del) {
- delete runnable;
- }
-
- return true;
-}
-
/*! \internal
Seaches for \a runnable in the queue, removes it from the queue and
runs it if found. This functon does not return until the runnable
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index 9a7c09695f0..910e0b07146 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -83,7 +83,6 @@ public:
void startThread(QRunnable *runnable = 0);
void reset();
bool waitForDone(int msecs = -1);
- bool startFrontRunnable();
void stealRunnable(QRunnable *);
mutable QMutex mutex;
diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp
index 1dfa3305bc3..68db8fe2619 100644
--- a/src/corelib/thread/qthreadstorage.cpp
+++ b/src/corelib/thread/qthreadstorage.cpp
@@ -246,11 +246,11 @@ void QThreadStorageData::finish(void **p)
\list
- \o The QThreadStorage destructor does not delete per-thread data.
+ \li The QThreadStorage destructor does not delete per-thread data.
QThreadStorage only deletes per-thread data when the thread exits
or when setLocalData() is called multiple times.
- \o QThreadStorage can be used to store data for the \c main()
+ \li QThreadStorage can be used to store data for the \c main()
thread. QThreadStorage deletes all data set for the \c main()
thread when QApplication is destroyed, regardless of whether or
not the \c main() thread has actually finished.
diff --git a/src/corelib/thread/qwaitcondition.qdoc b/src/corelib/thread/qwaitcondition.qdoc
index 7b861f8f7a4..8c93bd167df 100644
--- a/src/corelib/thread/qwaitcondition.qdoc
+++ b/src/corelib/thread/qwaitcondition.qdoc
@@ -129,9 +129,9 @@
calling thread will block until either of these conditions is met:
\list
- \o Another thread signals it using wakeOne() or wakeAll(). This
+ \li Another thread signals it using wakeOne() or wakeAll(). This
function will return true in this case.
- \o \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
+ \li \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
(the default), then the wait will never timeout (the event
must be signalled). This function will return false if the
wait timed out.
@@ -157,9 +157,9 @@
calling thread will block until either of these conditions is met:
\list
- \o Another thread signals it using wakeOne() or wakeAll(). This
+ \li Another thread signals it using wakeOne() or wakeAll(). This
function will return true in this case.
- \o \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
+ \li \a time milliseconds has elapsed. If \a time is \c ULONG_MAX
(the default), then the wait will never timeout (the event
must be signalled). This function will return false if the
wait timed out.
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index a16ed8b3dc4..5a4a278ad0d 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -159,14 +159,14 @@
bidirectional iterator, and supports the following operations:
\table
- \row \i \c{i += n} \i advances iterator \c i by \c n positions
- \row \i \c{i -= n} \i moves iterator \c i back by \c n positions
- \row \i \c{i + n} or \c{n + i} \i returns the iterator for the item \c
+ \row \li \c{i += n} \li advances iterator \c i by \c n positions
+ \row \li \c{i -= n} \li moves iterator \c i back by \c n positions
+ \row \li \c{i + n} or \c{n + i} \li returns the iterator for the item \c
n positions ahead of iterator \c i
- \row \i \c{i - n} \i returns the iterator for the item \c n positions behind of iterator \c i
- \row \i \c{i - j} \i returns the number of items between iterators \c i and \c j
- \row \i \c{i[n]} \i same as \c{*(i + n)}
- \row \i \c{i < j} \i returns true if iterator \c j comes after iterator \c i
+ \row \li \c{i - n} \li returns the iterator for the item \c n positions behind of iterator \c i
+ \row \li \c{i - j} \li returns the number of items between iterators \c i and \c j
+ \row \li \c{i[n]} \li same as \c{*(i + n)}
+ \row \li \c{i < j} \li returns true if iterator \c j comes after iterator \c i
\endtable
QList and QVector's non-const iterator types are random access iterators.
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 0d5c0f59bac..ac936b1d0a9 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -344,7 +344,7 @@ int qstrcmp(const QByteArray &str1, const QByteArray &str2)
{
int l1 = str1.length();
int l2 = str2.length();
- int ret = memcmp(str1, str2, qMin(l1, l2));
+ int ret = memcmp(str1.constData(), str2.constData(), qMin(l1, l2));
if (ret != 0)
return ret;
@@ -506,7 +506,7 @@ QByteArray qCompress(const uchar* data, int nbytes, int compressionLevel)
from this and any earlier Qt version, back to Qt 3.1 when this
feature was added.
- \bold{Note:} If you want to use this function to uncompress external
+ \b{Note:} If you want to use this function to uncompress external
data that was compressed using zlib, you first need to prepend a four
byte header to the byte array containing the data. The header must
contain the expected length (in bytes) of the uncompressed data,
@@ -996,6 +996,8 @@ QByteArray &QByteArray::operator=(const char *str)
/*! \fn QByteArray::operator const char *() const
\fn QByteArray::operator const void *() const
+ \obsolete Use constData() instead.
+
Returns a pointer to the data stored in the byte array. The
pointer can be used to access the bytes that compose the array.
The data is '\\0'-terminated. The pointer remains valid as long
@@ -2734,7 +2736,7 @@ QDataStream &operator<<(QDataStream &out, const QByteArray &ba)
out << (quint32)0xffffffff;
return out;
}
- return out.writeBytes(ba, ba.size());
+ return out.writeBytes(ba.constData(), ba.size());
}
/*! \relates QByteArray
@@ -3670,12 +3672,12 @@ QByteArray &QByteArray::setNum(qulonglong n, int base)
The format \a f can be any of the following:
\table
- \header \i Format \i Meaning
- \row \i \c e \i format as [-]9.9e[+|-]999
- \row \i \c E \i format as [-]9.9E[+|-]999
- \row \i \c f \i format as [-]9.9
- \row \i \c g \i use \c e or \c f format, whichever is the most concise
- \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
\endtable
With 'e', 'E', and 'f', \a prec is the number of digits after the
@@ -3799,12 +3801,12 @@ QByteArray QByteArray::number(qulonglong n, int base)
which is \c g by default, and can be any of the following:
\table
- \header \i Format \i Meaning
- \row \i \c e \i format as [-]9.9e[+|-]999
- \row \i \c E \i format as [-]9.9E[+|-]999
- \row \i \c f \i format as [-]9.9
- \row \i \c g \i use \c e or \c f format, whichever is the most concise
- \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
\endtable
With 'e', 'E', and 'f', \a prec is the number of digits after the
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index bd3a4a84448..e65a9201c20 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -205,8 +205,10 @@ public:
void squeeze();
#ifndef QT_NO_CAST_FROM_BYTEARRAY
- operator const char *() const;
- operator const void *() const;
+#if QT_DEPRECATED_SINCE(5, 0)
+ QT_DEPRECATED operator const char *() const { return constData(); }
+ QT_DEPRECATED operator const void *() const { return constData(); }
+#endif
#endif
char *data();
const char *data() const;
@@ -413,12 +415,6 @@ inline char QByteArray::operator[](uint i) const
inline bool QByteArray::isEmpty() const
{ return d->size == 0; }
-#ifndef QT_NO_CAST_FROM_BYTEARRAY
-inline QByteArray::operator const char *() const
-{ return d->data(); }
-inline QByteArray::operator const void *() const
-{ return d->data(); }
-#endif
inline char *QByteArray::data()
{ detach(); return d->data(); }
inline const char *QByteArray::data() const
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index 31a0fdc5e6a..be124c94f7c 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -48,14 +48,16 @@
#include "../../3rdparty/sha1/sha1.cpp"
/*
- These typedefs are needed by the RFC6234 code. Normally they would come
- from from stdint.h, but since this header is not available on all platforms
- (MSVC 2008, for example), we need to define them ourselves.
+ These #defines replace the typedefs needed by the RFC6234 code. Normally
+ the typedefs would come from from stdint.h, but since this header is not
+ available on all platforms (MSVC 2008, for example), we #define them to the
+ Qt equivalents.
*/
-typedef QT_PREPEND_NAMESPACE(quint64) uint64_t;
-typedef QT_PREPEND_NAMESPACE(quint32) uint32_t;
-typedef QT_PREPEND_NAMESPACE(quint8) uint8_t;
-typedef QT_PREPEND_NAMESPACE(qint16) int_least16_t;
+#define uint64_t QT_PREPEND_NAMESPACE(quint64)
+#define uint32_t QT_PREPEND_NAMESPACE(quint32)
+#define uint8_t QT_PREPEND_NAMESPACE(quint8)
+#define int_least16_t QT_PREPEND_NAMESPACE(qint16)
+
// Header from rfc6234 with 1 modification:
// sha1.h - commented out '#include ' on line 74
#include "../../3rdparty/rfc6234/sha.h"
@@ -81,16 +83,21 @@ static int SHA384_512AddLength(SHA512Context *context, unsigned int length);
// sha384-512.c - appended 'M' to the SHA224_256AddLength macro on line 304
#include "../../3rdparty/rfc6234/sha384-512.c"
+#undef uint64_t
+#undef uint32_t
+#undef uint68_t
+#undef int_least16_t
+
#include
static inline int SHA224_256AddLength(SHA256Context *context, unsigned int length)
{
- uint32_t addTemp;
+ QT_PREPEND_NAMESPACE(quint32) addTemp;
return SHA224_256AddLengthM(context, length);
}
static inline int SHA384_512AddLength(SHA512Context *context, unsigned int length)
{
- uint64_t addTemp;
+ QT_PREPEND_NAMESPACE(quint64) addTemp;
return SHA384_512AddLengthM(context, length);
}
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index 2bfc03373ab..6ebe389faf5 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -65,7 +65,7 @@ public:
Sha512
};
- QCryptographicHash(Algorithm method);
+ explicit QCryptographicHash(Algorithm method);
~QCryptographicHash();
void reset();
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 70efb5db222..fa5eed4f861 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -306,18 +306,18 @@ int QDate::year() const
the following convention:
\list
- \i 1 = "January"
- \i 2 = "February"
- \i 3 = "March"
- \i 4 = "April"
- \i 5 = "May"
- \i 6 = "June"
- \i 7 = "July"
- \i 8 = "August"
- \i 9 = "September"
- \i 10 = "October"
- \i 11 = "November"
- \i 12 = "December"
+ \li 1 = "January"
+ \li 2 = "February"
+ \li 3 = "March"
+ \li 4 = "April"
+ \li 5 = "May"
+ \li 6 = "June"
+ \li 7 = "July"
+ \li 8 = "August"
+ \li 9 = "September"
+ \li 10 = "October"
+ \li 11 = "November"
+ \li 12 = "December"
\endlist
Returns 0 if the date is invalid.
@@ -521,18 +521,18 @@ int QDate::weekNumber(int *yearNumber) const
The months are enumerated using the following convention:
\list
- \i 1 = "Jan"
- \i 2 = "Feb"
- \i 3 = "Mar"
- \i 4 = "Apr"
- \i 5 = "May"
- \i 6 = "Jun"
- \i 7 = "Jul"
- \i 8 = "Aug"
- \i 9 = "Sep"
- \i 10 = "Oct"
- \i 11 = "Nov"
- \i 12 = "Dec"
+ \li 1 = "Jan"
+ \li 2 = "Feb"
+ \li 3 = "Mar"
+ \li 4 = "Apr"
+ \li 5 = "May"
+ \li 6 = "Jun"
+ \li 7 = "Jul"
+ \li 8 = "Aug"
+ \li 9 = "Sep"
+ \li 10 = "Oct"
+ \li 11 = "Nov"
+ \li 12 = "Dec"
\endlist
The month names will be localized according to the system's locale
@@ -568,18 +568,18 @@ QString QDate::shortMonthName(int month, QDate::MonthNameType type)
The months are enumerated using the following convention:
\list
- \i 1 = "January"
- \i 2 = "February"
- \i 3 = "March"
- \i 4 = "April"
- \i 5 = "May"
- \i 6 = "June"
- \i 7 = "July"
- \i 8 = "August"
- \i 9 = "September"
- \i 10 = "October"
- \i 11 = "November"
- \i 12 = "December"
+ \li 1 = "January"
+ \li 2 = "February"
+ \li 3 = "March"
+ \li 4 = "April"
+ \li 5 = "May"
+ \li 6 = "June"
+ \li 7 = "July"
+ \li 8 = "August"
+ \li 9 = "September"
+ \li 10 = "October"
+ \li 11 = "November"
+ \li 12 = "December"
\endlist
The month names will be localized according to the system's locale
@@ -615,13 +615,13 @@ QString QDate::longMonthName(int month, MonthNameType type)
The days are enumerated using the following convention:
\list
- \i 1 = "Mon"
- \i 2 = "Tue"
- \i 3 = "Wed"
- \i 4 = "Thu"
- \i 5 = "Fri"
- \i 6 = "Sat"
- \i 7 = "Sun"
+ \li 1 = "Mon"
+ \li 2 = "Tue"
+ \li 3 = "Wed"
+ \li 4 = "Thu"
+ \li 5 = "Fri"
+ \li 6 = "Sat"
+ \li 7 = "Sun"
\endlist
The day names will be localized according to the system's locale
@@ -657,13 +657,13 @@ QString QDate::shortDayName(int weekday, MonthNameType type)
The days are enumerated using the following convention:
\list
- \i 1 = "Monday"
- \i 2 = "Tuesday"
- \i 3 = "Wednesday"
- \i 4 = "Thursday"
- \i 5 = "Friday"
- \i 6 = "Saturday"
- \i 7 = "Sunday"
+ \li 1 = "Monday"
+ \li 2 = "Tuesday"
+ \li 3 = "Wednesday"
+ \li 4 = "Thursday"
+ \li 5 = "Friday"
+ \li 6 = "Saturday"
+ \li 7 = "Sunday"
\endlist
The day names will be localized according to the system's locale
@@ -781,25 +781,25 @@ QString QDate::toString(Qt::DateFormat f) const
These expressions may be used:
\table
- \header \i Expression \i Output
- \row \i d \i the day as number without a leading zero (1 to 31)
- \row \i dd \i the day as number with a leading zero (01 to 31)
- \row \i ddd
- \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li the day as number without a leading zero (1 to 31)
+ \row \li dd \li the day as number with a leading zero (01 to 31)
+ \row \li ddd
+ \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \li dddd
+ \li the long localized day name (e.g. 'Monday' to 'Sunday').
Uses QDate::longDayName().
- \row \i M \i the month as number without a leading zero (1 to 12)
- \row \i MM \i the month as number with a leading zero (01 to 12)
- \row \i MMM
- \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li the month as number without a leading zero (1 to 12)
+ \row \li MM \li the month as number with a leading zero (01 to 12)
+ \row \li MMM
+ \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i the long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li the long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i the year as two digit number (00 to 99)
- \row \i yyyy \i the year as four digit number. If the year is negative,
+ \row \li yy \li the year as two digit number (00 to 99)
+ \row \li yyyy \li the year as four digit number. If the year is negative,
a minus sign is prepended in addition.
\endtable
@@ -812,10 +812,10 @@ QString QDate::toString(Qt::DateFormat f) const
1969):
\table
- \header \o Format \o Result
- \row \o dd.MM.yyyy \o 20.07.1969
- \row \o ddd MMMM d yy \o Sun July 20 69
- \row \o 'The day is' dddd \o The day is Sunday
+ \header \li Format \li Result
+ \row \li dd.MM.yyyy \li 20.07.1969
+ \row \li ddd MMMM d yy \li Sun July 20 69
+ \row \li 'The day is' dddd \li The day is Sunday
\endtable
If the datetime is invalid, an empty string will be returned.
@@ -1191,25 +1191,25 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the format:
\table
- \header \i Expression \i Output
- \row \i d \i The day as a number without a leading zero (1 to 31)
- \row \i dd \i The day as a number with a leading zero (01 to 31)
- \row \i ddd
- \i The abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li The day as a number without a leading zero (1 to 31)
+ \row \li dd \li The day as a number with a leading zero (01 to 31)
+ \row \li ddd
+ \li The abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i The long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \li dddd
+ \li The long localized day name (e.g. 'Monday' to 'Sunday').
Uses QDate::longDayName().
- \row \i M \i The month as a number without a leading zero (1 to 12)
- \row \i MM \i The month as a number with a leading zero (01 to 12)
- \row \i MMM
- \i The abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li The month as a number without a leading zero (1 to 12)
+ \row \li MM \li The month as a number with a leading zero (01 to 12)
+ \row \li MMM
+ \li The abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i The long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li The long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i The year as two digit number (00 to 99)
- \row \i yyyy \i The year as four digit number. If the year is negative,
+ \row \li yy \li The year as two digit number (00 to 99)
+ \row \li yyyy \li The year as four digit number. If the year is negative,
a minus sign is prepended in addition.
\endtable
@@ -1233,10 +1233,10 @@ QDate QDate::fromString(const QString& s, Qt::DateFormat f)
defaults are used:
\table
- \header \i Field \i Default value
- \row \i Year \i 1900
- \row \i Month \i 1
- \row \i Day \i 1
+ \header \li Field \li Default value
+ \row \li Year \li 1900
+ \row \li Month \li 1
+ \row \li Day \li 1
\endtable
The following examples demonstrate the default values:
@@ -1543,26 +1543,26 @@ QString QTime::toString(Qt::DateFormat format) const
These expressions may be used:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i H
- \i the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \i HH
- \i the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP or A
- \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
- \row \i ap or a
- \i use am/pm display. \e ap will be replaced by either "am" or "pm".
- \row \i t \i the timezone (for example "CEST")
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li H
+ \li the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \li HH
+ \li the hour with a leading zero (00 to 23, even with AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP or A
+ \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
+ \row \li ap or a
+ \li use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \row \li t \li the timezone (for example "CEST")
\endtable
All other input characters will be ignored. Any sequence of characters that
@@ -1573,10 +1573,10 @@ QString QTime::toString(Qt::DateFormat format) const
Example format strings (assuming that the QTime is 14:13:09.042)
\table
- \header \i Format \i Result
- \row \i hh:mm:ss.zzz \i 14:13:09.042
- \row \i h:m:s ap \i 2:13:9 pm
- \row \i H:m:s a \i 14:13:9 pm
+ \header \li Format \li Result
+ \row \li hh:mm:ss.zzz \li 14:13:09.042
+ \row \li h:m:s ap \li 2:13:9 pm
+ \row \li H:m:s a \li 14:13:9 pm
\endtable
If the datetime is invalid, an empty string will be returned.
@@ -1824,21 +1824,21 @@ QTime QTime::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the format:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP
- \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
- \row \i ap
- \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP
+ \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
+ \row \li ap
+ \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
\endtable
All other input characters will be treated as text. Any sequence
@@ -2515,45 +2515,45 @@ QString QDateTime::toString(Qt::DateFormat f) const
These expressions may be used for the date:
\table
- \header \i Expression \i Output
- \row \i d \i the day as number without a leading zero (1 to 31)
- \row \i dd \i the day as number with a leading zero (01 to 31)
- \row \i ddd
- \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li the day as number without a leading zero (1 to 31)
+ \row \li dd \li the day as number with a leading zero (01 to 31)
+ \row \li ddd
+ \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
+ \row \li dddd
+ \li the long localized day name (e.g. 'Monday' to 'Qt::Sunday').
Uses QDate::longDayName().
- \row \i M \i the month as number without a leading zero (1-12)
- \row \i MM \i the month as number with a leading zero (01-12)
- \row \i MMM
- \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li the month as number without a leading zero (1-12)
+ \row \li MM \li the month as number with a leading zero (01-12)
+ \row \li MMM
+ \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i the long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li the long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i the year as two digit number (00-99)
- \row \i yyyy \i the year as four digit number
+ \row \li yy \li the year as two digit number (00-99)
+ \row \li yyyy \li the year as four digit number
\endtable
These expressions may be used for the time:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP
- \i use AM/PM display. \e AP will be replaced by either "AM" or "PM".
- \row \i ap
- \i use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP
+ \li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
+ \row \li ap
+ \li use am/pm display. \e ap will be replaced by either "am" or "pm".
\endtable
All other input characters will be ignored. Any sequence of characters that
@@ -2565,11 +2565,11 @@ QString QDateTime::toString(Qt::DateFormat f) const
14:13:09):
\table
- \header \i Format \i Result
- \row \i dd.MM.yyyy \i 21.05.2001
- \row \i ddd MMMM d yy \i Tue May 21 01
- \row \i hh:mm:ss.zzz \i 14:13:09.042
- \row \i h:m:s ap \i 2:13:9 pm
+ \header \li Format \li Result
+ \row \li dd.MM.yyyy \li 21.05.2001
+ \row \li ddd MMMM d yy \li Tue May 21 01
+ \row \li hh:mm:ss.zzz \li 14:13:09.042
+ \row \li h:m:s ap \li 2:13:9 pm
\endtable
If the datetime is invalid, an empty string will be returned.
@@ -3367,25 +3367,25 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the date part of the format string:
\table
- \header \i Expression \i Output
- \row \i d \i the day as number without a leading zero (1 to 31)
- \row \i dd \i the day as number with a leading zero (01 to 31)
- \row \i ddd
- \i the abbreviated localized day name (e.g. 'Mon' to 'Sun').
+ \header \li Expression \li Output
+ \row \li d \li the day as number without a leading zero (1 to 31)
+ \row \li dd \li the day as number with a leading zero (01 to 31)
+ \row \li ddd
+ \li the abbreviated localized day name (e.g. 'Mon' to 'Sun').
Uses QDate::shortDayName().
- \row \i dddd
- \i the long localized day name (e.g. 'Monday' to 'Sunday').
+ \row \li dddd
+ \li the long localized day name (e.g. 'Monday' to 'Sunday').
Uses QDate::longDayName().
- \row \i M \i the month as number without a leading zero (1-12)
- \row \i MM \i the month as number with a leading zero (01-12)
- \row \i MMM
- \i the abbreviated localized month name (e.g. 'Jan' to 'Dec').
+ \row \li M \li the month as number without a leading zero (1-12)
+ \row \li MM \li the month as number with a leading zero (01-12)
+ \row \li MMM
+ \li the abbreviated localized month name (e.g. 'Jan' to 'Dec').
Uses QDate::shortMonthName().
- \row \i MMMM
- \i the long localized month name (e.g. 'January' to 'December').
+ \row \li MMMM
+ \li the long localized month name (e.g. 'January' to 'December').
Uses QDate::longMonthName().
- \row \i yy \i the year as two digit number (00-99)
- \row \i yyyy \i the year as four digit number
+ \row \li yy \li the year as two digit number (00-99)
+ \row \li yyyy \li the year as four digit number
\endtable
\note Unlike the other version of this function, day and month names must
@@ -3395,25 +3395,25 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
These expressions may be used for the time part of the format string:
\table
- \header \i Expression \i Output
- \row \i h
- \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
- \row \i hh
- \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
- \row \i H
- \i the hour without a leading zero (0 to 23, even with AM/PM display)
- \row \i HH
- \i the hour with a leading zero (00 to 23, even with AM/PM display)
- \row \i m \i the minute without a leading zero (0 to 59)
- \row \i mm \i the minute with a leading zero (00 to 59)
- \row \i s \i the second without a leading zero (0 to 59)
- \row \i ss \i the second with a leading zero (00 to 59)
- \row \i z \i the milliseconds without leading zeroes (0 to 999)
- \row \i zzz \i the milliseconds with leading zeroes (000 to 999)
- \row \i AP or A
- \i interpret as an AM/PM time. \e AP must be either "AM" or "PM".
- \row \i ap or a
- \i Interpret as an AM/PM time. \e ap must be either "am" or "pm".
+ \header \li Expression \li Output
+ \row \li h
+ \li the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)
+ \row \li hh
+ \li the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)
+ \row \li H
+ \li the hour without a leading zero (0 to 23, even with AM/PM display)
+ \row \li HH
+ \li the hour with a leading zero (00 to 23, even with AM/PM display)
+ \row \li m \li the minute without a leading zero (0 to 59)
+ \row \li mm \li the minute with a leading zero (00 to 59)
+ \row \li s \li the second without a leading zero (0 to 59)
+ \row \li ss \li the second with a leading zero (00 to 59)
+ \row \li z \li the milliseconds without leading zeroes (0 to 999)
+ \row \li zzz \li the milliseconds with leading zeroes (000 to 999)
+ \row \li AP or A
+ \li interpret as an AM/PM time. \e AP must be either "AM" or "PM".
+ \row \li ap or a
+ \li Interpret as an AM/PM time. \e ap must be either "am" or "pm".
\endtable
All other input characters will be treated as text. Any sequence
@@ -3437,13 +3437,13 @@ QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f)
defaults are used:
\table
- \header \i Field \i Default value
- \row \i Year \i 1900
- \row \i Month \i 1 (January)
- \row \i Day \i 1
- \row \i Hour \i 0
- \row \i Minute \i 0
- \row \i Second \i 0
+ \header \li Field \li Default value
+ \row \li Year \li 1900
+ \row \li Month \li 1 (January)
+ \row \li Day \li 1
+ \row \li Hour \li 0
+ \row \li Minute \li 0
+ \row \li Second \li 0
\endtable
For example:
@@ -3511,7 +3511,10 @@ void QDateTime::detach()
QDataStream &operator<<(QDataStream &out, const QDate &date)
{
- return out << (qint64)(date.jd);
+ if (out.version() < QDataStream::Qt_5_0)
+ return out << quint32(date.jd);
+ else
+ return out << qint64(date.jd);
}
/*!
@@ -3524,9 +3527,16 @@ QDataStream &operator<<(QDataStream &out, const QDate &date)
QDataStream &operator>>(QDataStream &in, QDate &date)
{
- qint64 jd;
- in >> jd;
- date.jd = jd;
+ if (in.version() < QDataStream::Qt_5_0) {
+ quint32 jd;
+ in >> jd;
+ date.jd = jd;
+ } else {
+ qint64 jd;
+ in >> jd;
+ date.jd = jd;
+ }
+
return in;
}
diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp
index 7d08547ab89..11126b814d5 100644
--- a/src/corelib/tools/qharfbuzz.cpp
+++ b/src/corelib/tools/qharfbuzz.cpp
@@ -122,7 +122,12 @@ HB_Bool qShapeItem(HB_ShaperItem *item)
HB_Face qHBNewFace(void *font, HB_GetFontTableFunc tableFunc)
{
- return HB_NewFace(font, tableFunc);
+ return HB_AllocFace(font, tableFunc);
+}
+
+HB_Face qHBLoadFace(HB_Face face)
+{
+ return HB_LoadFace(face);
}
void qHBFreeFace(HB_Face face)
diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/tools/qharfbuzz_p.h
index cc575ddffae..3cef3a55dd7 100644
--- a/src/corelib/tools/qharfbuzz_p.h
+++ b/src/corelib/tools/qharfbuzz_p.h
@@ -68,6 +68,7 @@ Q_CORE_EXPORT HB_Bool qShapeItem(HB_ShaperItem *item);
// ### temporary
Q_CORE_EXPORT HB_Face qHBNewFace(void *font, HB_GetFontTableFunc tableFunc);
Q_CORE_EXPORT void qHBFreeFace(HB_Face);
+Q_CORE_EXPORT HB_Face qHBLoadFace(HB_Face face);
Q_DECLARE_TYPEINFO(HB_GlyphAttributes, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(HB_FixedPoint, Q_PRIMITIVE_TYPE);
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index e0cd068158f..897de77f2ec 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -547,11 +547,11 @@ void QHashData::checkSanity()
differences are:
\list
- \i QHash provides faster lookups than QMap. (See \l{Algorithmic
+ \li QHash provides faster lookups than QMap. (See \l{Algorithmic
Complexity} for details.)
- \i When iterating over a QMap, the items are always sorted by
+ \li When iterating over a QMap, the items are always sorted by
key. With QHash, the items are arbitrarily ordered.
- \i The key type of a QMap must provide operator<(). The key
+ \li The key type of a QMap must provide operator<(). The key
type of a QHash must provide operator==() and a global
hash function called qHash() (see the related non-member
functions).
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
index 78f1c442636..39ec0ed97c8 100644
--- a/src/corelib/tools/qline.cpp
+++ b/src/corelib/tools/qline.cpp
@@ -61,8 +61,8 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qline-point.png
- \o \inlineimage qline-coordinates.png
+ \li \inlineimage qline-point.png
+ \li \inlineimage qline-coordinates.png
\endtable
The positions of the line's start and end points can be retrieved
@@ -322,8 +322,8 @@ QDataStream &operator>>(QDataStream &stream, QLine &line)
\table
\row
- \o \inlineimage qline-point.png
- \o \inlineimage qline-coordinates.png
+ \li \inlineimage qline-point.png
+ \li \inlineimage qline-coordinates.png
\endtable
The positions of the line's start and end points can be retrieved
@@ -360,11 +360,11 @@ QDataStream &operator>>(QDataStream &stream, QLine &line)
\table
\row
- \o \inlineimage qlinef-unbounded.png
- \o \inlineimage qlinef-bounded.png
+ \li \inlineimage qlinef-unbounded.png
+ \li \inlineimage qlinef-bounded.png
\row
- \o QLineF::UnboundedIntersection
- \o QLineF::BoundedIntersection
+ \li QLineF::UnboundedIntersection
+ \li QLineF::BoundedIntersection
\endtable
\value NoIntersection Indicates that the lines do not intersect;
@@ -795,8 +795,8 @@ qreal QLineF::angleTo(const QLineF &l) const
\table
\row
- \o \inlineimage qlinef-angle-identicaldirection.png
- \o \inlineimage qlinef-angle-oppositedirection.png
+ \li \inlineimage qlinef-angle-identicaldirection.png
+ \li \inlineimage qlinef-angle-oppositedirection.png
\endtable
When the lines are parallel, this function returns 0 if they have
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index db5404e4296..6e66f804c04 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -65,16 +65,16 @@ const QLinkedListData QLinkedListData::shared_null = {
functionality. Here's an overview:
\list
- \i For most purposes, QList is the right class to use. Its
+ \li For most purposes, QList is the right class to use. Its
index-based API is more convenient than QLinkedList's
iterator-based API, and it is usually faster than
QVector because of the way it stores its items in
memory (see \l{Algorithmic Complexity} for details).
It also expands to less code in your executable.
- \i If you need a real linked list, with guarantees of \l{constant
+ \li If you need a real linked list, with guarantees of \l{constant
time} insertions in the middle of the list and iterators to
items rather than indexes, use QLinkedList.
- \i If you want the items to occupy adjacent memory positions,
+ \li If you want the items to occupy adjacent memory positions,
use QVector.
\endlist
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 1b6610a724e..9ee4c0a797a 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -338,15 +338,15 @@ void **QListData::erase(void **xi)
functionality. Here's an overview:
\list
- \i For most purposes, QList is the right class to use. Its
+ \li For most purposes, QList is the right class to use. Its
index-based API is more convenient than QLinkedList's
iterator-based API, and it is usually faster than
QVector because of the way it stores its items in
memory. It also expands to less code in your executable.
- \i If you need a real linked list, with guarantees of \l{constant
+ \li If you need a real linked list, with guarantees of \l{constant
time} insertions in the middle of the list and iterators to
items rather than indexes, use QLinkedList.
- \i If you want the items to occupy adjacent memory positions,
+ \li If you want the items to occupy adjacent memory positions,
use QVector.
\endlist
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 31f776dc2e2..086ca7bd388 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -621,10 +621,10 @@ static quint16 localePrivateIndex(const QLocalePrivate *p)
"language[_script][_country][.codeset][@modifier]" or "C", where:
\list
- \i language is a lowercase, two-letter, ISO 639 language code,
- \i script is a titlecase, four-letter, ISO 15924 script code,
- \i country is an uppercase, two- or three-letter, ISO 3166 country code (also "419" as defined by United Nations),
- \i and codeset and modifier are ignored.
+ \li language is a lowercase, two-letter, ISO 639 language code,
+ \li script is a titlecase, four-letter, ISO 15924 script code,
+ \li country is an uppercase, two- or three-letter, ISO 3166 country code (also "419" as defined by United Nations),
+ \li and codeset and modifier are ignored.
\endlist
The separator can be either underscore or a minus sign.
@@ -671,11 +671,11 @@ QLocale::QLocale()
country.
\list
- \i If the language/country pair is found in the database, it is used.
- \i If the language is found but the country is not, or if the country
+ \li If the language/country pair is found in the database, it is used.
+ \li If the language is found but the country is not, or if the country
is \c AnyCountry, the language is used with the most
appropriate available country (for example, Germany for German),
- \i If neither the language nor the country are found, QLocale
+ \li If neither the language nor the country are found, QLocale
defaults to the default locale (see setDefault()).
\endlist
@@ -707,14 +707,14 @@ QLocale::QLocale(Language language, Country country)
\a country.
\list
- \i If the language/script/country is found in the database, it is used.
- \i If both \a script is AnyScript and \a country is AnyCountry, the
+ \li If the language/script/country is found in the database, it is used.
+ \li If both \a script is AnyScript and \a country is AnyCountry, the
language is used with the most appropriate available script and country
(for example, Germany for German),
- \i If either \a script is AnyScript or \a country is AnyCountry, the
+ \li If either \a script is AnyScript or \a country is AnyCountry, the
language is used with the first locale that matches the given \a script
and \a country.
- \i If neither the language nor the country are found, QLocale
+ \li If neither the language nor the country are found, QLocale
defaults to the default locale (see setDefault()).
\endlist
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index c029f627b2f..2ecd9341009 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -42,7 +42,6 @@
#ifndef QLOCALE_H
#define QLOCALE_H
-#include
#include
#include
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index 3a386c17d6f..8e90d7d94ee 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -51,12 +51,12 @@
following effects:
\list
- \i If a QLocale object is constructed with the default constructor,
+ \li If a QLocale object is constructed with the default constructor,
it will use the default locale's settings.
- \i QString::toInt(), QString::toDouble(), etc., interpret the
+ \li QString::toInt(), QString::toDouble(), etc., interpret the
string according to the default locale. If this fails, it
falls back on the "C" locale.
- \i QString::arg() uses the default locale to format a number when
+ \li QString::arg() uses the default locale to format a number when
its position specifier in the format string contains an 'L',
e.g. "%L1".
\endlist
@@ -69,11 +69,11 @@
of three things can happen:
\list
- \i If the language/country pair is found in the database, it is used.
- \i If the language is found but the country is not, or if the country
+ \li If the language/country pair is found in the database, it is used.
+ \li If the language is found but the country is not, or if the country
is \c AnyCountry, the language is used with the most
appropriate available country (for example, Germany for German),
- \i If neither the language nor the country are found, QLocale
+ \li If neither the language nor the country are found, QLocale
defaults to the default locale (see setDefault()).
\endlist
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index c6902ca2060..ad7c9706c4a 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -55,7 +55,7 @@
#include "QtCore/qstring.h"
#include "QtCore/qvarlengtharray.h"
-#include "QtCore/qmetatype.h"
+#include "QtCore/qvariant.h"
#include "qlocale.h"
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 31a29d7fe15..2d6b8047a6d 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -601,7 +601,7 @@ QT_END_INCLUDE_NAMESPACE
#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
#endif
-static inline ULong _getWord0(const NEEDS_VOLATILE double x)
+static inline ULong getWord0(const NEEDS_VOLATILE double x)
{
const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -611,7 +611,7 @@ static inline ULong _getWord0(const NEEDS_VOLATILE double x)
}
}
-static inline void _setWord0(NEEDS_VOLATILE double *x, ULong l)
+static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
{
NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -627,7 +627,7 @@ static inline void _setWord0(NEEDS_VOLATILE double *x, ULong l)
}
}
-static inline ULong _getWord1(const NEEDS_VOLATILE double x)
+static inline ULong getWord1(const NEEDS_VOLATILE double x)
{
const NEEDS_VOLATILE uchar *ptr = reinterpret_cast(&x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -636,7 +636,7 @@ static inline ULong _getWord1(const NEEDS_VOLATILE double x)
return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0];
}
}
-static inline void _setWord1(NEEDS_VOLATILE double *x, ULong l)
+static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
{
NEEDS_VOLATILE uchar *ptr = reinterpret_cast(x);
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
@@ -652,42 +652,6 @@ static inline void _setWord1(NEEDS_VOLATILE double *x, ULong l)
}
}
-static inline ULong getWord0(const NEEDS_VOLATILE double x)
-{
-#ifdef QT_ARMFPA
- return _getWord1(x);
-#else
- return _getWord0(x);
-#endif
-}
-
-static inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
-{
-#ifdef QT_ARMFPA
- _setWord1(x, l);
-#else
- _setWord0(x, l);
-#endif
-}
-
-static inline ULong getWord1(const NEEDS_VOLATILE double x)
-{
-#ifdef QT_ARMFPA
- return _getWord0(x);
-#else
- return _getWord1(x);
-#endif
-}
-
-static inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
-{
-#ifdef QT_ARMFPA
- _setWord0(x, l);
-#else
- _setWord1(x, l);
-#endif
-}
-
static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
{
diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h
index 2dc5c03a20e..d920d41cb3e 100644
--- a/src/corelib/tools/qlocale_tools_p.h
+++ b/src/corelib/tools/qlocale_tools_p.h
@@ -97,15 +97,11 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
inline bool isZero(double d)
{
uchar *ch = (uchar *)&d;
-#ifdef QT_ARMFPA
- return !(ch[3] & 0x7F || ch[2] || ch[1] || ch[0] || ch[7] || ch[6] || ch[5] || ch[4]);
-#else
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]);
} else {
return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]);
}
-#endif
}
// Removes thousand-group separators in "C" locale.
diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp
index 6ace96f7715..f2876912b40 100644
--- a/src/corelib/tools/qlocale_unix.cpp
+++ b/src/corelib/tools/qlocale_unix.cpp
@@ -98,7 +98,7 @@ QLocale QSystemLocale::fallbackLocale() const
lang = qgetenv("LC_NUMERIC");
if (lang.isEmpty())
lang = qgetenv("LANG");
- return QLocale(QLatin1String(lang));
+ return QLocale(QString::fromLatin1(lang));
}
QVariant QSystemLocale::query(QueryType type, QVariant in) const
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 474e9cb59df..c922d7aab02 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -232,11 +232,11 @@ void QMapData::dump()
differences are:
\list
- \i QHash provides faster lookups than QMap. (See \l{Algorithmic
+ \li QHash provides faster lookups than QMap. (See \l{Algorithmic
Complexity} for details.)
- \i When iterating over a QHash, the items are arbitrarily ordered.
+ \li When iterating over a QHash, the items are arbitrarily ordered.
With QMap, the items are always sorted by key.
- \i The key type of a QHash must provide operator==() and a global
+ \li The key type of a QHash must provide operator==() and a global
qHash(Key) function. The key type of a QMap must provide
operator<() specifying a total order.
\endlist
diff --git a/src/corelib/tools/qpair.h b/src/corelib/tools/qpair.h
index 501f2af3e6d..4dc28f2d26e 100644
--- a/src/corelib/tools/qpair.h
+++ b/src/corelib/tools/qpair.h
@@ -55,16 +55,30 @@ struct QPair
typedef T1 first_type;
typedef T2 second_type;
- QPair() : first(T1()), second(T2()) {}
+ QPair() : first(), second() {}
QPair(const T1 &t1, const T2 &t2) : first(t1), second(t2) {}
-
- QPair &operator=(const QPair &other)
- { first = other.first; second = other.second; return *this; }
+ // compiler-generated copy/move ctor/assignment operators are fine!
T1 first;
T2 second;
};
+// mark QPair as complex/movable/primitive depending on the
+// typeinfos of the constituents:
+template
+class QTypeInfo< QPair >
+{
+public:
+ enum {
+ isComplex = QTypeInfo::isComplex || QTypeInfo::isComplex,
+ isStatic = QTypeInfo::isStatic || QTypeInfo::isStatic,
+ isLarge = sizeof(QPair) > sizeof(void*),
+ isPointer = false,
+ isDummy = false,
+ sizeOf = sizeof(QPair)
+ };
+};
+
template
Q_INLINE_TEMPLATE bool operator==(const QPair &p1, const QPair &p2)
{ return p1.first == p2.first && p1.second == p2.second; }
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index 7ff883a99a6..aeab97803de 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -99,11 +99,11 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qrect-intersect.png
- \o \inlineimage qrect-unite.png
+ \li \inlineimage qrect-intersect.png
+ \li \inlineimage qrect-unite.png
\row
- \o intersected()
- \o united()
+ \li intersected()
+ \li united()
\endtable
The isEmpty() function returns true if left() > right() or top() >
@@ -139,17 +139,17 @@ QT_BEGIN_NAMESPACE
\table
\row
- \o \inlineimage qrect-diagram-zero.png
- \o \inlineimage qrect-diagram-one.png
+ \li \inlineimage qrect-diagram-zero.png
+ \li \inlineimage qrect-diagram-one.png
\row
- \o Logical representation
- \o One pixel wide pen
+ \li Logical representation
+ \li One pixel wide pen
\row
- \o \inlineimage qrect-diagram-two.png
- \o \inlineimage qrect-diagram-three.png
+ \li \inlineimage qrect-diagram-two.png
+ \li \inlineimage qrect-diagram-three.png
\row
- \o Two pixel wide pen
- \o Three pixel wide pen
+ \li Two pixel wide pen
+ \li Three pixel wide pen
\endtable
\section1 Coordinates
@@ -1278,11 +1278,11 @@ QDebug operator<<(QDebug dbg, const QRect &r) {
\table
\row
- \o \inlineimage qrect-intersect.png
- \o \inlineimage qrect-unite.png
+ \li \inlineimage qrect-intersect.png
+ \li \inlineimage qrect-unite.png
\row
- \o intersected()
- \o united()
+ \li intersected()
+ \li united()
\endtable
The isEmpty() function returns true if the rectangle's width or
@@ -1318,17 +1318,17 @@ QDebug operator<<(QDebug dbg, const QRect &r) {
\table
\row
- \o \inlineimage qrect-diagram-zero.png
- \o \inlineimage qrectf-diagram-one.png
+ \li \inlineimage qrect-diagram-zero.png
+ \li \inlineimage qrectf-diagram-one.png
\row
- \o Logical representation
- \o One pixel wide pen
+ \li Logical representation
+ \li One pixel wide pen
\row
- \o \inlineimage qrectf-diagram-two.png
- \o \inlineimage qrectf-diagram-three.png
+ \li \inlineimage qrectf-diagram-two.png
+ \li \inlineimage qrectf-diagram-three.png
\row
- \o Two pixel wide pen
- \o Three pixel wide pen
+ \li Two pixel wide pen
+ \li Three pixel wide pen
\endtable
\section1 Coordinates
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index d7bcd0edbce..29b34243150 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -90,21 +90,21 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
substrings in a text. This is useful in many contexts, e.g.,
\table
- \row \i Validation
- \i A regexp can test whether a substring meets some criteria,
+ \row \li Validation
+ \li A regexp can test whether a substring meets some criteria,
e.g. is an integer or contains no whitespace.
- \row \i Searching
- \i A regexp provides more powerful pattern matching than
+ \row \li Searching
+ \li A regexp provides more powerful pattern matching than
simple substring matching, e.g., match one of the words
\e{mail}, \e{letter} or \e{correspondence}, but none of the
words \e{email}, \e{mailman}, \e{mailer}, \e{letterbox}, etc.
- \row \i Search and Replace
- \i A regexp can replace all occurrences of a substring with a
+ \row \li Search and Replace
+ \li A regexp can replace all occurrences of a substring with a
different substring, e.g., replace all occurrences of \e{&}
with \e{\&} except where the \e{&} is already followed by
an \e{amp;}.
- \row \i String Splitting
- \i A regexp can be used to identify where a string should be
+ \row \li String Splitting
+ \li A regexp can be used to identify where a string should be
split apart, e.g. splitting tab-delimited strings.
\endtable
@@ -127,18 +127,18 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\section1 Introduction
Regexps are built up from expressions, quantifiers, and
- assertions. The simplest expression is a character, e.g. \bold{x}
- or \bold{5}. An expression can also be a set of characters
- enclosed in square brackets. \bold{[ABCD]} will match an \bold{A}
- or a \bold{B} or a \bold{C} or a \bold{D}. We can write this same
- expression as \bold{[A-D]}, and an experession to match any
+ assertions. The simplest expression is a character, e.g. \b{x}
+ or \b{5}. An expression can also be a set of characters
+ enclosed in square brackets. \b{[ABCD]} will match an \b{A}
+ or a \b{B} or a \b{C} or a \b{D}. We can write this same
+ expression as \b{[A-D]}, and an experession to match any
captital letter in the English alphabet is written as
- \bold{[A-Z]}.
+ \b{[A-Z]}.
A quantifier specifies the number of occurrences of an expression
- that must be matched. \bold{x{1,1}} means match one and only one
- \bold{x}. \bold{x{1,5}} means match a sequence of \bold{x}
- characters that contains at least one \bold{x} but no more than
+ that must be matched. \b{x{1,1}} means match one and only one
+ \b{x}. \b{x{1,5}} means match a sequence of \b{x}
+ characters that contains at least one \b{x} but no more than
five.
Note that in general regexps cannot be used to check for balanced
@@ -156,35 +156,35 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Suppose we want a regexp to match integers in the range 0 to 99.
At least one digit is required, so we start with the expression
- \bold{[0-9]{1,1}}, which matches a single digit exactly once. This
+ \b{[0-9]{1,1}}, which matches a single digit exactly once. This
regexp matches integers in the range 0 to 9. To match integers up
to 99, increase the maximum number of occurrences to 2, so the
- regexp becomes \bold{[0-9]{1,2}}. This regexp satisfies the
+ regexp becomes \b{[0-9]{1,2}}. This regexp satisfies the
original requirement to match integers from 0 to 99, but it will
also match integers that occur in the middle of strings. If we
want the matched integer to be the whole string, we must use the
- anchor assertions, \bold{^} (caret) and \bold{$} (dollar). When
- \bold{^} is the first character in a regexp, it means the regexp
- must match from the beginning of the string. When \bold{$} is the
+ anchor assertions, \b{^} (caret) and \b{$} (dollar). When
+ \b{^} is the first character in a regexp, it means the regexp
+ must match from the beginning of the string. When \b{$} is the
last character of the regexp, it means the regexp must match to
- the end of the string. The regexp becomes \bold{^[0-9]{1,2}$}.
- Note that assertions, e.g. \bold{^} and \bold{$}, do not match
+ the end of the string. The regexp becomes \b{^[0-9]{1,2}$}.
+ Note that assertions, e.g. \b{^} and \b{$}, do not match
characters but locations in the string.
If you have seen regexps described elsewhere, they may have looked
different from the ones shown here. This is because some sets of
characters and some quantifiers are so common that they have been
- given special symbols to represent them. \bold{[0-9]} can be
- replaced with the symbol \bold{\\d}. The quantifier to match
- exactly one occurrence, \bold{{1,1}}, can be replaced with the
- expression itself, i.e. \bold{x{1,1}} is the same as \bold{x}. So
- our 0 to 99 matcher could be written as \bold{^\\d{1,2}$}. It can
- also be written \bold{^\\d\\d{0,1}$}, i.e. \e{From the start of
+ given special symbols to represent them. \b{[0-9]} can be
+ replaced with the symbol \b{\\d}. The quantifier to match
+ exactly one occurrence, \b{{1,1}}, can be replaced with the
+ expression itself, i.e. \b{x{1,1}} is the same as \b{x}. So
+ our 0 to 99 matcher could be written as \b{^\\d{1,2}$}. It can
+ also be written \b{^\\d\\d{0,1}$}, i.e. \e{From the start of
the string, match a digit, followed immediately by 0 or 1 digits}.
- In practice, it would be written as \bold{^\\d\\d?$}. The \bold{?}
- is shorthand for the quantifier \bold{{0,1}}, i.e. 0 or 1
- occurrences. \bold{?} makes an expression optional. The regexp
- \bold{^\\d\\d?$} means \e{From the beginning of the string, match
+ In practice, it would be written as \b{^\\d\\d?$}. The \b{?}
+ is shorthand for the quantifier \b{{0,1}}, i.e. 0 or 1
+ occurrences. \b{?} makes an expression optional. The regexp
+ \b{^\\d\\d?$} means \e{From the beginning of the string, match
one digit, followed immediately by 0 or 1 more digit, followed
immediately by end of string}.
@@ -192,45 +192,45 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
'letter' \e or 'correspondence' but does not match words that
contain these words, e.g., 'email', 'mailman', 'mailer', and
'letterbox', start with a regexp that matches 'mail'. Expressed
- fully, the regexp is \bold{m{1,1}a{1,1}i{1,1}l{1,1}}, but because
+ fully, the regexp is \b{m{1,1}a{1,1}i{1,1}l{1,1}}, but because
a character expression is automatically quantified by
- \bold{{1,1}}, we can simplify the regexp to \bold{mail}, i.e., an
+ \b{{1,1}}, we can simplify the regexp to \b{mail}, i.e., an
'm' followed by an 'a' followed by an 'i' followed by an 'l'. Now
- we can use the vertical bar \bold{|}, which means \bold{or}, to
+ we can use the vertical bar \b{|}, which means \b{or}, to
include the other two words, so our regexp for matching any of the
- three words becomes \bold{mail|letter|correspondence}. Match
- 'mail' \bold{or} 'letter' \bold{or} 'correspondence'. While this
+ three words becomes \b{mail|letter|correspondence}. Match
+ 'mail' \b{or} 'letter' \b{or} 'correspondence'. While this
regexp will match one of the three words we want to match, it will
also match words we don't want to match, e.g., 'email'. To
prevent the regexp from matching unwanted words, we must tell it
to begin and end the match at word boundaries. First we enclose
- our regexp in parentheses, \bold{(mail|letter|correspondence)}.
+ our regexp in parentheses, \b{(mail|letter|correspondence)}.
Parentheses group expressions together, and they identify a part
of the regexp that we wish to \l{capturing text}{capture}.
Enclosing the expression in parentheses allows us to use it as a
component in more complex regexps. It also allows us to examine
which of the three words was actually matched. To force the match
to begin and end on word boundaries, we enclose the regexp in
- \bold{\\b} \e{word boundary} assertions:
- \bold{\\b(mail|letter|correspondence)\\b}. Now the regexp means:
+ \b{\\b} \e{word boundary} assertions:
+ \b{\\b(mail|letter|correspondence)\\b}. Now the regexp means:
\e{Match a word boundary, followed by the regexp in parentheses,
- followed by a word boundary}. The \bold{\\b} assertion matches a
+ followed by a word boundary}. The \b{\\b} assertion matches a
\e position in the regexp, not a \e character. A word boundary is
any non-word character, e.g., a space, newline, or the beginning
or ending of a string.
If we want to replace ampersand characters with the HTML entity
- \bold{\&}, the regexp to match is simply \bold{\&}. But this
+ \b{\&}, the regexp to match is simply \b{\&}. But this
regexp will also match ampersands that have already been converted
to HTML entities. We want to replace only ampersands that are not
- already followed by \bold{amp;}. For this, we need the negative
- lookahead assertion, \bold{(?!}__\bold{)}. The regexp can then be
- written as \bold{\&(?!amp;)}, i.e. \e{Match an ampersand that is}
- \bold{not} \e{followed by} \bold{amp;}.
+ already followed by \b{amp;}. For this, we need the negative
+ lookahead assertion, \b{(?!}__\b{)}. The regexp can then be
+ written as \b{\&(?!amp;)}, i.e. \e{Match an ampersand that is}
+ \b{not} \e{followed by} \b{amp;}.
If we want to count all the occurrences of 'Eric' and 'Eirik' in a
- string, two valid solutions are \bold{\\b(Eric|Eirik)\\b} and
- \bold{\\bEi?ri[ck]\\b}. The word boundary assertion '\\b' is
+ string, two valid solutions are \b{\\b(Eric|Eirik)\\b} and
+ \b{\\bEi?ri[ck]\\b}. The word boundary assertion '\\b' is
required to avoid matching words that contain either name,
e.g. 'Ericsson'. Note that the second regexp matches more
spellings than we want: 'Eric', 'Erik', 'Eiric' and 'Eirik'.
@@ -242,52 +242,52 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\section1 Characters and Abbreviations for Sets of Characters
\table
- \header \i Element \i Meaning
- \row \i \bold{c}
- \i A character represents itself unless it has a special
- regexp meaning. e.g. \bold{c} matches the character \e c.
- \row \i \bold{\\c}
- \i A character that follows a backslash matches the character
+ \header \li Element \li Meaning
+ \row \li \b{c}
+ \li A character represents itself unless it has a special
+ regexp meaning. e.g. \b{c} matches the character \e c.
+ \row \li \b{\\c}
+ \li A character that follows a backslash matches the character
itself, except as specified below. e.g., To match a literal
- caret at the beginning of a string, write \bold{\\^}.
- \row \i \bold{\\a}
- \i Matches the ASCII bell (BEL, 0x07).
- \row \i \bold{\\f}
- \i Matches the ASCII form feed (FF, 0x0C).
- \row \i \bold{\\n}
- \i Matches the ASCII line feed (LF, 0x0A, Unix newline).
- \row \i \bold{\\r}
- \i Matches the ASCII carriage return (CR, 0x0D).
- \row \i \bold{\\t}
- \i Matches the ASCII horizontal tab (HT, 0x09).
- \row \i \bold{\\v}
- \i Matches the ASCII vertical tab (VT, 0x0B).
- \row \i \bold{\\x\e{hhhh}}
- \i Matches the Unicode character corresponding to the
+ caret at the beginning of a string, write \b{\\^}.
+ \row \li \b{\\a}
+ \li Matches the ASCII bell (BEL, 0x07).
+ \row \li \b{\\f}
+ \li Matches the ASCII form feed (FF, 0x0C).
+ \row \li \b{\\n}
+ \li Matches the ASCII line feed (LF, 0x0A, Unix newline).
+ \row \li \b{\\r}
+ \li Matches the ASCII carriage return (CR, 0x0D).
+ \row \li \b{\\t}
+ \li Matches the ASCII horizontal tab (HT, 0x09).
+ \row \li \b{\\v}
+ \li Matches the ASCII vertical tab (VT, 0x0B).
+ \row \li \b{\\x\e{hhhh}}
+ \li Matches the Unicode character corresponding to the
hexadecimal number \e{hhhh} (between 0x0000 and 0xFFFF).
- \row \i \bold{\\0\e{ooo}} (i.e., \\zero \e{ooo})
- \i matches the ASCII/Latin1 character for the octal number
+ \row \li \b{\\0\e{ooo}} (i.e., \\zero \e{ooo})
+ \li matches the ASCII/Latin1 character for the octal number
\e{ooo} (between 0 and 0377).
- \row \i \bold{. (dot)}
- \i Matches any character (including newline).
- \row \i \bold{\\d}
- \i Matches a digit (QChar::isDigit()).
- \row \i \bold{\\D}
- \i Matches a non-digit.
- \row \i \bold{\\s}
- \i Matches a whitespace character (QChar::isSpace()).
- \row \i \bold{\\S}
- \i Matches a non-whitespace character.
- \row \i \bold{\\w}
- \i Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').
- \row \i \bold{\\W}
- \i Matches a non-word character.
- \row \i \bold{\\\e{n}}
- \i The \e{n}-th \l backreference, e.g. \\1, \\2, etc.
+ \row \li \b{. (dot)}
+ \li Matches any character (including newline).
+ \row \li \b{\\d}
+ \li Matches a digit (QChar::isDigit()).
+ \row \li \b{\\D}
+ \li Matches a non-digit.
+ \row \li \b{\\s}
+ \li Matches a whitespace character (QChar::isSpace()).
+ \row \li \b{\\S}
+ \li Matches a non-whitespace character.
+ \row \li \b{\\w}
+ \li Matches a word character (QChar::isLetterOrNumber(), QChar::isMark(), or '_').
+ \row \li \b{\\W}
+ \li Matches a non-word character.
+ \row \li \b{\\\e{n}}
+ \li The \e{n}-th \l backreference, e.g. \\1, \\2, etc.
\endtable
- \bold{Note:} The C++ compiler transforms backslashes in strings.
- To include a \bold{\\} in a regexp, enter it twice, i.e. \c{\\}.
+ \b{Note:} The C++ compiler transforms backslashes in strings.
+ To include a \b{\\} in a regexp, enter it twice, i.e. \c{\\}.
To match the backslash character itself, enter it four times, i.e.
\c{\\\\}.
@@ -301,24 +301,24 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
characters do not have special meanings in square brackets.
\table
- \row \i \bold{^}
+ \row \li \b{^}
- \i The caret negates the character set if it occurs as the
+ \li The caret negates the character set if it occurs as the
first character (i.e. immediately after the opening square
- bracket). \bold{[abc]} matches 'a' or 'b' or 'c', but
- \bold{[^abc]} matches anything \e but 'a' or 'b' or 'c'.
+ bracket). \b{[abc]} matches 'a' or 'b' or 'c', but
+ \b{[^abc]} matches anything \e but 'a' or 'b' or 'c'.
- \row \i \bold{-}
+ \row \li \b{-}
- \i The dash indicates a range of characters. \bold{[W-Z]}
+ \li The dash indicates a range of characters. \b{[W-Z]}
matches 'W' or 'X' or 'Y' or 'Z'.
\endtable
Using the predefined character set abbreviations is more portable
than using character ranges across platforms and languages. For
- example, \bold{[0-9]} matches a digit in Western alphabets but
- \bold{\\d} matches a digit in \e any alphabet.
+ example, \b{[0-9]} matches a digit in Western alphabets but
+ \b{\\d} matches a digit in \e any alphabet.
Note: In other regexp documentation, sets of characters are often
called "character classes".
@@ -327,64 +327,64 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\section1 Quantifiers
By default, an expression is automatically quantified by
- \bold{{1,1}}, i.e. it should occur exactly once. In the following
- list, \bold{\e {E}} stands for expression. An expression is a
+ \b{{1,1}}, i.e. it should occur exactly once. In the following
+ list, \b{\e {E}} stands for expression. An expression is a
character, or an abbreviation for a set of characters, or a set of
characters in square brackets, or an expression in parentheses.
\table
- \row \i \bold{\e {E}?}
+ \row \li \b{\e {E}?}
- \i Matches zero or one occurrences of \e E. This quantifier
+ \li Matches zero or one occurrences of \e E. This quantifier
means \e{The previous expression is optional}, because it
- will match whether or not the expression is found. \bold{\e
- {E}?} is the same as \bold{\e {E}{0,1}}. e.g., \bold{dents?}
+ will match whether or not the expression is found. \b{\e
+ {E}?} is the same as \b{\e {E}{0,1}}. e.g., \b{dents?}
matches 'dent' or 'dents'.
- \row \i \bold{\e {E}+}
+ \row \li \b{\e {E}+}
- \i Matches one or more occurrences of \e E. \bold{\e {E}+} is
- the same as \bold{\e {E}{1,}}. e.g., \bold{0+} matches '0',
+ \li Matches one or more occurrences of \e E. \b{\e {E}+} is
+ the same as \b{\e {E}{1,}}. e.g., \b{0+} matches '0',
'00', '000', etc.
- \row \i \bold{\e {E}*}
+ \row \li \b{\e {E}*}
- \i Matches zero or more occurrences of \e E. It is the same
- as \bold{\e {E}{0,}}. The \bold{*} quantifier is often used
- in error where \bold{+} should be used. For example, if
- \bold{\\s*$} is used in an expression to match strings that
+ \li Matches zero or more occurrences of \e E. It is the same
+ as \b{\e {E}{0,}}. The \b{*} quantifier is often used
+ in error where \b{+} should be used. For example, if
+ \b{\\s*$} is used in an expression to match strings that
end in whitespace, it will match every string because
- \bold{\\s*$} means \e{Match zero or more whitespaces followed
+ \b{\\s*$} means \e{Match zero or more whitespaces followed
by end of string}. The correct regexp to match strings that
have at least one trailing whitespace character is
- \bold{\\s+$}.
+ \b{\\s+$}.
- \row \i \bold{\e {E}{n}}
+ \row \li \b{\e {E}{n}}
- \i Matches exactly \e n occurrences of \e E. \bold{\e {E}{n}}
+ \li Matches exactly \e n occurrences of \e E. \b{\e {E}{n}}
is the same as repeating \e E \e n times. For example,
- \bold{x{5}} is the same as \bold{xxxxx}. It is also the same
- as \bold{\e {E}{n,n}}, e.g. \bold{x{5,5}}.
+ \b{x{5}} is the same as \b{xxxxx}. It is also the same
+ as \b{\e {E}{n,n}}, e.g. \b{x{5,5}}.
- \row \i \bold{\e {E}{n,}}
- \i Matches at least \e n occurrences of \e E.
+ \row \li \b{\e {E}{n,}}
+ \li Matches at least \e n occurrences of \e E.
- \row \i \bold{\e {E}{,m}}
- \i Matches at most \e m occurrences of \e E. \bold{\e {E}{,m}}
- is the same as \bold{\e {E}{0,m}}.
+ \row \li \b{\e {E}{,m}}
+ \li Matches at most \e m occurrences of \e E. \b{\e {E}{,m}}
+ is the same as \b{\e {E}{0,m}}.
- \row \i \bold{\e {E}{n,m}}
- \i Matches at least \e n and at most \e m occurrences of \e E.
+ \row \li \b{\e {E}{n,m}}
+ \li Matches at least \e n and at most \e m occurrences of \e E.
\endtable
To apply a quantifier to more than just the preceding character,
use parentheses to group characters together in an expression. For
- example, \bold{tag+} matches a 't' followed by an 'a' followed by
- at least one 'g', whereas \bold{(tag)+} matches at least one
+ example, \b{tag+} matches a 't' followed by an 'a' followed by
+ at least one 'g', whereas \b{(tag)+} matches at least one
occurrence of 'tag'.
Note: Quantifiers are normally "greedy". They always match as much
- text as they can. For example, \bold{0+} matches the first zero it
+ text as they can. For example, \b{0+} matches the first zero it
finds and all the consecutive zeros after the first zero. Applied
to '20005', it matches'2\underline{000}5'. Quantifiers can be made
non-greedy, see setMinimal().
@@ -395,10 +395,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Parentheses allow us to group elements together so that we can
quantify and capture them. For example if we have the expression
- \bold{mail|letter|correspondence} that matches a string we know
+ \b{mail|letter|correspondence} that matches a string we know
that \e one of the words matched but not which one. Using
parentheses allows us to "capture" whatever is matched within
- their bounds, so if we used \bold{(mail|letter|correspondence)}
+ their bounds, so if we used \b{(mail|letter|correspondence)}
and matched this regexp against the string "I sent you some email"
we can use the cap() or capturedTexts() functions to extract the
matched characters, in this case 'mail'.
@@ -406,14 +406,14 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
We can use captured text within the regexp itself. To refer to the
captured text we use \e backreferences which are indexed from 1,
the same as for cap(). For example we could search for duplicate
- words in a string using \bold{\\b(\\w+)\\W+\\1\\b} which means match a
+ words in a string using \b{\\b(\\w+)\\W+\\1\\b} which means match a
word boundary followed by one or more word characters followed by
one or more non-word characters followed by the same text as the
first parenthesized expression followed by a word boundary.
If we want to use parentheses purely for grouping and not for
capturing we can use the non-capturing syntax, e.g.
- \bold{(?:green|blue)}. Non-capturing parentheses begin '(?:' and
+ \b{(?:green|blue)}. Non-capturing parentheses begin '(?:' and
end ')'. In this example we match either 'green' or 'blue' but we
do not capture the match so we only know whether or not we matched
but not which color we actually found. Using non-capturing
@@ -424,9 +424,9 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
\target greedy quantifiers
- For historical reasons, quantifiers (e.g. \bold{*}) that apply to
+ For historical reasons, quantifiers (e.g. \b{*}) that apply to
capturing parentheses are more "greedy" than other quantifiers.
- For example, \bold{a*(a*)} will match "aaa" with cap(1) == "aaa".
+ For example, \b{a*(a*)} will match "aaa" with cap(1) == "aaa".
This behavior is different from what other regexp engines do
(notably, Perl). To obtain a more intuitive capturing behavior,
specify QRegExp::RegExp2 to the QRegExp constructor or call
@@ -444,54 +444,54 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Assertions make some statement about the text at the point where
they occur in the regexp but they do not match any characters. In
- the following list \bold{\e {E}} stands for any expression.
+ the following list \b{\e {E}} stands for any expression.
\table
- \row \i \bold{^}
- \i The caret signifies the beginning of the string. If you
+ \row \li \b{^}
+ \li The caret signifies the beginning of the string. If you
wish to match a literal \c{^} you must escape it by
- writing \c{\\^}. For example, \bold{^#include} will only
+ writing \c{\\^}. For example, \b{^#include} will only
match strings which \e begin with the characters '#include'.
(When the caret is the first character of a character set it
has a special meaning, see \link #sets-of-characters Sets of
Characters \endlink.)
- \row \i \bold{$}
- \i The dollar signifies the end of the string. For example
- \bold{\\d\\s*$} will match strings which end with a digit
+ \row \li \b{$}
+ \li The dollar signifies the end of the string. For example
+ \b{\\d\\s*$} will match strings which end with a digit
optionally followed by whitespace. If you wish to match a
literal \c{$} you must escape it by writing
\c{\\$}.
- \row \i \bold{\\b}
- \i A word boundary. For example the regexp
- \bold{\\bOK\\b} means match immediately after a word
+ \row \li \b{\\b}
+ \li A word boundary. For example the regexp
+ \b{\\bOK\\b} means match immediately after a word
boundary (e.g. start of string or whitespace) the letter 'O'
then the letter 'K' immediately before another word boundary
(e.g. end of string or whitespace). But note that the
assertion does not actually match any whitespace so if we
- write \bold{(\\bOK\\b)} and we have a match it will only
+ write \b{(\\bOK\\b)} and we have a match it will only
contain 'OK' even if the string is "It's \underline{OK} now".
- \row \i \bold{\\B}
- \i A non-word boundary. This assertion is true wherever
- \bold{\\b} is false. For example if we searched for
- \bold{\\Bon\\B} in "Left on" the match would fail (space
+ \row \li \b{\\B}
+ \li A non-word boundary. This assertion is true wherever
+ \b{\\b} is false. For example if we searched for
+ \b{\\Bon\\B} in "Left on" the match would fail (space
and end of string aren't non-word boundaries), but it would
match in "t\underline{on}ne".
- \row \i \bold{(?=\e E)}
- \i Positive lookahead. This assertion is true if the
+ \row \li \b{(?=\e E)}
+ \li Positive lookahead. This assertion is true if the
expression matches at this point in the regexp. For example,
- \bold{const(?=\\s+char)} matches 'const' whenever it is
+ \b{const(?=\\s+char)} matches 'const' whenever it is
followed by 'char', as in 'static \underline{const} char *'.
- (Compare with \bold{const\\s+char}, which matches 'static
+ (Compare with \b{const\\s+char}, which matches 'static
\underline{const char} *'.)
- \row \i \bold{(?!\e E)}
- \i Negative lookahead. This assertion is true if the
+ \row \li \b{(?!\e E)}
+ \li Negative lookahead. This assertion is true if the
expression does not match at this point in the regexp. For
- example, \bold{const(?!\\s+char)} matches 'const' \e except
+ example, \b{const(?!\\s+char)} matches 'const' \e except
when it is followed by 'char'.
\endtable
@@ -505,17 +505,17 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
simpler than full regexps and has only four features:
\table
- \row \i \bold{c}
- \i Any character represents itself apart from those mentioned
- below. Thus \bold{c} matches the character \e c.
- \row \i \bold{?}
- \i Matches any single character. It is the same as
- \bold{.} in full regexps.
- \row \i \bold{*}
- \i Matches zero or more of any characters. It is the
- same as \bold{.*} in full regexps.
- \row \i \bold{[...]}
- \i Sets of characters can be represented in square brackets,
+ \row \li \b{c}
+ \li Any character represents itself apart from those mentioned
+ below. Thus \b{c} matches the character \e c.
+ \row \li \b{?}
+ \li Matches any single character. It is the same as
+ \b{.} in full regexps.
+ \row \li \b{*}
+ \li Matches zero or more of any characters. It is the
+ same as \b{.*} in full regexps.
+ \row \li \b{[...]}
+ \li Sets of characters can be represented in square brackets,
similar to full regexps. Within the character class, like
outside, backslash has no special meaning.
\endtable
@@ -525,7 +525,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
wildcard.
For example if we are in wildcard mode and have strings which
- contain filenames we could identify HTML files with \bold{*.html}.
+ contain filenames we could identify HTML files with \b{*.html}.
This will match zero or more characters followed by a dot followed
by 'h', 't', 'm' and 'l'.
@@ -553,7 +553,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
(but see the \l{greedy quantifiers}{note above}). Non-greedy
matching cannot be applied to individual quantifiers, but can be
applied to all the quantifiers in the pattern. For example, to
- match the Perl regexp \bold{ro+?m} requires:
+ match the Perl regexp \b{ro+?m} requires:
\snippet doc/src/snippets/code/src_corelib_tools_qregexp.cpp 2
@@ -562,7 +562,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Perl's \c{/g} option can be emulated using a \l{#cap_in_a_loop}{loop}.
- In QRegExp \bold{.} matches any character, therefore all QRegExp
+ In QRegExp \b{.} matches any character, therefore all QRegExp
regexps have the equivalent of Perl's \c{/s} option. QRegExp
does not have an equivalent to Perl's \c{/m} option, but this
can be emulated in various ways for example by splitting the input
@@ -598,7 +598,7 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
to Perl's split and join functions.
Note: because C++ transforms \\'s they must be written \e twice in
- code, e.g. \bold{\\b} must be written \bold{\\\\b}.
+ code, e.g. \b{\\b} must be written \b{\\\\b}.
\target code-examples
\section1 Code Examples
@@ -670,10 +670,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
Wildcard matching can be convenient because of its simplicity, but
any wildcard regexp can be defined using full regexps, e.g.
- \bold{.*\\.html$}. Notice that we can't match both \c .html and \c
- .htm files with a wildcard unless we use \bold{*.htm*} which will
+ \b{.*\\.html$}. Notice that we can't match both \c .html and \c
+ .htm files with a wildcard unless we use \b{*.htm*} which will
also match 'test.html.bak'. A full regexp gives us the precision
- we need, \bold{.*\\.html?$}.
+ we need, \b{.*\\.html?$}.
QRegExp can match case insensitively using setCaseSensitivity(),
and can use non-greedy matching, see setMinimal(). By
@@ -3015,6 +3015,8 @@ int QRegExpEngine::getEscape()
if (xmlSchemaExtensions) {
yyCharClass->setNegative(!yyCharClass->negative());
// fall through
+ } else {
+ break;
}
case 'i':
if (xmlSchemaExtensions) {
@@ -3045,12 +3047,16 @@ int QRegExpEngine::getEscape()
yyCharClass->addRange(0xf900, 0xfdcf);
yyCharClass->addRange(0xfdf0, 0xfffd);
yyCharClass->addRange((ushort)0x10000, (ushort)0xeffff);
+ return Tok_CharClass;
+ } else {
+ break;
}
- return Tok_CharClass;
case 'C':
if (xmlSchemaExtensions) {
yyCharClass->setNegative(!yyCharClass->negative());
// fall through
+ } else {
+ break;
}
case 'c':
if (xmlSchemaExtensions) {
@@ -3087,12 +3093,16 @@ int QRegExpEngine::getEscape()
yyCharClass->addRange((ushort)0x10000, (ushort)0xeffff);
yyCharClass->addRange(0x0300, 0x036f);
yyCharClass->addRange(0x203f, 0x2040);
+ return Tok_CharClass;
+ } else {
+ break;
}
- return Tok_CharClass;
case 'P':
if (xmlSchemaExtensions) {
yyCharClass->setNegative(!yyCharClass->negative());
// fall through
+ } else {
+ break;
}
case 'p':
if (xmlSchemaExtensions) {
@@ -3246,8 +3256,10 @@ int QRegExpEngine::getEscape()
} else {
error(RXERR_CATEGORY);
}
+ return Tok_CharClass;
+ } else {
+ break;
}
- return Tok_CharClass;
#endif
#ifndef QT_NO_REGEXP_ESCAPE
case 'x':
@@ -3265,20 +3277,21 @@ int QRegExpEngine::getEscape()
return Tok_Char | val;
#endif
default:
- if (prevCh >= '1' && prevCh <= '9') {
-#ifndef QT_NO_REGEXP_BACKREF
- val = prevCh - '0';
- while (yyCh >= '0' && yyCh <= '9') {
- val = (val * 10) + (yyCh - '0');
- yyCh = getChar();
- }
- return Tok_BackRef | val;
-#else
- error(RXERR_DISABLED);
-#endif
- }
- return Tok_Char | prevCh;
+ break;
}
+ if (prevCh >= '1' && prevCh <= '9') {
+#ifndef QT_NO_REGEXP_BACKREF
+ val = prevCh - '0';
+ while (yyCh >= '0' && yyCh <= '9') {
+ val = (val * 10) + (yyCh - '0');
+ yyCh = getChar();
+ }
+ return Tok_BackRef | val;
+#else
+ error(RXERR_DISABLED);
+#endif
+ }
+ return Tok_Char | prevCh;
}
#ifndef QT_NO_REGEXP_INTERVAL
@@ -3885,7 +3898,7 @@ static void invalidateEngine(QRegExpPrivate *priv)
\enum QRegExp::CaretMode
The CaretMode enum defines the different meanings of the caret
- (\bold{^}) in a regular expression. The possible values are:
+ (\b{^}) in a regular expression. The possible values are:
\value CaretAtZero
The caret corresponds to index 0 in the searched string.
@@ -4052,11 +4065,11 @@ bool QRegExp::isEmpty() const
Returns true if the regular expression is valid; otherwise returns
false. An invalid regular expression never matches.
- The pattern \bold{[a-z} is an example of an invalid pattern, since
+ The pattern \b{[a-z} is an example of an invalid pattern, since
it lacks a closing square bracket.
Note that the validity of a regexp may also depend on the setting
- of the wildcard flag, for example \bold{*.html} is a valid
+ of the wildcard flag, for example \b{*.html} is a valid
wildcard regexp but an invalid full regexp.
\sa errorString()
@@ -4111,7 +4124,7 @@ Qt::CaseSensitivity QRegExp::caseSensitivity() const
/*!
Sets case sensitive matching to \a cs.
- If \a cs is Qt::CaseSensitive, \bold{\\.txt$} matches
+ If \a cs is Qt::CaseSensitive, \b{\\.txt$} matches
\c{readme.txt} but not \c{README.TXT}.
\sa setPatternSyntax(), setPattern(), setMinimal()
@@ -4140,7 +4153,7 @@ QRegExp::PatternSyntax QRegExp::patternSyntax() const
QRegExp::RegExp.
Setting \a syntax to QRegExp::Wildcard enables simple shell-like
- \l{wildcard matching}. For example, \bold{r*.txt} matches the
+ \l{wildcard matching}. For example, \b{r*.txt} matches the
string \c{readme.txt} in wildcard mode, but does not match
\c{readme}.
@@ -4175,13 +4188,13 @@ bool QRegExp::isMinimal() const
For example, suppose we have the input string "We must be
bold, very bold!" and the pattern
- \bold{.*}. With the default greedy (maximal) matching,
+ \b{.*}. With the default greedy (maximal) matching,
the match is "We must be \underline{bold, very
bold}!". But with minimal (non-greedy) matching, the
first match is: "We must be \underline{bold}, very
bold!" and the second match is "We must be bold,
very \underline{bold}!". In practice we might use the pattern
- \bold{[^<]*\} instead, although this will still fail for
+ \b{[^<]*\} instead, although this will still fail for
nested tags.
\sa setCaseSensitivity()
@@ -4202,7 +4215,7 @@ void QRegExp::setMinimal(bool minimal)
in the start of string and end of string anchors, except that it
sets matchedLength() differently.
- For example, if the regular expression is \bold{blue}, then
+ For example, if the regular expression is \b{blue}, then
exactMatch() returns true only for input \c blue. For inputs \c
bluebell, \c blutak and \c lightblue, exactMatch() returns false
and matchedLength() will return 4, 3 and 0 respectively.
@@ -4234,7 +4247,7 @@ bool QRegExp::exactMatch(const QString &str) const
Returns the position of the first match, or -1 if there was no
match.
- The \a caretMode parameter can be used to instruct whether \bold{^}
+ The \a caretMode parameter can be used to instruct whether \b{^}
should match at index 0 or at \a offset.
You might prefer to use QString::indexOf(), QString::contains(),
@@ -4273,7 +4286,7 @@ int QRegExp::indexIn(const QString &str, int offset, CaretMode caretMode) const
Returns the position of the first match, or -1 if there was no
match.
- The \a caretMode parameter can be used to instruct whether \bold{^}
+ The \a caretMode parameter can be used to instruct whether \b{^}
should match at index 0 or at \a offset.
Although const, this function sets matchedLength(),
@@ -4358,7 +4371,7 @@ int QRegExp::captureCount() const
Some regexps can match an indeterminate number of times. For
example if the input string is "Offsets: 12 14 99 231 7" and the
- regexp, \c{rx}, is \bold{(\\d+)+}, we would hope to get a list of
+ regexp, \c{rx}, is \b{(\\d+)+}, we would hope to get a list of
all the numbers matched. However, after calling
\c{rx.indexIn(str)}, capturedTexts() will return the list ("12",
"12"), i.e. the entire match was "12" and the first subexpression
diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp
new file mode 100644
index 00000000000..0fa7d6459e7
--- /dev/null
+++ b/src/corelib/tools/qregularexpression.cpp
@@ -0,0 +1,2134 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Giuseppe D'Angelo .
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qregularexpression.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QRegularExpression
+ \reentrant
+
+ \brief The QRegularExpression class provides pattern matching using regular
+ expressions.
+
+ \since 5.0
+
+ \ingroup tools
+ \ingroup shared
+
+ \keyword regular expression
+
+ Regular expressions, or \e{regexps}, are a very powerful tool to handle
+ strings and texts. This is useful in many contexts, e.g.,
+
+ \table
+ \row \li Validation
+ \li A regexp can test whether a substring meets some criteria,
+ e.g. is an integer or contains no whitespace.
+ \row \li Searching
+ \li A regexp provides more powerful pattern matching than
+ simple substring matching, e.g., match one of the words
+ \e{mail}, \e{letter} or \e{correspondence}, but none of the
+ words \e{email}, \e{mailman}, \e{mailer}, \e{letterbox}, etc.
+ \row \li Search and Replace
+ \li A regexp can replace all occurrences of a substring with a
+ different substring, e.g., replace all occurrences of \e{&}
+ with \e{\&} except where the \e{&} is already followed by
+ an \e{amp;}.
+ \row \li String Splitting
+ \li A regexp can be used to identify where a string should be
+ split apart, e.g. splitting tab-delimited strings.
+ \endtable
+
+ This document is by no means a complete reference to pattern matching using
+ regular expressions, and the following parts will require the reader to
+ have some basic knowledge about Perl-like regular expressions and their
+ pattern syntax.
+
+ Good references about regular expressions include:
+
+ \list
+ \li \e {Mastering Regular Expressions} (Third Edition) by Jeffrey E. F.
+ Friedl, ISBN 0-596-52812-4;
+ \li the \l{http://pcre.org/pcre.txt} {pcrepattern(3)} man page, describing
+ the pattern syntax supported by PCRE (the reference implementation of
+ Perl-compatible regular expressions);
+ \li the \l{http://perldoc.perl.org/perlre.html} {Perl's regular expression
+ documentation} and the \l{http://perldoc.perl.org/perlretut.html} {Perl's
+ regular expression tutorial}.
+ \endlist
+
+ \tableofcontents
+
+ \section1 Introduction
+
+ QRegularExpression implements Perl-compatible regular expressions. It fully
+ supports Unicode. For an overview of the regular expression syntax
+ supported by QRegularExpression, please refer to the aforementioned
+ pcrepattern(3) man page. A regular expression is made up of two things: a
+ \b{pattern string} and a set of \b{pattern options} that change the
+ meaning of the pattern string.
+
+ You can set the pattern string by passing a string to the QRegularExpression
+ constructor:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 0
+
+ This sets the pattern string to \c{a pattern}. You can also use the
+ setPattern() function to set a pattern on an existing QRegularExpression
+ object:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 1
+
+ Note that due to C++ literal strings rules, you must escape all backslashes
+ inside the pattern string with another backslash:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 2
+
+ The pattern() function returns the pattern that it's currently set for a
+ QRegularExpression object:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 3
+
+ \section1 Pattern options
+
+ The meaning of the pattern string can be modified by setting one or more
+ \e{pattern options}. For instance, it is possible to set a pattern to match
+ case insensitively by setting the QRegularExpression::CaseInsensitiveOption.
+
+ You can set the options by passing them to the QRegularExpression
+ constructor, as in:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 4
+
+ Alternatively, you can use the setPatternOptions() function on an existing
+ QRegularExpressionObject:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 5
+
+ It is possible to get the pattern options currently set on a
+ QRegularExpression object by using the patternOptions() function:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 6
+
+ Please refer to the QRegularExpression::PatternOption enum documentation for
+ more information about each pattern option.
+
+ \section1 Match type and match options
+
+ The last two arguments of the match() and the globalMatch() functions set
+ the match type and the match options. The match type is a value of the
+ QRegularExpression::MatchType enum; the "traditional" matching algorithm is
+ chosen by using the NormalMatch match type (the default). It is also
+ possible to enable partial matching of the regular expression against a
+ subject string: see the \l{partial matching} section for more details.
+
+ The match options are a set of one or more QRegularExpression::MatchOption
+ values. They change the way a specific match of a regular expression
+ against a subject string is done. Please refer to the
+ QRegularExpression::MatchOption enum documentation for more details.
+
+ \target normal matching
+ \section1 Normal matching
+
+ In order to perform a match you can simply invoke the match() function
+ passing a string to match against. We refer to this string as the
+ \e{subject string}. The result of the match() function is a
+ QRegularExpressionMatch object that can be used to inspect the results of
+ the match. For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 7
+
+ If a match is successful, the (implicit) capturing group number 0 can be
+ used to retrieve the substring matched by the entire pattern (see also the
+ section about \l{extracting captured substrings}):
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 8
+
+ It's also possible to start a match at an arbitrary offset inside the
+ subject string by passing the offset as an argument of the
+ match() function. In the following example \c{"12 abc"}
+ is not matched because the match is started at offset 1:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 9
+
+ \target extracting captured substrings
+ \section2 Extracting captured substrings
+
+ The QRegularExpressionMatch object contains also information about the
+ substrings captured by the capturing groups in the pattern string. The
+ \l{QRegularExpressionMatch::}{captured()} function will return the string
+ captured by the n-th capturing group:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 10
+
+ Capturing groups in the pattern are numbered starting from 1, and the
+ implicit capturing group 0 is used to capture the substring that matched
+ the entire pattern.
+
+ It's also possible to retrieve the starting and the ending offsets (inside
+ the subject string) of each captured substring, by using the
+ \l{QRegularExpressionMatch::}{capturedStart()} and the
+ \l{QRegularExpressionMatch::}{capturedEnd()} functions:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 11
+
+ All of these functions have an overload taking a QString as a parameter
+ in order to extract \e{named} captured substrings. For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 12
+
+ \target global matching
+ \section1 Global matching
+
+ \e{Global matching} is useful to find all the occurrences of a given
+ regular expression inside a subject string. Suppose that we want to extract
+ all the words from a given string, where a word is a substring matching
+ the pattern \c{\w+}.
+
+ QRegularExpression::globalMatch returns a QRegularExpressionMatchIterator,
+ which is a Java-like forward iterator that can be used to iterate over the
+ results. For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 13
+
+ Since it's a Java-like iterator, the QRegularExpressionMatchIterator will
+ point immediately before the first result. Every result is returned as a
+ QRegularExpressionMatch object. The
+ \l{QRegularExpressionMatchIterator::}{hasNext()} function will return true
+ if there's at least one more result, and
+ \l{QRegularExpressionMatchIterator::}{next()} will return the next result
+ and advance the iterator. Continuing from the previous example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 14
+
+ You can also use \l{QRegularExpressionMatchIterator::}{peekNext()} to get
+ the next result without advancing the iterator.
+
+ It is possible to pass a starting offset and one or more match options to
+ the globalMatch() function, exactly like normal matching with match().
+
+ \target partial matching
+ \section1 Partial matching
+
+ A \e{partial match} is obtained when the end of the subject string is
+ reached, but more characters are needed to successfully complete the match.
+ Note that a partial match is usually much more inefficient than a normal
+ match because many optimizations of the matching algorithm cannot be
+ employed.
+
+ A partial match must be explicitly requested by specifying a match type of
+ PartialPreferCompleteMatch or PartialPreferFirstMatch when calling
+ QRegularExpression::match or QRegularExpression::globalMatch. If a partial
+ match is found, then calling the \l{QRegularExpressionMatch::}{hasMatch()}
+ function on the QRegularExpressionMatch object returned by match() will
+ return \c{false}, but \l{QRegularExpressionMatch::}{hasPartialMatch()} will return
+ \c{true}.
+
+ When a partial match is found, no captured substrings are returned, and the
+ (implicit) capturing group 0 corresponding to the whole match captures the
+ partially matched substring of the subject string.
+
+ Note that asking for a partial match can still lead to a complete match, if
+ one is found; in this case, \l{QRegularExpressionMatch::}{hasMatch()} will
+ return \c{true} and \l{QRegularExpressionMatch::}{hasPartialMatch()}
+ \c{false}. It never happens that a QRegularExpressionMatch reports both a
+ partial and a complete match.
+
+ Partial matching is mainly useful in two scenarios: validating user input
+ in real time and incremental/multi-segment matching.
+
+ \target
+ \section2 Validating user input
+
+ Suppose that we would like the user to input a date in a specific
+ format, for instance "MMM dd, yyyy". We can check the input validity with
+ a pattern like:
+
+ \c{^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d?, \d\d\d\d$}
+
+ (This pattern doesn't catch invalid days, but let's keep it for the
+ example's purposes).
+
+ We would like to validate the input with this regular expression \e{while}
+ the user is typing it, so that we can report an error in the input as soon
+ as it is committed (for instance, the user typed the wrong key). In order
+ to do so we must distinguish three cases:
+
+ \list
+ \li the input cannot possibly match the regular expression;
+ \li the input does match the regular expression;
+ \li the input does not match the regular expression right now,
+ but it will if more charaters will be added to it.
+ \endlist
+
+ Note that these three cases represent exactly the possible states of a
+ QValidator (see the QValidator::State enum).
+
+ In particular, in the last case we want the regular expression engine to
+ report a partial match: we are successfully matching the pattern against
+ the subject string but the matching cannot continue because the end of the
+ subject is encountered. Notice, however, that the matching algorithm should
+ continue and try all possibilities, and in case a complete (non-partial)
+ match is found, then this one should be reported, and the input string
+ accepted as fully valid.
+
+ This behaviour is implemented by the PartialPreferCompleteMatch match type.
+ For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 15
+
+ If matching the same regular expression against the subject string leads to
+ a complete match, it is reported as usual:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 16
+
+ Another example with a different pattern, showing the behaviour of
+ preferring a complete match over a partial one:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 17
+
+ In this case, the subpattern \c{abc\\w+X} partially matches the subject
+ string; however, the subpattern \c{def} matches the subject string
+ completely, and therefore a complete match is reported.
+
+ In case multiple partial matches are found when matching (but no complete
+ match), then the QRegularExpressionMatch will report the first one that it
+ is found. For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 18
+
+ \section2 Incremental/multi-segment matching
+
+ Incremental matching is another use case of partial matching. Suppose that
+ we want to find the occurrences of a regular expression inside a large text
+ (that is, substrings matching the regular expression). In order to do so we
+ would like to "feed" the large text to the regular expression engines in
+ smaller chunks. The obvious problem is what happens if the substring that
+ matches the regular expression spans across two or more chunks.
+
+ In this case, the regular expression engine should report a partial match,
+ so that we can match again adding new data and (eventually) get a complete
+ match. This implies that the regular expression engine may assume that
+ there are other characters \e{beyond the end} of the subject string. This
+ is not to be taken literally -- the engine will never try to access
+ any character after the last one in the subject.
+
+ QRegularExpression implements this behaviour when using the
+ PartialPreferFirstMatch match type. This match type reports a partial match
+ as soon as it is found, and other match alternatives are not tried
+ (even if they could lead to a complete match). For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 19
+
+ This happens because when matching the first branch of the alternation
+ operator a partial match is found, and therefore matching stops, without
+ trying the second branch. Another example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 20
+
+ This shows what could seem a counterintuitve behaviour of quantifiers:
+ since \c{?} is greedy, then the engine tries first to continue the match
+ after having matched \c{"abc"}; but then the matching reaches the end of the
+ subject string, and therefore a partial match is reported. This is
+ even more surprising in the following example:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 21
+
+ It's easy to understand this behaviour if we remember that the engine
+ expects the subject string to be only a substring of the whole text we're
+ looking for a match into (that is, how we said before, that the engine
+ assumes that there are other characters beyond the end of the subject
+ string).
+
+ Since the \c{*} quantifier is greedy, then reporting a complete match could
+ be an error, because after the current subject \c{"abc"} there may be other
+ occurrences of \c{"abc"}. For instance, the complete text could have been
+ "abcabcX", and therefore the \e{right} match to report (in the complete
+ text) would have been \c{"abcabc"}; by matching only against the leading
+ \c{"abc"} we instead get a partial match.
+
+ \section1 Error handling
+
+ It is possible for a QRegularExpression object to be invalid because of
+ syntax errors in the pattern string. The isValid() function will return
+ true if the regular expression is valid, or false otherwise:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 22
+
+ You can get more information about the specific error by calling the
+ errorString() function; moreover, the patternErrorOffset() function
+ will return the offset inside the pattern string
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 23
+
+ If a match is attempted with an invalid QRegularExpression, then the
+ returned QRegularExpressionMatch object will be invalid as well (that is,
+ its \l{QRegularExpressionMatch::}{isValid()} function will return false).
+ The same applies for attempting a global match.
+
+ \section1 Unsupported Perl-compatible regular expressions features
+
+ QRegularExpression does not support all the features available in
+ Perl-compatible regular expressions. The most notable one is the fact that
+ duplicated names for capturing groups are not supported, and using them can
+ lead to undefined behaviour.
+
+ This may change in a future version of Qt.
+
+ \section1 Notes for QRegExp users
+
+ The QRegularExpression class introduced in Qt 5 is a big improvement upon
+ QRegExp, in terms of APIs offered, supported pattern syntax and speed of
+ execution. The biggest difference is that QRegularExpression simply holds a
+ regular expression, and it's \e{not} modified when a match is requested.
+ Instead, a QRegularExpressionMatch object is returned, in order to check
+ the result of a match and extract the captured substring. The same applies
+ with global matching and QRegularExpressionMatchIterator.
+
+ Other differences are outlined below.
+
+ \section2 Exact matching
+
+ QRegExp::exactMatch in Qt 4 served for two purposes: it exactly matched
+ a regular expression against a subject string, and it implemented partial
+ matching. In fact, if an exact match was not found, one could still find
+ out how much of the subject string was matched by the regular expression
+ by calling QRegExp::matchedLength(). If the returned length was equal
+ to the subject string's length, then one could desume that a partial match
+ was found.
+
+ QRegularExpression supports partial matching explicitly by means of the
+ appropriate MatchType. If instead you simply want to be sure that the
+ subject string matches the regular expression exactly, you can wrap the
+ pattern between a couple of anchoring expressions. Simply
+ putting the pattern between the \c{^} and the \c{$} anchors is enough
+ in most cases:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 24
+
+ However, remember that the \c{$} anchor not only matches at the end of the
+ string, but also at a newline character right before the end of the string;
+ that is, the previous pattern matches against the string "this pattern must
+ match exactly\n". Also, the behaviour of both the \c{^} and the \c{$}
+ anchors changes if the MultiLineOption is set either explicitely (as a
+ pattern option) or implicitly (as a directive inside the pattern string).
+
+ Therefore, in the most general case, you should wrap the pattern between
+ the \c{\A} and the \c{\z} anchors:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 25
+
+ Note the usage of the non-capturing group in order to preserve the meaning
+ of the branch operator inside the pattern.
+
+ \section2 Global matching
+
+ Due to limitations of the QRegExp API it was impossible to implement global
+ matching correctly (that is, like Perl does). In particular, patterns that
+ can match 0 characters (like \c{"a*"}) are problematic.
+
+ QRegularExpression::globalMatch implements Perl global match correctly, and
+ the returned iterator can be used to examine each result.
+
+ \section2 Wildcard matching
+
+ There is no equivalent of wildcard matching in QRegularExpression.
+ Nevertheless, rewriting a regular expression in wildcard syntax to a
+ Perl-compatible regular expression is a very easy task, given the fact
+ that wildcard syntax supported by QRegExp is very simple.
+
+ \section2 Other pattern syntaxes
+
+ QRegularExpression supports only Perl-compatible regular expressions.
+
+ \section2 Minimal matching
+
+ QRegExp::setMinimal implemented minimal matching by simply reversing the
+ greediness of the quantifiers (QRegExp did not support lazy quantifiers,
+ like \c{*?}, \c{+?}, etc.). QRegularExpression instead does support greedy,
+ lazy and possessive quantifiers. The InvertedGreedinessOption
+ pattern option can be useful to emulate the effects of QRegExp::setMinimal:
+ if enabled, it inverts the greediness of quantifiers (greedy ones become
+ lazy and vice versa).
+
+ \section2 Caret modes
+
+ The AnchoredMatchOption match option can be used to emulate the
+ QRegExp::CaretAtOffset behaviour. There is no equivalent for the other
+ QRegExp::CaretMode modes.
+
+ \section1 Debugging code that uses QRegularExpression
+
+ QRegularExpression internally uses a just in time compiler (JIT) to
+ optimize the execution of the matching algorithm. The JIT makes extensive
+ usage of self-modifying code, which can lead debugging tools such as
+ Valgrind to crash. You must enable all checks for self-modifying code if
+ you want to debug programs using QRegularExpression (f.i., see Valgrind's
+ \c{--smc-check} command line option). The downside of enabling such checks
+ is that your program will run considerably slower.
+
+ To avoid that, the JIT is disabled by default if you compile Qt in debug
+ mode. It is possible to override the default and enable or disable the JIT
+ usage (both in debug or release mode) by setting the
+ \c{QT_ENABLE_REGEXP_JIT} environment variable to a non-zero or zero value
+ respectively.
+
+ \sa QRegularExpressionMatch, QRegularExpressionMatchIterator
+*/
+
+/*!
+ \class QRegularExpressionMatch
+ \reentrant
+
+ \brief The QRegularExpressionMatch class provides the results of a matching
+ a QRegularExpression against a string.
+
+ \since 5.0
+
+ \ingroup tools
+ \ingroup shared
+
+ \keyword regular expression match
+
+ A QRegularExpressionMatch object can be obtained by calling the
+ QRegularExpression::match() function, or as a single result of a global
+ match from a QRegularExpressionMatchIterator.
+
+ The success or the failure of a match attempt can be inspected by calling
+ the hasMatch() function. QRegularExpressionMatch also reports a successful
+ partial match through the hasPartialMatch() function.
+
+ In addition, QRegularExpressionMatch returns the substrings captured by the
+ capturing groups in the pattern string. The implicit capturing group with
+ index 0 captures the result of the whole match. The captured() function
+ returns each substring captured, either by the capturing group's index or
+ by its name:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 29
+
+ For each captured substring it is possible to query its starting and ending
+ offsets in the subject string by calling the capturedStart() and the
+ capturedEnd() function, respectively. The length of each captured
+ substring is available using the capturedLength() function.
+
+ The convenience function capturedTexts() will return \e{all} the captured
+ substrings at once (including the substring matched by the entire pattern)
+ in the order they have been captured by captring groups; that is,
+ \c{captured(i) == capturedTexts().at(i)}.
+
+ You can retrieve the QRegularExpression object the subject string was
+ matched against by calling the regularExpression() function; the
+ match type and the match options are available as well by calling
+ the matchType() and the matchOptions() respectively.
+
+ Please refer to the QRegularExpression documentation for more information
+ about the Qt regular expression classes.
+
+ \sa QRegularExpression
+*/
+
+/*!
+ \class QRegularExpressionMatchIterator
+ \reentrant
+
+ \brief The QRegularExpressionMatchIterator class provides an iterator on
+ the results of a global match of a QRegularExpression object against a string.
+
+ \since 5.0
+
+ \ingroup tools
+ \ingroup shared
+
+ \keyword regular expression iterator
+
+ A QRegularExpressionMatchIterator object is a forward only Java-like
+ iterator; it can be obtained by calling the
+ QRegularExpression::globalMatch() function. A new
+ QRegularExpressionMatchIterator will be positioned before the first result.
+ You can then call the hasNext() function to check if there are more
+ results available; if so, the next() function will return the next
+ result and advance the iterator.
+
+ Each result is a QRegularExpressionMatch object holding all the information
+ for that result (including captured substrings).
+
+ For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 30
+
+ Moreover, QRegularExpressionMatchIterator offers a peekNext() function
+ to get the next result \e{without} advancing the iterator.
+
+ You can retrieve the QRegularExpression object the subject string was
+ matched against by calling the regularExpression() function; the
+ match type and the match options are available as well by calling
+ the matchType() and the matchOptions() respectively.
+
+ Please refer to the QRegularExpression documentation for more information
+ about the Qt regular expression classes.
+
+ \sa QRegularExpression, QRegularExpressionMatch
+*/
+
+
+/*!
+ \enum QRegularExpression::PatternOption
+
+ The PatternOption enum defines modifiers to the way the pattern string
+ should be interpreted, and therefore the way the pattern matches against a
+ subject string.
+
+ \value NoPatternOption
+ No pattern options are set.
+
+ \value CaseInsensitiveOption
+ The pattern should match against the subject string in a case
+ insensitive way. This option corresponds to the /i modifier in Perl
+ regular expressions.
+
+ \value DotMatchesEverythingOption
+ The dot metacharacter (\c{.}) in the pattern string is allowed to match
+ any character in the subject string, including newlines (normally, the
+ dot does not match newlines). This option corresponds to the \c{/s}
+ modifier in Perl regular expressions.
+
+ \value MultilineOption
+ The caret (\c{^}) and the dollar (\c{$}) metacharacters in the pattern
+ string are allowed to match, respectively, immediately after and
+ immediately before any newline in the subject string, as well as at the
+ very beginning and at the very end of the subject string. This option
+ corresponds to the \c{/m} modifier in Perl regular expressions.
+
+ \value ExtendedPatternSyntaxOption
+ Any whitespace in the pattern string which is not escaped and outside a
+ character class is ignored. Moreover, an unescaped sharp (\b{#})
+ outside a character class causes all the following characters, until
+ the first newline (included), to be ignored. This can be used to
+ increase the readability of a pattern string as well as put comments
+ inside regular expressions; this is particulary useful if the pattern
+ string is loaded from a file or written by the user, because in C++
+ code it is always possible to use the rules for string literals to put
+ comments outside the pattern string. This option corresponds to the \c{/x}
+ modifier in Perl regular expressions.
+
+ \value InvertedGreedinessOption
+ The greediness of the quantifiers is inverted: \c{*}, \c{+}, \c{?},
+ \c{{m,n}}, etc. become lazy, while their lazy versions (\c{*?},
+ \c{+?}, \c{??}, \c{{m,n}?}, etc.) become greedy. There is no equivalent
+ for this option in Perl regular expressions.
+
+ \value DontCaptureOption
+ The non-named capturing groups do not capture substrings; named
+ capturing groups still work as intended, as well as the implicit
+ capturing group number 0 corresponding to the entire match. There is no
+ equivalent for this option in Perl regular expressions.
+
+ \value UseUnicodePropertiesOption
+ The meaning of the \c{\w}, \c{\d}, etc., character types, as well as
+ the meaning of their counterparts (\c{\W}, \c{\D}, etc.), is changed
+ from matching ASCII charaters only to matching any character with the
+ corresponding Unicode property. For instance, \c{\d} is changed to
+ match any character with the Unicode Nd (decimal digit) property;
+ \c{\w} to match any character with either the Unicode L (letter) or N
+ (digit) property, plus underscore, and so on. This option corresponds
+ to the \c{/u} modifier in Perl regular expressions.
+*/
+
+/*!
+ \enum QRegularExpression::MatchType
+
+ The MatchType enum defines the type of the match that should be attempted
+ against the subject string.
+
+ \value NormalMatch
+ A normal match is done.
+
+ \value PartialPreferCompleteMatch
+ The pattern string is matched partially against the subject string. If
+ a partial match is found, then it is recorded, and other matching
+ alternatives are tried as usual. If a complete match is then found,
+ then it's preferred to the partial match; in this case only the
+ complete match is reported. If instead no complete match is found (but
+ only the partial one), then the partial one is reported.
+
+ \value PartialPreferFirstMatch
+ The pattern string is matched partially against the subject string. If
+ a partial match is found, then matching stops and the partial match is
+ reported. In this case, other matching alternatives (potentially
+ leading to a complete match) are not tried. Moreover, this match type
+ assumes that the subject string only a substring of a larger text, and
+ that (in this text) there are other characters beyond the end of the
+ subject string. This can lead to surprising results; see the discussion
+ in the \l{partial matching} section for more details.
+*/
+
+/*!
+ \enum QRegularExpression::MatchOption
+
+ \value NoMatchOption
+ No match options are set.
+
+ \value AnchoredMatchOption
+ The match is constrained to start exactly at the offset passed to
+ match() in order to be successful, even if the pattern string does not
+ contain any metacharacter that anchors the match at that point.
+*/
+
+// after how many usages we optimize the regexp
+#ifdef QT_BUILD_INTERNAL
+Q_AUTOTEST_EXPORT unsigned int qt_qregularexpression_optimize_after_use_count = 10;
+#else
+static const unsigned int qt_qregularexpression_optimize_after_use_count = 10;
+#endif // QT_BUILD_INTERNAL
+
+/*!
+ \internal
+*/
+static int convertToPcreOptions(QRegularExpression::PatternOptions patternOptions)
+{
+ int options = 0;
+
+ if (patternOptions & QRegularExpression::CaseInsensitiveOption)
+ options |= PCRE_CASELESS;
+ if (patternOptions & QRegularExpression::DotMatchesEverythingOption)
+ options |= PCRE_DOTALL;
+ if (patternOptions & QRegularExpression::MultilineOption)
+ options |= PCRE_MULTILINE;
+ if (patternOptions & QRegularExpression::ExtendedPatternSyntaxOption)
+ options |= PCRE_EXTENDED;
+ if (patternOptions & QRegularExpression::InvertedGreedinessOption)
+ options |= PCRE_UNGREEDY;
+ if (patternOptions & QRegularExpression::DontCaptureOption)
+ options |= PCRE_NO_AUTO_CAPTURE;
+ if (patternOptions & QRegularExpression::UseUnicodePropertiesOption)
+ options |= PCRE_UCP;
+
+ return options;
+}
+
+/*!
+ \internal
+*/
+static int convertToPcreOptions(QRegularExpression::MatchOptions matchOptions)
+{
+ int options = 0;
+
+ if (matchOptions & QRegularExpression::AnchoredMatchOption)
+ options |= PCRE_ANCHORED;
+
+ return options;
+}
+
+struct QRegularExpressionPrivate : QSharedData
+{
+ QRegularExpressionPrivate();
+ ~QRegularExpressionPrivate();
+ QRegularExpressionPrivate(const QRegularExpressionPrivate &other);
+
+ void cleanCompiledPattern();
+ void compilePattern();
+ void getPatternInfo();
+ pcre16_extra *optimizePattern();
+
+ QRegularExpressionMatchPrivate *doMatch(const QString &subject,
+ int offset,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ const QRegularExpressionMatchPrivate *previous = 0) const;
+
+ int captureIndexForName(const QString &name) const;
+
+ QString pattern;
+ QRegularExpression::PatternOptions patternOptions;
+
+ // *All* of the following members are set managed while holding this mutex,
+ // except for isDirty which is set to true by QRegularExpression setters
+ // (right after a detach happened).
+ // On the other hand, after the compilation and studying,
+ // it's safe to *use* (i.e. read) them from multiple threads at the same time.
+ // Therefore, doMatch doesn't need to lock this mutex.
+ QMutex mutex;
+
+ // The PCRE pointers are reference-counted by the QRegularExpressionPrivate
+ // objects themselves; when the private is copied (i.e. a detach happened)
+ // they are set to 0
+ pcre16 *compiledPattern;
+ pcre16_extra *studyData;
+ const char *errorString;
+ int errorOffset;
+ int capturingCount;
+ unsigned int usedCount;
+ bool usingCrLfNewlines;
+ bool isDirty;
+};
+
+struct QRegularExpressionMatchPrivate : QSharedData
+{
+ QRegularExpressionMatchPrivate(const QRegularExpression &re,
+ const QString &subject,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ int capturingCount);
+
+ QRegularExpressionMatch nextMatch() const;
+
+ const QRegularExpression regularExpression;
+ const QString subject;
+ // the capturedOffsets vector contains pairs of (start, end) positions
+ // for each captured substring
+ QVector capturedOffsets;
+
+ const QRegularExpression::MatchType matchType;
+ const QRegularExpression::MatchOptions matchOptions;
+
+ int capturedCount;
+
+ bool hasMatch;
+ bool hasPartialMatch;
+ bool isValid;
+};
+
+struct QRegularExpressionMatchIteratorPrivate : QSharedData
+{
+ QRegularExpressionMatchIteratorPrivate(const QRegularExpression &re,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ const QRegularExpressionMatch &next);
+
+ bool hasNext() const;
+ QRegularExpressionMatch next;
+ const QRegularExpression regularExpression;
+ const QRegularExpression::MatchType matchType;
+ const QRegularExpression::MatchOptions matchOptions;
+};
+
+/*!
+ \internal
+*/
+QRegularExpression::QRegularExpression(QRegularExpressionPrivate &dd)
+ : d(&dd)
+{
+}
+
+/*!
+ \internal
+*/
+QRegularExpressionPrivate::QRegularExpressionPrivate()
+ : pattern(), patternOptions(0),
+ mutex(),
+ compiledPattern(0), studyData(0),
+ errorString(0), errorOffset(-1),
+ capturingCount(0),
+ usedCount(0),
+ usingCrLfNewlines(false),
+ isDirty(true)
+{
+}
+
+/*!
+ \internal
+*/
+QRegularExpressionPrivate::~QRegularExpressionPrivate()
+{
+ cleanCompiledPattern();
+}
+
+/*!
+ \internal
+
+ Copies the private, which means copying only the pattern and the pattern
+ options. The compiledPattern and the studyData pointers are NOT copied (we
+ do not own them any more), and in general all the members set when
+ compiling a pattern are set to default values. isDirty is set back to true
+ so that the pattern has to be recompiled again.
+*/
+QRegularExpressionPrivate::QRegularExpressionPrivate(const QRegularExpressionPrivate &other)
+ : QSharedData(other),
+ pattern(other.pattern), patternOptions(other.patternOptions),
+ mutex(),
+ compiledPattern(0), studyData(0),
+ errorString(0),
+ errorOffset(-1), capturingCount(0),
+ usedCount(0),
+ usingCrLfNewlines(false), isDirty(true)
+{
+}
+
+/*!
+ \internal
+*/
+void QRegularExpressionPrivate::cleanCompiledPattern()
+{
+ pcre16_free(compiledPattern);
+ pcre16_free_study(studyData);
+ usedCount = 0;
+ compiledPattern = 0;
+ studyData = 0;
+ usingCrLfNewlines = false;
+ errorOffset = -1;
+ capturingCount = 0;
+}
+
+/*!
+ \internal
+*/
+void QRegularExpressionPrivate::compilePattern()
+{
+ QMutexLocker lock(&mutex);
+
+ if (!isDirty)
+ return;
+
+ isDirty = false;
+ cleanCompiledPattern();
+
+ int options = convertToPcreOptions(patternOptions);
+ options |= PCRE_UTF16;
+
+ int errorCode;
+ compiledPattern = pcre16_compile2(pattern.utf16(), options,
+ &errorCode, &errorString, &errorOffset, 0);
+
+ if (!compiledPattern)
+ return;
+
+ Q_ASSERT(errorCode == 0);
+ Q_ASSERT(studyData == 0); // studying (=>optimizing) is always done later
+ errorOffset = -1;
+
+ getPatternInfo();
+}
+
+/*!
+ \internal
+*/
+void QRegularExpressionPrivate::getPatternInfo()
+{
+ Q_ASSERT(compiledPattern);
+
+ pcre16_fullinfo(compiledPattern, 0, PCRE_INFO_CAPTURECOUNT, &capturingCount);
+
+ // detect the settings for the newline
+ int patternNewlineSetting;
+ pcre16_fullinfo(compiledPattern, studyData, PCRE_INFO_OPTIONS, &patternNewlineSetting);
+ patternNewlineSetting &= PCRE_NEWLINE_CR | PCRE_NEWLINE_LF | PCRE_NEWLINE_CRLF
+ | PCRE_NEWLINE_ANY | PCRE_NEWLINE_ANYCRLF;
+ if (patternNewlineSetting == 0) {
+ // no option was specified in the regexp, grab PCRE build defaults
+ int pcreNewlineSetting;
+ pcre16_config(PCRE_CONFIG_NEWLINE, &pcreNewlineSetting);
+ switch (pcreNewlineSetting) {
+ case 13:
+ patternNewlineSetting = PCRE_NEWLINE_CR; break;
+ case 10:
+ patternNewlineSetting = PCRE_NEWLINE_LF; break;
+ case 3338: // (13<<8 | 10)
+ patternNewlineSetting = PCRE_NEWLINE_CRLF; break;
+ case -2:
+ patternNewlineSetting = PCRE_NEWLINE_ANYCRLF; break;
+ case -1:
+ patternNewlineSetting = PCRE_NEWLINE_ANY; break;
+ default:
+ qWarning("QRegularExpressionPrivate::compilePattern(): "
+ "PCRE_CONFIG_NEWLINE returned an unknown newline");
+ break;
+ }
+ }
+
+ usingCrLfNewlines = (patternNewlineSetting == PCRE_NEWLINE_CRLF) ||
+ (patternNewlineSetting == PCRE_NEWLINE_ANY) ||
+ (patternNewlineSetting == PCRE_NEWLINE_ANYCRLF);
+}
+
+/*!
+ \internal
+*/
+static bool isJitEnabled()
+{
+ QByteArray jitEnvironment = qgetenv("QT_ENABLE_REGEXP_JIT");
+ if (!jitEnvironment.isEmpty()) {
+ bool ok;
+ int enableJit = jitEnvironment.toInt(&ok);
+ return ok ? (enableJit != 0) : true;
+ }
+
+#ifdef QT_DEBUG
+ return false;
+#else
+ return true;
+#endif
+}
+
+/*!
+ \internal
+
+ The purpose of the function is to call pcre16_study (which allows some
+ optimizations to be performed, including JIT-compiling the pattern), and
+ setting the studyData member variable to the result of the study. It gets
+ called by doMatch() every time a match is performed. As of now, the
+ optimizations on the pattern are performed after a certain number of usages
+ (i.e. the qt_qregularexpression_optimize_after_use_count constant).
+
+ Notice that although the method is protected by a mutex, one thread may
+ invoke this function and return immediately (i.e. not study the pattern,
+ leaving studyData to NULL); but before calling pcre16_exec to perform the
+ match, another thread performs the studying and sets studyData to something
+ else. Although the assignment to studyData is itself atomic, the release of
+ the memory pointed by studyData isn't. Therefore, the current studyData
+ value is returned and used by doMatch.
+*/
+pcre16_extra *QRegularExpressionPrivate::optimizePattern()
+{
+ Q_ASSERT(compiledPattern);
+
+ QMutexLocker lock(&mutex);
+
+ if (studyData || (++usedCount != qt_qregularexpression_optimize_after_use_count))
+ return studyData;
+
+ static const bool enableJit = isJitEnabled();
+
+ int studyOptions = 0;
+ if (enableJit)
+ studyOptions |= PCRE_STUDY_JIT_COMPILE;
+
+ const char *err;
+ studyData = pcre16_study(compiledPattern, studyOptions, &err);
+
+ if (!studyData && err)
+ qWarning("QRegularExpressionPrivate::optimizePattern(): pcre_study failed: %s", err);
+
+ return studyData;
+}
+
+/*!
+ \internal
+
+ Returns the capturing group number for the given name. Duplicated names for
+ capturing groups are not supported.
+*/
+int QRegularExpressionPrivate::captureIndexForName(const QString &name) const
+{
+ Q_ASSERT(!name.isEmpty());
+
+ int index = pcre16_get_stringnumber(compiledPattern, name.utf16());
+ if (index >= 0)
+ return index;
+
+ return -1;
+}
+
+/*!
+ \internal
+
+ Performs a match of type \a matchType on the given \a subject string with
+ options \a matchOptions and returns the QRegularExpressionMatchPrivate of
+ the result. It also advances a match if a previous result is given as \a
+ previous.
+
+ Advancing a match is a tricky algorithm. If the previous match matched a
+ non-empty string, we just do an ordinary match at the offset position.
+
+ If the previous match matched an empty string, then an anchored, non-empty
+ match is attempted at the offset position. If that succeeds, then we got
+ the next match and we can return it. Otherwise, we advance by 1 position
+ (which can be one or two code units in UTF-16!) and reattempt a "normal"
+ match. We also have the problem of detecting the current newline format: if
+ the new advanced offset is pointing to the beginning of a CRLF sequence, we
+ must advance over it.
+*/
+QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString &subject,
+ int offset,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ const QRegularExpressionMatchPrivate *previous) const
+{
+ if (offset < 0)
+ offset += subject.length();
+
+ QRegularExpression re(*const_cast(this));
+
+ if (offset < 0 || offset > subject.length())
+ return new QRegularExpressionMatchPrivate(re, subject, matchType, matchOptions, 0);
+
+ if (!compiledPattern) {
+ qWarning("QRegularExpressionPrivate::doMatch(): called on an invalid QRegularExpression object");
+ return new QRegularExpressionMatchPrivate(re, subject, matchType, matchOptions, 0);
+ }
+
+ QRegularExpressionMatchPrivate *priv = new QRegularExpressionMatchPrivate(re, subject,
+ matchType, matchOptions,
+ capturingCount);
+
+ // this is mutex protected
+ const pcre16_extra *currentStudyData = const_cast(this)->optimizePattern();
+
+ int pcreOptions = convertToPcreOptions(matchOptions);
+
+ if (matchType == QRegularExpression::PartialPreferCompleteMatch)
+ pcreOptions |= PCRE_PARTIAL_SOFT;
+ else if (matchType == QRegularExpression::PartialPreferFirstMatch)
+ pcreOptions |= PCRE_PARTIAL_HARD;
+
+ bool previousMatchWasEmpty = false;
+ if (previous && previous->hasMatch &&
+ (previous->capturedOffsets.at(0) == previous->capturedOffsets.at(1))) {
+ previousMatchWasEmpty = true;
+ }
+
+ int * const captureOffsets = priv->capturedOffsets.data();
+ const int captureOffsetsCount = priv->capturedOffsets.size();
+
+ const unsigned short * const subjectUtf16 = subject.utf16();
+ const int subjectLength = subject.length();
+
+ int result;
+
+ if (!previousMatchWasEmpty) {
+ result = pcre16_exec(compiledPattern, currentStudyData,
+ subjectUtf16, subjectLength,
+ offset, pcreOptions,
+ captureOffsets, captureOffsetsCount);
+ } else {
+ result = pcre16_exec(compiledPattern, currentStudyData,
+ subjectUtf16, subjectLength,
+ offset, pcreOptions | PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED,
+ captureOffsets, captureOffsetsCount);
+
+ if (result == PCRE_ERROR_NOMATCH) {
+ ++offset;
+
+ if (usingCrLfNewlines
+ && offset < subjectLength
+ && subjectUtf16[offset - 1] == QLatin1Char('\r')
+ && subjectUtf16[offset] == QLatin1Char('\n')) {
+ ++offset;
+ } else if (offset < subjectLength
+ && QChar::isLowSurrogate(subjectUtf16[offset])) {
+ ++offset;
+ }
+
+ result = pcre16_exec(compiledPattern, currentStudyData,
+ subjectUtf16, subjectLength,
+ offset, pcreOptions,
+ captureOffsets, captureOffsetsCount);
+ }
+ }
+
+#ifdef QREGULAREXPRESSION_DEBUG
+ qDebug() << "Matching" << pattern << "against" << subject
+ << offset << matchType << matchOptions << previousMatchWasEmpty
+ << "result" << result;
+#endif
+
+ // result == 0 means not enough space in captureOffsets; should never happen
+ Q_ASSERT(result != 0);
+
+ if (result > 0) {
+ // full match
+ priv->isValid = true;
+ priv->hasMatch = true;
+ priv->capturedCount = result;
+ priv->capturedOffsets.resize(result * 2);
+ } else {
+ // no match, partial match or error
+ priv->hasPartialMatch = (result == PCRE_ERROR_PARTIAL);
+ priv->isValid = (result == PCRE_ERROR_NOMATCH || result == PCRE_ERROR_PARTIAL);
+
+ if (result == PCRE_ERROR_PARTIAL) {
+ // partial match:
+ // leave the start and end capture offsets (i.e. cap(0))
+ priv->capturedCount = 1;
+ priv->capturedOffsets.resize(2);
+ } else {
+ // no match or error
+ priv->capturedCount = 0;
+ priv->capturedOffsets.clear();
+ }
+ }
+
+ return priv;
+}
+
+/*!
+ \internal
+*/
+QRegularExpressionMatchPrivate::QRegularExpressionMatchPrivate(const QRegularExpression &re,
+ const QString &subject,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ int capturingCount)
+ : regularExpression(re), subject(subject),
+ matchType(matchType), matchOptions(matchOptions),
+ capturedCount(0),
+ hasMatch(false), hasPartialMatch(false), isValid(false)
+{
+ Q_ASSERT(capturingCount >= 0);
+ const int captureOffsetsCount = (capturingCount + 1) * 3;
+ capturedOffsets.resize(captureOffsetsCount);
+}
+
+
+/*!
+ \internal
+*/
+QRegularExpressionMatch QRegularExpressionMatchPrivate::nextMatch() const
+{
+ Q_ASSERT(isValid);
+ Q_ASSERT(hasMatch || hasPartialMatch);
+
+ QRegularExpressionMatchPrivate *nextPrivate = regularExpression.d->doMatch(subject,
+ capturedOffsets.at(1),
+ matchType,
+ matchOptions,
+ this);
+ return QRegularExpressionMatch(*nextPrivate);
+}
+
+/*!
+ \internal
+*/
+QRegularExpressionMatchIteratorPrivate::QRegularExpressionMatchIteratorPrivate(const QRegularExpression &re,
+ QRegularExpression::MatchType matchType,
+ QRegularExpression::MatchOptions matchOptions,
+ const QRegularExpressionMatch &next)
+ : next(next),
+ regularExpression(re),
+ matchType(matchType), matchOptions(matchOptions)
+{
+}
+
+/*!
+ \internal
+*/
+bool QRegularExpressionMatchIteratorPrivate::hasNext() const
+{
+ return next.isValid() && (next.hasMatch() || next.hasPartialMatch());
+}
+
+// PUBLIC API
+
+/*!
+ Constructs a QRegularExpression object with an empty pattern and no pattern
+ options.
+
+ \sa setPattern(), setPatternOptions()
+*/
+QRegularExpression::QRegularExpression()
+ : d(new QRegularExpressionPrivate)
+{
+}
+
+/*!
+ Constructs a QRegularExpression object using the given \a pattern as
+ pattern and the \a options as the pattern options.
+
+ \sa setPattern(), setPatternOptions()
+*/
+QRegularExpression::QRegularExpression(const QString &pattern, PatternOptions options)
+ : d(new QRegularExpressionPrivate)
+{
+ d->pattern = pattern;
+ d->patternOptions = options;
+}
+
+/*!
+ Constructs a QRegularExpression object as a copy of \a re.
+
+ \sa operator=()
+*/
+QRegularExpression::QRegularExpression(const QRegularExpression &re)
+ : d(re.d)
+{
+}
+
+/*!
+ Destroys the QRegularExpression object.
+*/
+QRegularExpression::~QRegularExpression()
+{
+}
+
+/*!
+ Assigns the regular expression \a re to this object, and returns a reference
+ to the copy. Both the pattern and the pattern options are copied.
+*/
+QRegularExpression &QRegularExpression::operator=(const QRegularExpression &re)
+{
+ d = re.d;
+ return *this;
+}
+
+/*!
+ \fn void QRegularExpression::swap(QRegularExpression &other)
+
+ Swaps the regular expression \a other with this regular expression. This
+ operation is very fast and never fails.
+*/
+
+/*!
+ Returns the pattern string of the regular expression.
+
+ \sa setPattern(), patternOptions()
+*/
+QString QRegularExpression::pattern() const
+{
+ return d->pattern;
+}
+
+/*!
+ Sets the pattern string of the regular expression to \a pattern. The
+ pattern options are left unchanged.
+
+ \sa pattern(), setPatternOptions()
+*/
+void QRegularExpression::setPattern(const QString &pattern)
+{
+ d.detach();
+ d->isDirty = true;
+ d->pattern = pattern;
+}
+
+/*!
+ Returns the pattern options for the regular expression.
+
+ \sa setPatternOptions(), pattern()
+*/
+QRegularExpression::PatternOptions QRegularExpression::patternOptions() const
+{
+ return d->patternOptions;
+}
+
+/*!
+ Sets the given \a options as the pattern options of the regular expression.
+ The pattern string is left unchanged.
+
+ \sa patternOptions(), setPattern()
+*/
+void QRegularExpression::setPatternOptions(PatternOptions options)
+{
+ d.detach();
+ d->isDirty = true;
+ d->patternOptions = options;
+}
+
+/*!
+ Returns the number of capturing groups inside the pattern string,
+ or -1 if the regular expression is not valid.
+
+ \sa isValid()
+*/
+int QRegularExpression::captureCount() const
+{
+ if (!isValid()) // will compile the pattern
+ return -1;
+ return d->capturingCount;
+}
+
+/*!
+ Returns true if the regular expression is a valid regular expression (that
+ is, it contains no syntax errors, etc.), or false otherwise. Use
+ errorString() to obtain a textual description of the error.
+
+ \sa errorString(), patternErrorOffset()
+*/
+bool QRegularExpression::isValid() const
+{
+ d.data()->compilePattern();
+ return d->compiledPattern;
+}
+
+/*!
+ Returns a textual description of the error found when checking the validity
+ of the regular expression, or "no error" if no error was found.
+
+ \sa isValid(), patternErrorOffset()
+*/
+QString QRegularExpression::errorString() const
+{
+ d.data()->compilePattern();
+ if (d->errorString)
+ return QCoreApplication::translate("QRegularExpression", d->errorString, 0, QCoreApplication::UnicodeUTF8);
+ return QCoreApplication::translate("QRegularExpression", "no error", 0, QCoreApplication::UnicodeUTF8);
+}
+
+/*!
+ Returns the offset, inside the pattern string, at which an error was found
+ when checking the validity of the regular expression. If no error was
+ found, then -1 is returned.
+
+ \sa pattern(), isValid(), errorString()
+*/
+int QRegularExpression::patternErrorOffset() const
+{
+ d.data()->compilePattern();
+ return d->errorOffset;
+}
+
+/*!
+ Attempts to match the regular expression against the given \a subject
+ string, starting at the position \a offset inside the subject, using a
+ match of type \a matchType and honoring the given \a matchOptions.
+
+ The returned QRegularExpressionMatch object contains the results of the
+ match.
+
+ \sa QRegularExpressionMatch, {normal matching}
+*/
+QRegularExpressionMatch QRegularExpression::match(const QString &subject,
+ int offset,
+ MatchType matchType,
+ MatchOptions matchOptions) const
+{
+ d.data()->compilePattern();
+
+ QRegularExpressionMatchPrivate *priv = d->doMatch(subject, offset, matchType, matchOptions);
+ return QRegularExpressionMatch(*priv);
+}
+
+/*!
+ Attempts to perform a global match of the regular expression against the
+ given \a subject string, starting at the position \a offset inside the
+ subject, using a match of type \a matchType and honoring the given \a
+ matchOptions.
+
+ The returned QRegularExpressionMatchIterator is positioned before the
+ first match result (if any).
+
+ \sa QRegularExpressionMatchIterator, {global matching}
+*/
+QRegularExpressionMatchIterator QRegularExpression::globalMatch(const QString &subject,
+ int offset,
+ MatchType matchType,
+ MatchOptions matchOptions) const
+{
+ QRegularExpressionMatchIteratorPrivate *priv =
+ new QRegularExpressionMatchIteratorPrivate(*this,
+ matchType,
+ matchOptions,
+ match(subject, offset, matchType, matchOptions));
+
+ return QRegularExpressionMatchIterator(*priv);
+}
+
+/*!
+ Returns true if the regular expression is equal to \a re, or false
+ otherwise. Two QRegularExpression objects are equal if they have
+ the same pattern string and the same pattern options.
+
+ \sa operator!=()
+*/
+bool QRegularExpression::operator==(const QRegularExpression &re) const
+{
+ return (d == re.d) ||
+ (d->pattern == re.d->pattern && d->patternOptions == re.d->patternOptions);
+}
+
+/*!
+ \fn bool QRegularExpression::operator!=(const QRegularExpression &re) const
+
+ Returns true if the regular expression is different from \a re, or
+ false otherwise.
+
+ \sa operator==()
+*/
+
+/*!
+ Escapes all characters of \a str so that they no longer have any special
+ meaning when used as a regular expression pattern string, and returns
+ the escaped string. For instance:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 26
+
+ This is very convenient in order to build patterns from arbitrary strings:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 27
+
+ \note This function implements Perl's quotemeta algorithm and escapes with
+ a backslash all characters in \a str, except for the characters in the
+ \c{[A-Z]}, \c{[a-z]} and \c{[0-9]} ranges, as well as the underscore
+ (\c{_}) character. The only difference with Perl is that a literal NUL
+ inside \a str is escaped with the sequence \c{"\\\\0"} (backslash +
+ \c{'0'}), instead of \c{"\\\\\\0"} (backslash + \c{NUL}).
+*/
+QString QRegularExpression::escape(const QString &str)
+{
+ QString result;
+ const int count = str.size();
+ result.reserve(count * 2);
+
+ // everything but [a-zA-Z0-9_] gets escaped,
+ // cf. perldoc -f quotemeta
+ for (int i = 0; i < count; ++i) {
+ const QChar current = str.at(i);
+
+ if (current == QChar::Null) {
+ // unlike Perl, a literal NUL must be escaped with
+ // "\\0" (backslash + 0) and not "\\\0" (backslash + NUL),
+ // because pcre16_compile uses a NUL-terminated string
+ result.append(QLatin1Char('\\'));
+ result.append(QLatin1Char('0'));
+ } else if ( (current < QLatin1Char('a') || current > QLatin1Char('z')) &&
+ (current < QLatin1Char('A') || current > QLatin1Char('Z')) &&
+ (current < QLatin1Char('0') || current > QLatin1Char('9')) &&
+ current != QLatin1Char('_') )
+ {
+ result.append(QLatin1Char('\\'));
+ result.append(current);
+ if (current.isHighSurrogate() && i < (count - 1))
+ result.append(str.at(++i));
+ } else {
+ result.append(current);
+ }
+ }
+
+ result.squeeze();
+ return result;
+}
+
+/*!
+ Destroys the match result.
+*/
+QRegularExpressionMatch::~QRegularExpressionMatch()
+{
+}
+
+/*!
+ Constructs a match result by copying the result of the given \a match.
+
+ \sa operator=()
+*/
+QRegularExpressionMatch::QRegularExpressionMatch(const QRegularExpressionMatch &match)
+ : d(match.d)
+{
+}
+
+/*!
+ Assigns the match result \a match to this object, and returns a reference
+ to the copy.
+*/
+QRegularExpressionMatch &QRegularExpressionMatch::operator=(const QRegularExpressionMatch &match)
+{
+ d = match.d;
+ return *this;
+}
+
+/*!
+ \fn void QRegularExpressionMatch::swap(QRegularExpressionMatch &other)
+
+ Swaps the match result \a other with this match result. This
+ operation is very fast and never fails.
+*/
+
+/*!
+ \internal
+*/
+QRegularExpressionMatch::QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd)
+ : d(&dd)
+{
+}
+
+/*!
+ Returns the QRegularExpression object whose match() function returned this
+ object.
+
+ \sa QRegularExpression::match(), matchType(), matchOptions()
+*/
+QRegularExpression QRegularExpressionMatch::regularExpression() const
+{
+ return d->regularExpression;
+}
+
+
+/*!
+ Returns the match type that was used to get this QRegularExpressionMatch
+ object, that is, the match type that was passed to
+ QRegularExpression::match() or QRegularExpression::globalMatch().
+
+ \sa QRegularExpression::match(), regularExpression(), matchOptions()
+*/
+QRegularExpression::MatchType QRegularExpressionMatch::matchType() const
+{
+ return d->matchType;
+}
+
+/*!
+ Returns the match options that were used to get this
+ QRegularExpressionMatch object, that is, the match options that were passed
+ to QRegularExpression::match() or QRegularExpression::globalMatch().
+
+ \sa QRegularExpression::match(), regularExpression(), matchType()
+*/
+QRegularExpression::MatchOptions QRegularExpressionMatch::matchOptions() const
+{
+ return d->matchOptions;
+}
+
+/*!
+ Returns the index of the last capturing group that captured something,
+ including the implicit capturing group 0. This can be used to extract all
+ the substrings that were captured:
+
+ \snippet doc/src/snippets/code/src_corelib_tools_qregularexpression.cpp 28
+
+ Note that some of the capturing groups with an index less than
+ lastCapturedIndex() could have not matched, and therefore captured nothing.
+
+ If the regular expression did not match, this function returns -1.
+
+ \sa captured(), capturedStart(), capturedEnd(), capturedLength()
+*/
+int QRegularExpressionMatch::lastCapturedIndex() const
+{
+ return d->capturedCount - 1;
+}
+
+/*!
+ Returns the substring captured by the \a nth capturing group. If the \a nth
+ capturing group did not capture a string or doesn't exist, returns a null
+ QString.
+
+ \sa capturedRef(), lastCapturedIndex(), capturedStart(), capturedEnd(),
+ capturedLength(), QString::isNull()
+*/
+QString QRegularExpressionMatch::captured(int nth) const
+{
+ if (nth < 0 || nth > lastCapturedIndex())
+ return QString();
+
+ int start = capturedStart(nth);
+
+ if (start == -1) // didn't capture
+ return QString();
+
+ return d->subject.mid(start, capturedLength(nth));
+}
+
+/*!
+ Returns a reference to the substring captured by the \a nth capturing group.
+ If the \a nth capturing group did not capture a string or doesn't exist,
+ returns a null QStringRef.
+
+ \sa captured(), lastCapturedIndex(), capturedStart(), capturedEnd(),
+ capturedLength(), QStringRef::isNull()
+*/
+QStringRef QRegularExpressionMatch::capturedRef(int nth) const
+{
+ if (nth < 0 || nth > lastCapturedIndex())
+ return QStringRef();
+
+ int start = capturedStart(nth);
+
+ if (start == -1) // didn't capture
+ return QStringRef();
+
+ return d->subject.midRef(start, capturedLength(nth));
+}
+
+/*!
+ Returns the substring captured by the capturing group named \a name. If the
+ capturing group named \a name did not capture a string or doesn't exist,
+ returns a null QString.
+
+ \sa capturedRef(), capturedStart(), capturedEnd(), capturedLength(),
+ QString::isNull()
+*/
+QString QRegularExpressionMatch::captured(const QString &name) const
+{
+ if (name.isEmpty()) {
+ qWarning("QRegularExpressionMatch::captured: empty capturing group name passed");
+ return QString();
+ }
+ int nth = d->regularExpression.d->captureIndexForName(name);
+ if (nth == -1)
+ return QString();
+ return captured(nth);
+}
+
+/*!
+ Returns a reference to the string captured by the capturing group named \a
+ name. If the capturing group named \a name did not capture a string or
+ doesn't exist, returns a null QStringRef.
+
+ \sa captured(), capturedStart(), capturedEnd(), capturedLength(),
+ QStringRef::isNull()
+*/
+QStringRef QRegularExpressionMatch::capturedRef(const QString &name) const
+{
+ if (name.isEmpty()) {
+ qWarning("QRegularExpressionMatch::capturedRef: empty capturing group name passed");
+ return QStringRef();
+ }
+ int nth = d->regularExpression.d->captureIndexForName(name);
+ if (nth == -1)
+ return QStringRef();
+ return capturedRef(nth);
+}
+
+/*!
+ Returns a list of all strings captured by capturing groups, in the order
+ the groups themselves appear in the pattern string.
+*/
+QStringList QRegularExpressionMatch::capturedTexts() const
+{
+ QStringList texts;
+ for (int i = 0; i <= lastCapturedIndex(); ++i)
+ texts << captured(i);
+ return texts;
+}
+
+/*!
+ Returns the offset inside the subject string corresponding to the
+ starting position of the substring captured by the \a nth capturing group.
+ If the \a nth capturing group did not capture a string or doesn't exist,
+ returns -1.
+
+ \sa capturedEnd(), capturedLength(), captured()
+*/
+int QRegularExpressionMatch::capturedStart(int nth) const
+{
+ if (nth < 0 || nth > lastCapturedIndex())
+ return -1;
+
+ return d->capturedOffsets.at(nth * 2);
+}
+
+/*!
+ Returns the length of the substring captured by the \a nth capturing group.
+
+ \note This function returns 0 if the \a nth capturing group did not capture
+ a string or doesn't exist.
+
+ \sa capturedStart(), capturedEnd(), captured()
+*/
+int QRegularExpressionMatch::capturedLength(int nth) const
+{
+ // bound checking performed by these two functions
+ return capturedEnd(nth) - capturedStart(nth);
+}
+
+/*!
+ Returns the offset inside the subject string immediately after the ending
+ position of the substring captured by the \a nth capturing group. If the \a
+ nth capturing group did not capture a string or doesn't exist, returns -1.
+
+ \sa capturedStart(), capturedLength(), captured()
+*/
+int QRegularExpressionMatch::capturedEnd(int nth) const
+{
+ if (nth < 0 || nth > lastCapturedIndex())
+ return -1;
+
+ return d->capturedOffsets.at(nth * 2 + 1);
+}
+
+/*!
+ Returns the offset inside the subject string corresponding to the starting
+ position of the substring captured by the capturing group named \a name.
+ If the capturing group named \a name did not capture a string or doesn't
+ exist, returns -1.
+
+ \sa capturedEnd(), capturedLength(), captured()
+*/
+int QRegularExpressionMatch::capturedStart(const QString &name) const
+{
+ if (name.isEmpty()) {
+ qWarning("QRegularExpressionMatch::capturedStart: empty capturing group name passed");
+ return -1;
+ }
+ int nth = d->regularExpression.d->captureIndexForName(name);
+ if (nth == -1)
+ return -1;
+ return capturedStart(nth);
+}
+
+/*!
+ Returns the offset inside the subject string corresponding to the starting
+ position of the substring captured by the capturing group named \a name.
+
+ \note This function returns 0 if the capturing group named \a name did not
+ capture a string or doesn't exist.
+
+ \sa capturedStart(), capturedEnd(), captured()
+*/
+int QRegularExpressionMatch::capturedLength(const QString &name) const
+{
+ if (name.isEmpty()) {
+ qWarning("QRegularExpressionMatch::capturedLength: empty capturing group name passed");
+ return 0;
+ }
+ int nth = d->regularExpression.d->captureIndexForName(name);
+ if (nth == -1)
+ return 0;
+ return capturedLength(nth);
+}
+
+/*!
+ Returns the offset inside the subject string immediately after the ending
+ position of the substring captured by the capturing group named \a name. If
+ the capturing group named \a name did not capture a string or doesn't
+ exist, returns -1.
+
+ \sa capturedStart(), capturedLength(), captured()
+*/
+int QRegularExpressionMatch::capturedEnd(const QString &name) const
+{
+ if (name.isEmpty()) {
+ qWarning("QRegularExpressionMatch::capturedEnd: empty capturing group name passed");
+ return -1;
+ }
+ int nth = d->regularExpression.d->captureIndexForName(name);
+ if (nth == -1)
+ return -1;
+ return capturedEnd(nth);
+}
+
+/*!
+ Returns true if the regular expression matched against the subject string,
+ or false otherwise.
+
+ \sa QRegularExpression::match(), hasPartialMatch()
+*/
+bool QRegularExpressionMatch::hasMatch() const
+{
+ return d->hasMatch;
+}
+
+/*!
+ Returns true if the regular expression partially matched against the
+ subject string, or false otherwise.
+
+ \note Only a match that explicitely used the one of the partial match types
+ can yield a partial match. Still, if such a match succeeds totally, this
+ function will return false, while hasMatch() will return true.
+
+ \sa QRegularExpression::match(), QRegularExpression::MatchType, hasMatch()
+*/
+bool QRegularExpressionMatch::hasPartialMatch() const
+{
+ return d->hasPartialMatch;
+}
+
+/*!
+ Returns true if the match object was obtained as a result from the
+ QRegularExpression::match() function invoked on a valid QRegularExpression
+ object; returns false if the QRegularExpression was invalid.
+
+ \sa QRegularExpression::match(), QRegularExpression::isValid()
+*/
+bool QRegularExpressionMatch::isValid() const
+{
+ return d->isValid;
+}
+
+/*!
+ \internal
+*/
+QRegularExpressionMatchIterator::QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd)
+ : d(&dd)
+{
+}
+
+/*!
+ Destroys the QRegularExpressionMatchIterator object.
+*/
+QRegularExpressionMatchIterator::~QRegularExpressionMatchIterator()
+{
+}
+
+/*!
+ Constructs a QRegularExpressionMatchIterator object as a copy of \a
+ iterator.
+
+ \sa operator=()
+*/
+QRegularExpressionMatchIterator::QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator)
+ : d(iterator.d)
+{
+}
+
+/*!
+ Assigns the iterator \a iterator to this object, and returns a reference to
+ the copy.
+*/
+QRegularExpressionMatchIterator &QRegularExpressionMatchIterator::operator=(const QRegularExpressionMatchIterator &iterator)
+{
+ d = iterator.d;
+ return *this;
+}
+
+/*!
+ \fn void QRegularExpressionMatchIterator::swap(QRegularExpressionMatchIterator &other)
+
+ Swaps the iterator \a other with this iterator object. This operation is
+ very fast and never fails.
+*/
+
+/*!
+ Returns true if the iterator object was obtained as a result from the
+ QRegularExpression::globalMatch() function invoked on a valid
+ QRegularExpression object; returns false if the QRegularExpression was
+ invalid.
+
+ \sa QRegularExpression::globalMatch(), QRegularExpression::isValid()
+*/
+bool QRegularExpressionMatchIterator::isValid() const
+{
+ return d->next.isValid();
+}
+
+/*!
+ Returns true if there is at least one match result ahead of the iterator;
+ otherwise it returns false.
+
+ \sa next()
+*/
+bool QRegularExpressionMatchIterator::hasNext() const
+{
+ return d->hasNext();
+}
+
+/*!
+ Returns the next match result without moving the iterator.
+
+ \note Calling this function when the iterator is at the end of the result
+ set leads to undefined results.
+*/
+QRegularExpressionMatch QRegularExpressionMatchIterator::peekNext() const
+{
+ if (!hasNext())
+ qWarning("QRegularExpressionMatchIterator::peekNext() called on an iterator already at end");
+
+ return d->next;
+}
+
+/*!
+ Returns the next match result and advances the iterator by one position.
+
+ \note Calling this function when the iterator is at the end of the result
+ set leads to undefined results.
+*/
+QRegularExpressionMatch QRegularExpressionMatchIterator::next()
+{
+ if (!hasNext()) {
+ qWarning("QRegularExpressionMatchIterator::next() called on an iterator already at end");
+ return d->next;
+ }
+
+ QRegularExpressionMatch current = d->next;
+ d->next = d->next.d.constData()->nextMatch();
+ return current;
+}
+
+/*!
+ Returns the QRegularExpression object whose globalMatch() function returned
+ this object.
+
+ \sa QRegularExpression::globalMatch(), matchType(), matchOptions()
+*/
+QRegularExpression QRegularExpressionMatchIterator::regularExpression() const
+{
+ return d->regularExpression;
+}
+
+/*!
+ Returns the match type that was used to get this
+ QRegularExpressionMatchIterator object, that is, the match type that was
+ passed to QRegularExpression::globalMatch().
+
+ \sa QRegularExpression::globalMatch(), regularExpression(), matchOptions()
+*/
+QRegularExpression::MatchType QRegularExpressionMatchIterator::matchType() const
+{
+ return d->matchType;
+}
+
+/*!
+ Returns the match options that were used to get this
+ QRegularExpressionMatchIterator object, that is, the match options that
+ were passed to QRegularExpression::globalMatch().
+
+ \sa QRegularExpression::globalMatch(), regularExpression(), matchType()
+*/
+QRegularExpression::MatchOptions QRegularExpressionMatchIterator::matchOptions() const
+{
+ return d->matchOptions;
+}
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QRegularExpression
+
+ Writes the regular expression \a re to stream \a out.
+
+ \sa {Serializing Qt Data Types}
+*/
+QDataStream &operator<<(QDataStream &out, const QRegularExpression &re)
+{
+ out << re.pattern() << quint32(re.patternOptions());
+ return out;
+}
+
+/*!
+ \relates QRegularExpression
+
+ Reads a regular expression from stream \a in into \a re.
+
+ \sa {Serializing Qt Data Types}
+*/
+QDataStream &operator>>(QDataStream &in, QRegularExpression &re)
+{
+ QString pattern;
+ quint32 patternOptions;
+ in >> pattern >> patternOptions;
+ re.setPattern(pattern);
+ re.setPatternOptions(QRegularExpression::PatternOptions(patternOptions));
+ return in;
+}
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ \relates QRegularExpression
+
+ Writes the regular expression \a re into the debug object \a debug for
+ debugging purposes.
+
+ \sa {Debugging Techniques}
+*/
+QDebug operator<<(QDebug debug, const QRegularExpression &re)
+{
+ debug.nospace() << "QRegularExpression(" << re.pattern() << ", " << re.patternOptions() << ")";
+ return debug.space();
+}
+
+/*!
+ \relates QRegularExpression
+
+ Writes the pattern options \a patternOptions into the debug object \a debug
+ for debugging purposes.
+
+ \sa {Debugging Techniques}
+*/
+QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions)
+{
+ QStringList flags;
+
+ if (patternOptions == QRegularExpression::NoPatternOption) {
+ flags << QLatin1String("NoPatternOption");
+ } else {
+ if (patternOptions & QRegularExpression::CaseInsensitiveOption)
+ flags << QLatin1String("CaseInsensitiveOption");
+ if (patternOptions & QRegularExpression::DotMatchesEverythingOption)
+ flags << QLatin1String("DotMatchesEverythingOption");
+ if (patternOptions & QRegularExpression::MultilineOption)
+ flags << QLatin1String("MultilineOption");
+ if (patternOptions & QRegularExpression::ExtendedPatternSyntaxOption)
+ flags << QLatin1String("ExtendedPatternSyntaxOption");
+ if (patternOptions & QRegularExpression::InvertedGreedinessOption)
+ flags << QLatin1String("InvertedGreedinessOption");
+ if (patternOptions & QRegularExpression::DontCaptureOption)
+ flags << QLatin1String("DontCaptureOption");
+ if (patternOptions & QRegularExpression::UseUnicodePropertiesOption)
+ flags << QLatin1String("UseUnicodePropertiesOption");
+ }
+
+ debug.nospace() << "QRegularExpression::PatternOptions("
+ << qPrintable(flags.join(QLatin1String("|")))
+ << ")";
+
+ return debug.space();
+}
+/*!
+ \relates QRegularExpressionMatch
+
+ Writes the match object \a match into the debug object \a debug for
+ debugging purposes.
+
+ \sa {Debugging Techniques}
+*/
+QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match)
+{
+ debug.nospace() << "QRegularExpressionMatch(";
+
+ if (!match.isValid()) {
+ debug << "Invalid)";
+ return debug.space();
+ }
+
+ debug << "Valid";
+
+ if (match.hasMatch()) {
+ debug << ", has match: ";
+ for (int i = 0; i <= match.lastCapturedIndex(); ++i) {
+ debug << i
+ << ":(" << match.capturedStart(i) << ", " << match.capturedEnd(i)
+ << ", " << match.captured(i) << ")";
+ if (i < match.lastCapturedIndex())
+ debug << ", ";
+ }
+ } else if (match.hasPartialMatch()) {
+ debug << ", has partial match: ("
+ << match.capturedStart(0) << ", "
+ << match.capturedEnd(0) << ", "
+ << match.captured(0) << ")";
+ } else {
+ debug << ", no match";
+ }
+
+ debug << ")";
+
+ return debug.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/tools/qregularexpression.h
new file mode 100644
index 00000000000..3ca83c9e270
--- /dev/null
+++ b/src/corelib/tools/qregularexpression.h
@@ -0,0 +1,248 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Giuseppe D'Angelo .
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QREGULAREXPRESSION_H
+#define QREGULAREXPRESSION_H
+
+#ifndef QT_NO_REGEXP
+
+#include
+#include
+#include
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QRegularExpressionMatch;
+class QRegularExpressionMatchIterator;
+struct QRegularExpressionPrivate;
+
+class Q_CORE_EXPORT QRegularExpression
+{
+public:
+ enum PatternOption {
+ NoPatternOption = 0x0000,
+ CaseInsensitiveOption = 0x0001,
+ DotMatchesEverythingOption = 0x0002,
+ MultilineOption = 0x0004,
+ ExtendedPatternSyntaxOption = 0x0008,
+ InvertedGreedinessOption = 0x0010,
+ DontCaptureOption = 0x0020,
+ UseUnicodePropertiesOption = 0x0040
+ };
+ Q_DECLARE_FLAGS(PatternOptions, PatternOption)
+
+ PatternOptions patternOptions() const;
+ void setPatternOptions(PatternOptions options);
+
+ QRegularExpression();
+ explicit QRegularExpression(const QString &pattern, PatternOptions options = NoPatternOption);
+ QRegularExpression(const QRegularExpression &re);
+ ~QRegularExpression();
+ QRegularExpression &operator=(const QRegularExpression &re);
+
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QRegularExpression &operator=(QRegularExpression &&re)
+ { d.swap(re.d); return *this; }
+#endif
+
+ inline void swap(QRegularExpression &re) { d.swap(re.d); }
+
+ QString pattern() const;
+ void setPattern(const QString &pattern);
+
+ bool isValid() const;
+ int patternErrorOffset() const;
+ QString errorString() const;
+
+ int captureCount() const;
+
+ enum MatchType {
+ NormalMatch = 0,
+ PartialPreferCompleteMatch,
+ PartialPreferFirstMatch
+ };
+
+ enum MatchOption {
+ NoMatchOption = 0x0000,
+ AnchoredMatchOption = 0x0001
+ };
+ Q_DECLARE_FLAGS(MatchOptions, MatchOption)
+
+ QRegularExpressionMatch match(const QString &subject,
+ int offset = 0,
+ MatchType matchType = NormalMatch,
+ MatchOptions matchOptions = NoMatchOption) const;
+
+ QRegularExpressionMatchIterator globalMatch(const QString &subject,
+ int offset = 0,
+ MatchType matchType = NormalMatch,
+ MatchOptions matchOptions = NoMatchOption) const;
+
+ static QString escape(const QString &str);
+
+ bool operator==(const QRegularExpression &re) const;
+ inline bool operator!=(const QRegularExpression &re) const { return !operator==(re); }
+
+private:
+ friend struct QRegularExpressionPrivate;
+ friend class QRegularExpressionMatch;
+ friend struct QRegularExpressionMatchPrivate;
+ friend class QRegularExpressionMatchIterator;
+
+ QRegularExpression(QRegularExpressionPrivate &dd);
+ QExplicitlySharedDataPointer d;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions)
+Q_DECLARE_TYPEINFO(QRegularExpression, Q_MOVABLE_TYPE);
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &in, QRegularExpression &re);
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpression &re);
+Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions patternOptions);
+#endif
+
+struct QRegularExpressionMatchPrivate;
+
+class Q_CORE_EXPORT QRegularExpressionMatch
+{
+public:
+ ~QRegularExpressionMatch();
+ QRegularExpressionMatch(const QRegularExpressionMatch &match);
+ QRegularExpressionMatch &operator=(const QRegularExpressionMatch &match);
+
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match)
+ { d.swap(match.d); return *this; }
+#endif
+ inline void swap(QRegularExpressionMatch &match) { d.swap(match.d); }
+
+ QRegularExpression regularExpression() const;
+ QRegularExpression::MatchType matchType() const;
+ QRegularExpression::MatchOptions matchOptions() const;
+
+ bool hasMatch() const;
+ bool hasPartialMatch() const;
+
+ bool isValid() const;
+
+ int lastCapturedIndex() const;
+
+ QString captured(int nth = 0) const;
+ QStringRef capturedRef(int nth = 0) const;
+
+ QString captured(const QString &name) const;
+ QStringRef capturedRef(const QString &name) const;
+
+ QStringList capturedTexts() const;
+
+ int capturedStart(int nth = 0) const;
+ int capturedLength(int nth = 0) const;
+ int capturedEnd(int nth = 0) const;
+
+ int capturedStart(const QString &name) const;
+ int capturedLength(const QString &name) const;
+ int capturedEnd(const QString &name) const;
+
+private:
+ friend class QRegularExpression;
+ friend struct QRegularExpressionMatchPrivate;
+ friend class QRegularExpressionMatchIterator;
+
+ QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd);
+ QSharedDataPointer d;
+};
+
+Q_DECLARE_TYPEINFO(QRegularExpressionMatch, Q_MOVABLE_TYPE);
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match);
+#endif
+
+struct QRegularExpressionMatchIteratorPrivate;
+
+class Q_CORE_EXPORT QRegularExpressionMatchIterator
+{
+public:
+ ~QRegularExpressionMatchIterator();
+ QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator);
+ QRegularExpressionMatchIterator &operator=(const QRegularExpressionMatchIterator &iterator);
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator)
+ { d.swap(iterator.d); return *this; }
+#endif
+ void swap(QRegularExpressionMatchIterator &iterator) { d.swap(iterator.d); }
+
+ bool isValid() const;
+
+ bool hasNext() const;
+ QRegularExpressionMatch next();
+ QRegularExpressionMatch peekNext() const;
+
+ QRegularExpression regularExpression() const;
+ QRegularExpression::MatchType matchType() const;
+ QRegularExpression::MatchOptions matchOptions() const;
+
+private:
+ friend class QRegularExpression;
+
+ QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd);
+ QSharedDataPointer d;
+};
+
+Q_DECLARE_TYPEINFO(QRegularExpressionMatchIterator, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QRegularExpression)
+
+QT_END_HEADER
+
+#endif // QT_NO_REGEXP
+
+#endif // QREGULAREXPRESSION_H
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index 46e505099a9..c248477f2c0 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QRingBuffer
{
public:
- inline QRingBuffer(int growth = 4096) : basicBlockSize(growth) {
+ explicit inline QRingBuffer(int growth = 4096) : basicBlockSize(growth) {
buffers << QByteArray();
clear();
}
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index b6bf525fb9c..5ecca89229a 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -89,10 +89,10 @@ QT_BEGIN_NAMESPACE
The following custom cleanup handlers exist:
\list
- \i QScopedPointerDeleter - the default, deletes the pointer using \c delete
- \i QScopedPointerArrayDeleter - deletes the pointer using \c{delete []}. Use
+ \li QScopedPointerDeleter - the default, deletes the pointer using \c delete
+ \li QScopedPointerArrayDeleter - deletes the pointer using \c{delete []}. Use
this handler for pointers that were allocated with \c{new []}.
- \i QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this
+ \li QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this
handler for pointers that were allocated with \c{malloc()}.
\endlist
diff --git a/src/corelib/tools/qscopedvaluerollback.h b/src/corelib/tools/qscopedvaluerollback.h
index 23d2d9eda04..d53cabd3157 100644
--- a/src/corelib/tools/qscopedvaluerollback.h
+++ b/src/corelib/tools/qscopedvaluerollback.h
@@ -51,7 +51,7 @@ template
class QScopedValueRollback
{
public:
- QScopedValueRollback(T &var) :
+ explicit QScopedValueRollback(T &var) :
varRef(var)
{
oldValue = varRef;
diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp
index 62507454000..ffc8ac601db 100644
--- a/src/corelib/tools/qshareddata.cpp
+++ b/src/corelib/tools/qshareddata.cpp
@@ -86,10 +86,10 @@ QT_BEGIN_NAMESPACE
\list
- \o Define the class \c Employee to have a single data member of
+ \li Define the class \c Employee to have a single data member of
type \c {QSharedDataPointer}.
- \o Define the \c EmployeeData class derived from \l QSharedData to
+ \li Define the \c EmployeeData class derived from \l QSharedData to
contain all the data members you would normally have put in the
\c Employee class.
diff --git a/src/corelib/tools/qsize.cpp b/src/corelib/tools/qsize.cpp
index 4c94f899e73..b276d2d2e0d 100644
--- a/src/corelib/tools/qsize.cpp
+++ b/src/corelib/tools/qsize.cpp
@@ -186,10 +186,10 @@ void QSize::transpose()
height, according to the specified \a mode:
\list
- \i If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
- \i If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
+ \li If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
+ \li If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
as large as possible inside (\a width, \a height), preserving the aspect ratio.
- \i If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
+ \li If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
as small as possible outside (\a width, \a height), preserving the aspect ratio.
\endlist
@@ -614,10 +614,10 @@ void QSizeF::transpose()
height, according to the specified \a mode.
\list
- \i If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
- \i If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
+ \li If \a mode is Qt::IgnoreAspectRatio, the size is set to (\a width, \a height).
+ \li If \a mode is Qt::KeepAspectRatio, the current size is scaled to a rectangle
as large as possible inside (\a width, \a height), preserving the aspect ratio.
- \i If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
+ \li If \a mode is Qt::KeepAspectRatioByExpanding, the current size is scaled to a rectangle
as small as possible outside (\a width, \a height), preserving the aspect ratio.
\endlist
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index d0c2dd7148e..58eb7111681 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -608,12 +608,12 @@ const QString::Null QString::null = { };
toLatin1(), toUtf8(), and toLocal8Bit().
\list
- \o toAscii() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
- \o toLatin1() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
- \o toUtf8() returns a UTF-8 encoded 8-bit string. UTF-8 is a
+ \li toAscii() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
+ \li toLatin1() returns a Latin-1 (ISO 8859-1) encoded 8-bit string.
+ \li toUtf8() returns a UTF-8 encoded 8-bit string. UTF-8 is a
superset of US-ASCII (ANSI X3.4-1986) that supports the entire
Unicode character set through multibyte sequences.
- \o toLocal8Bit() returns an 8-bit string using the system's local
+ \li toLocal8Bit() returns an 8-bit string using the system's local
encoding.
\endlist
@@ -631,9 +631,9 @@ const QString::Null QString::null = { };
conversions by defining the following two preprocessor symbols:
\list
- \o \c QT_NO_CAST_FROM_ASCII disables automatic conversions from
+ \li \c QT_NO_CAST_FROM_ASCII disables automatic conversions from
C string literals and pointers to Unicode.
- \o \c QT_NO_CAST_TO_ASCII disables automatic conversion from QString
+ \li \c QT_NO_CAST_TO_ASCII disables automatic conversion from QString
to C strings.
\endlist
@@ -657,10 +657,10 @@ const QString::Null QString::null = { };
\table 100 %
\header
- \o Note for C Programmers
+ \li Note for C Programmers
\row
- \o
+ \li
Due to C++'s type system and the fact that QString is
\l{implicitly shared}, QStrings may be treated like \c{int}s or
other basic types. For example:
@@ -699,12 +699,12 @@ const QString::Null QString::null = { };
following:
\table
- \header \o Format \o Meaning
- \row \o \c e \o format as [-]9.9e[+|-]999
- \row \o \c E \o format as [-]9.9E[+|-]999
- \row \o \c f \o format as [-]9.9
- \row \o \c g \o use \c e or \c f format, whichever is the most concise
- \row \o \c G \o use \c E or \c f format, whichever is the most concise
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
\endtable
A \e precision is also specified with the argument \e format. For
@@ -2115,7 +2115,8 @@ QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivi
/*!
- Returns true if string \a other is equal to this string; otherwise
+ \relates QString
+ Returns true if string \a s1 is equal to string \a s2; otherwise
returns false.
The comparison is based exclusively on the numeric Unicode values of
@@ -2123,12 +2124,12 @@ QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivi
expect. Consider sorting user-interface strings with
localeAwareCompare().
*/
-bool QString::operator==(const QString &other) const
+bool operator==(const QString &s1, const QString &s2)
{
- if (d->size != other.d->size)
+ if (s1.d->size != s2.d->size)
return false;
- return qMemEquals(d->data(), other.d->data(), d->size);
+ return qMemEquals(s1.d->data(), s2.d->data(), s1.d->size);
}
/*!
@@ -2183,17 +2184,18 @@ bool QString::operator==(const QLatin1String &other) const
*/
/*!
- Returns true if this string is lexically less than string \a
- other; otherwise returns false.
+ \relates QString
+ Returns true if string \a s1 is lexically less than string
+ \a s2; otherwise returns false.
The comparison is based exclusively on the numeric Unicode values
of the characters and is very fast, but is not what a human would
expect. Consider sorting user-interface strings using the
QString::localeAwareCompare() function.
*/
-bool QString::operator<(const QString &other) const
+bool operator<(const QString &s1, const QString &s2)
{
- return ucstrcmp(constData(), length(), other.constData(), other.length()) < 0;
+ return ucstrcmp(s1.constData(), s1.length(), s2.constData(), s2.length()) < 0;
}
/*!
@@ -2244,10 +2246,11 @@ bool QString::operator<(const QLatin1String &other) const
go through QObject::tr(), for example.
*/
-/*! \fn bool QString::operator<=(const QString &other) const
+/*! \fn bool operator<=(const QString &s1, const QString &s2)
+ \relates QString
- Returns true if this string is lexically less than or equal to
- string \a other; otherwise returns false.
+ Returns true if string \a s1 is lexically less than or equal to
+ string \a s2; otherwise returns false.
The comparison is based exclusively on the numeric Unicode values
of the characters and is very fast, but is not what a human would
@@ -2287,10 +2290,11 @@ bool QString::operator<(const QLatin1String &other) const
go through QObject::tr(), for example.
*/
-/*! \fn bool QString::operator>(const QString &other) const
+/*! \fn bool operator>(const QString &s1, const QString &s2)
+ \relates QString
- Returns true if this string is lexically greater than string \a
- other; otherwise returns false.
+ Returns true if string \a s1 is lexically greater than string \a
+ s2; otherwise returns false.
The comparison is based exclusively on the numeric Unicode values
of the characters and is very fast, but is not what a human would
@@ -2346,10 +2350,11 @@ bool QString::operator>(const QLatin1String &other) const
for example.
*/
-/*! \fn bool QString::operator>=(const QString &other) const
+/*! \fn bool operator>=(const QString &s1, const QString &s2)
+ \relates QString
- Returns true if this string is lexically greater than or equal to
- string \a other; otherwise returns false.
+ Returns true if string \a s1 is lexically greater than or equal to
+ string \a s2; otherwise returns false.
The comparison is based exclusively on the numeric Unicode values
of the characters and is very fast, but is not what a human would
@@ -2389,9 +2394,10 @@ bool QString::operator>(const QLatin1String &other) const
for example.
*/
-/*! \fn bool QString::operator!=(const QString &other) const
+/*! \fn bool operator!=(const QString &s1, const QString &s2)
+ \relates QString
- Returns true if this string is not equal to string \a other;
+ Returns true if string \a s1 is not equal to string \a s2;
otherwise returns false.
The comparison is based exclusively on the numeric Unicode values
@@ -2772,7 +2778,7 @@ struct QStringCapture
\snippet doc/src/snippets/qstring/main.cpp 42
For regular expressions containing \l{capturing parentheses},
- occurrences of \bold{\\1}, \bold{\\2}, ..., in \a after are replaced
+ occurrences of \b{\\1}, \b{\\2}, ..., in \a after are replaced
with \a{rx}.cap(1), cap(2), ...
\snippet doc/src/snippets/qstring/main.cpp 43
@@ -4706,7 +4712,7 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
} // else fall through
# endif
// declared in
- int delta = strcoll(toLocal8Bit_helper(data1, length1), toLocal8Bit_helper(data2, length2));
+ int delta = strcoll(toLocal8Bit_helper(data1, length1).constData(), toLocal8Bit_helper(data2, length2).constData());
if (delta == 0)
delta = ucstrcmp(data1, length1, data2, length2);
return delta;
@@ -6038,7 +6044,7 @@ QStringList QString::split(QChar sep, SplitBehavior behavior, Qt::CaseSensitivit
\snippet doc/src/snippets/qstring/main.cpp 60
Here's a third example where we use a zero-length assertion,
- \bold{\\b} (word boundary), to split the string into an
+ \b{\\b} (word boundary), to split the string into an
alternating sequence of non-word and word tokens:
\snippet doc/src/snippets/qstring/main.cpp 61
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index ba68ab022b7..26959d81f31 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -97,7 +97,9 @@ template