Merge remote-tracking branch 'origin/5.5' into 5.6
Conflicts: qmake/doc/snippets/code/doc_src_qmake-manual.pro qmake/doc/src/qmake-manual.qdoc src/corelib/io/qstorageinfo_unix.cpp src/corelib/tools/qbytearray.cpp src/widgets/kernel/qwidgetwindow.cpp tests/auto/corelib/io/qprocess/tst_qprocess.cpp tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp tests/auto/network/access/qnetworkreply/BLACKLIST Change-Id: I9efcd7e1cce1c394eed425c43aa6fce7d2edf31c
This commit is contained in:
commit
afab1546a7
@ -6,7 +6,7 @@
|
||||
You may use, distribute and copy the Qt GUI Toolkit under the terms of
|
||||
GNU Lesser General Public License version 3. That license references
|
||||
the General Public License version 3, that is displayed below. Other
|
||||
portions of the Qt Toolkit may be licensed directly other this license.
|
||||
portions of the Qt Toolkit may be licensed directly under this license.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
Contact: http://www.qt.io/licensing/
|
||||
|
||||
You may use, distribute and copy the Qt GUI Toolkit under the terms of
|
||||
GNU Lesser General Public License version 3, which is displayed
|
||||
below. This license makes reference to the version 3 of the GNU General
|
||||
GNU Lesser General Public License version 3, which is displayed below.
|
||||
This license makes reference to the version 3 of the GNU General
|
||||
Public License, which you can find in the LICENSE.GPLv3 file.
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
|
@ -140,7 +140,7 @@ greaterThan(MSC_VER, 1899) {
|
||||
QMAKE_CFLAGS += -Zc:strictStrings
|
||||
QMAKE_CFLAGS_WARN_ON += -w44456 -w44457 -w44458
|
||||
QMAKE_CFLAGS_AVX2 = -arch:AVX2
|
||||
QMAKE_CXXFLAGS += -Zc:strictStrings
|
||||
QMAKE_CXXFLAGS += -Zc:strictStrings -Zc:throwingNew
|
||||
QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458 -wd4577
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,8 @@
|
||||
<Identity
|
||||
Name=\"$${WINRT_MANIFEST.identity}\"
|
||||
Publisher=\"$${WINRT_MANIFEST.publisherid}\"
|
||||
Version=\"$${WINRT_MANIFEST.version}\" />
|
||||
Version=\"$${WINRT_MANIFEST.version}\"
|
||||
ProcessorArchitecture=\"$${WINRT_MANIFEST.architecture}\" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId=\"$${WINRT_MANIFEST.identity}\" PhonePublisherId=\"$${WINRT_MANIFEST.phone_publisher_id}\"/>
|
||||
|
||||
@ -20,7 +21,7 @@
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10069.0\" MaxVersionTested=\"10.0.10069.0\" />
|
||||
<TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10069.0\" MaxVersionTested=\"10.0.10069.0\" />$${WINRT_MANIFEST.dependencies}
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
|
@ -41,6 +41,8 @@
|
||||
<m2:SplashScreen Image=\"$${WINRT_MANIFEST.logo_620x300}\" />$${WINRT_MANIFEST.rotation_preference}
|
||||
</m2:VisualElements>
|
||||
</Application>
|
||||
</Applications>$${WINRT_MANIFEST.capabilities}$${WINRT_MANIFEST.dependencies}
|
||||
</Applications>$${WINRT_MANIFEST.capabilities}
|
||||
<Dependencies>$${WINRT_MANIFEST.dependencies}
|
||||
</Dependencies>
|
||||
</Package>
|
||||
<!-- Generated by qmake using the $$[QMAKE_XSPEC] mkspec. -->
|
||||
|
@ -42,6 +42,8 @@
|
||||
<m3:SplashScreen Image=\"$${WINRT_MANIFEST.logo_480x800}\" />$${WINRT_MANIFEST.rotation_preference}
|
||||
</m3:VisualElements>
|
||||
</Application>
|
||||
</Applications>$${WINRT_MANIFEST.capabilities}$${WINRT_MANIFEST.dependencies}
|
||||
</Applications>$${WINRT_MANIFEST.capabilities}
|
||||
<Dependencies>$${WINRT_MANIFEST.dependencies}
|
||||
</Dependencies>
|
||||
</Package>
|
||||
<!-- Generated by qmake using the $$[QMAKE_XSPEC] mkspec. -->
|
||||
|
12
mkspecs/features/winrt/default_pre.prf
Normal file
12
mkspecs/features/winrt/default_pre.prf
Normal file
@ -0,0 +1,12 @@
|
||||
*msvc2015 {
|
||||
# Note that the order is important, ucrt(d) has to be first
|
||||
# Otherwise the linker might use malloc from a different library
|
||||
# but free_dbg() from the runtime, causing assert when deleting
|
||||
# items from different heaps
|
||||
CONFIG(debug, debug|release): \
|
||||
QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS
|
||||
else: \
|
||||
QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS
|
||||
}
|
||||
|
||||
load(default_pre)
|
@ -58,9 +58,11 @@
|
||||
VCLIBS = Microsoft.VCLibs.$$replace(MSVC_VER, \\., ).00
|
||||
winphone: VCLIBS = $${VCLIBS}.Phone
|
||||
CONFIG(debug, debug|release): \
|
||||
WINRT_MANIFEST.dependencies += $${VCLIBS}.Debug
|
||||
VCLIBS = $${VCLIBS}.Debug
|
||||
else: \
|
||||
WINRT_MANIFEST.dependencies += $$VCLIBS
|
||||
VCLIBS = $${VCLIBS}
|
||||
contains(MSVC_VER, "14.0"): VCLIBS = "$${VCLIBS}\" MinVersion=\"14.0.0.0\" Publisher=\"CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
|
||||
WINRT_MANIFEST.dependencies += $$VCLIBS
|
||||
}
|
||||
|
||||
# Provide default values for required variables
|
||||
@ -122,12 +124,11 @@
|
||||
}
|
||||
|
||||
# Dependencies are given as a string list. The CRT dependency is added automatically above.
|
||||
# For MSVC2015 the dependencies are added in conjunction with TargetDeviceFamily
|
||||
WINRT_MANIFEST.dependencies = $$unique(WINRT_MANIFEST.dependencies)
|
||||
!isEmpty(WINRT_MANIFEST.dependencies) {
|
||||
MANIFEST_DEPENDENCIES += "<Dependencies>"
|
||||
for(DEPENDENCY, WINRT_MANIFEST.dependencies): \
|
||||
MANIFEST_DEPENDENCIES += " <PackageDependency Name=\"$$DEPENDENCY\" />"
|
||||
MANIFEST_DEPENDENCIES += "</Dependencies>"
|
||||
|
||||
WINRT_MANIFEST.dependencies = $$join(MANIFEST_DEPENDENCIES, $$INDENT, $$INDENT)
|
||||
}
|
||||
@ -159,5 +160,13 @@
|
||||
WINRT_MANIFEST.$${ICON_NAME} = assets/$$basename(ICON_FILE)
|
||||
}
|
||||
|
||||
!contains(TEMPLATE, "vc.*") {
|
||||
winrt_manifest_install.files = $$manifest_file.output
|
||||
winrt_manifest_install.path = $$target.path
|
||||
winrt_assets_install.files = $$BUILD_DIR/assets/*
|
||||
winrt_assets_install.path = $$target.path/assets
|
||||
INSTALLS += winrt_manifest_install winrt_assets_install
|
||||
}
|
||||
|
||||
QMAKE_SUBSTITUTES += manifest_file
|
||||
}
|
||||
|
@ -10,19 +10,9 @@ DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP ARM __ARM__ __arm__
|
||||
|
||||
QMAKE_CFLAGS += -FS
|
||||
QMAKE_CXXFLAGS += -FS
|
||||
QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib
|
||||
QMAKE_LFLAGS += /MACHINE:ARM
|
||||
|
||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib
|
||||
|
||||
# Note that the order is important, ucrt(d) has to be first
|
||||
# Otherwise the linker might use malloc from a different library
|
||||
# but free_dbg() from the runtime, causing assert when deleting
|
||||
# items from different heaps
|
||||
CONFIG(debug, debug|release) {
|
||||
QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS
|
||||
} else {
|
||||
QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS
|
||||
}
|
||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib kernel32.lib
|
||||
|
||||
VCPROJ_ARCH = ARM
|
||||
MSVC_VER = 14.0
|
||||
|
@ -10,19 +10,9 @@ DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X64 __X64__ __x64__
|
||||
|
||||
QMAKE_CFLAGS += -FS
|
||||
QMAKE_CXXFLAGS += -FS
|
||||
QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib
|
||||
QMAKE_LFLAGS += /MACHINE:X64
|
||||
|
||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib
|
||||
|
||||
# Note that the order is important, ucrt(d) has to be first
|
||||
# Otherwise the linker might use malloc from a different library
|
||||
# but free_dbg() from the runtime, causing assert when deleting
|
||||
# items from different heaps
|
||||
CONFIG(debug, debug|release) {
|
||||
QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS
|
||||
} else {
|
||||
QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS
|
||||
}
|
||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib kernel32.lib
|
||||
|
||||
VCPROJ_ARCH = x64
|
||||
MSVC_VER = 14.0
|
||||
|
@ -10,19 +10,9 @@ DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X86 __X86__ __x86__
|
||||
|
||||
QMAKE_CFLAGS += -FS
|
||||
QMAKE_CXXFLAGS += -FS
|
||||
QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib
|
||||
QMAKE_LFLAGS += /SAFESEH /MACHINE:X86
|
||||
|
||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib
|
||||
|
||||
# Note that the order is important, ucrt(d) has to be first
|
||||
# Otherwise the linker might use malloc from a different library
|
||||
# but free_dbg() from the runtime, causing assert when deleting
|
||||
# items from different heaps
|
||||
CONFIG(debug, debug|release) {
|
||||
QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS
|
||||
} else {
|
||||
QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS
|
||||
}
|
||||
QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib kernel32.lib
|
||||
|
||||
VCPROJ_ARCH = Win32
|
||||
MSVC_VER = 14.0
|
||||
|
@ -977,3 +977,9 @@ VERSION_PE_HEADER = 1.2
|
||||
RC_DEFINES += USE_MY_STUFF
|
||||
#! [186]
|
||||
|
||||
#! [187]
|
||||
win32-g++:contains(QMAKE_HOST.arch, x86_64):{
|
||||
message("Host is 64bit")
|
||||
...
|
||||
}
|
||||
#! [187]
|
||||
|
@ -1714,6 +1714,25 @@
|
||||
|
||||
See \l{Creating Frameworks} for more information about creating frameworks.
|
||||
|
||||
\target QMAKE_HOST
|
||||
\section1 QMAKE_HOST
|
||||
|
||||
Provides information about the host machine running qmake.
|
||||
For example, you can retrieve the host machine architecture from
|
||||
\c{QMAKE_HOST.arch}.
|
||||
|
||||
\table
|
||||
\header \li Keys \li Values
|
||||
\row \li .arch \li Host architecture
|
||||
\row \li .os \li Host OS
|
||||
\row \li .cpu_count \li Number of available cpus
|
||||
\row \li .name \li Host computer name
|
||||
\row \li .version \li Host OS version number
|
||||
\row \li .version_string \li Host OS version string
|
||||
\endtable
|
||||
|
||||
\snippet code/doc_src_qmake-manual.pro 187
|
||||
|
||||
\target QMAKE_INCDIR
|
||||
\section1 QMAKE_INCDIR
|
||||
|
||||
|
@ -1478,7 +1478,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
else
|
||||
warn_msg(WarnLogic, "Could not resolve Info.plist: '%s'. Check if QMAKE_INFO_PLIST points to a valid file.", plist.toLatin1().constData());
|
||||
} else {
|
||||
plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
|
||||
plist = fileFixify(specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"), FileFixifyBackwards);
|
||||
QFile plist_in_file(plist);
|
||||
if (plist_in_file.open(QIODevice::ReadOnly)) {
|
||||
QTextStream plist_in(&plist_in_file);
|
||||
@ -1505,7 +1505,11 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
QTextStream plist_out(&plist_out_file);
|
||||
plist_out << plist_in_text;
|
||||
t << "\t\t\t\t" << writeSettings("INFOPLIST_FILE", "Info.plist") << ";\n";
|
||||
} else {
|
||||
warn_msg(WarnLogic, "Could not write Info.plist: '%s'.", plist_out_file.fileName().toLatin1().constData());
|
||||
}
|
||||
} else {
|
||||
warn_msg(WarnLogic, "Could not open Info.plist: '%s'.", plist.toLatin1().constData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -817,7 +817,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
t << escapeDependencyPath(info_plist_out) << ": \n\t";
|
||||
info_plist_out = escapeFilePath(info_plist_out);
|
||||
if (!destdir.isEmpty())
|
||||
t << mkdir_p_asstring(destdir, false) << "\n\t";
|
||||
t << mkdir_p_asstring(destdir) << "\n\t";
|
||||
ProStringList commonSedArgs;
|
||||
if (!project->values("VERSION").isEmpty()) {
|
||||
commonSedArgs << "-e \"s,@SHORT_VERSION@," << project->first("VER_MAJ") << "."
|
||||
@ -839,6 +839,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
|
||||
bundleIdentifier.chop(4);
|
||||
if (bundleIdentifier.endsWith(".framework"))
|
||||
bundleIdentifier.chop(10);
|
||||
// replace invalid bundle id characters
|
||||
bundleIdentifier.replace('_', '-');
|
||||
commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" ";
|
||||
|
||||
if (!isFramework) {
|
||||
|
@ -643,7 +643,12 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
|
||||
<< tagValue("DefaultLanguage", "en")
|
||||
<< tagValue("AppContainerApplication", "true")
|
||||
<< tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store")
|
||||
<< tagValue("ApplicationTypeRevision", tool.SdkVersion == "10.0" ? "8.2" : tool.SdkVersion);
|
||||
<< tagValue("ApplicationTypeRevision", tool.SdkVersion);
|
||||
if (tool.SdkVersion == "10.0") {
|
||||
const QString ucrtVersion = qgetenv("UCRTVERSION");
|
||||
xml << tagValue("WindowsTargetPlatformVersion", ucrtVersion)
|
||||
<< tagValue("WindowsTargetPlatformMinVersion", ucrtVersion);
|
||||
}
|
||||
}
|
||||
|
||||
xml << closetag();
|
||||
|
@ -190,19 +190,24 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
|
||||
|
||||
incDirs << vcInstallDir + QStringLiteral("include");
|
||||
incDirs << vcInstallDir + QStringLiteral("atlmfc/include");
|
||||
// ### Investigate why VS uses 10056 first
|
||||
incDirs << kitDir + QStringLiteral("Include/10.0.10056.0/ucrt");
|
||||
incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/ucrt");
|
||||
incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/um");
|
||||
incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/shared");
|
||||
incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/winrt");
|
||||
|
||||
const QString crtVersion = qgetenv("UCRTVersion");
|
||||
if (crtVersion.isEmpty()) {
|
||||
fprintf(stderr, "Failed to access CRT version.\n");
|
||||
return false;
|
||||
}
|
||||
const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion;
|
||||
const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion;
|
||||
incDirs << crtInclude + QStringLiteral("/ucrt");
|
||||
incDirs << crtInclude + QStringLiteral("/um");
|
||||
incDirs << crtInclude + QStringLiteral("/shared");
|
||||
incDirs << crtInclude + QStringLiteral("/winrt");
|
||||
|
||||
libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch;
|
||||
libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch;
|
||||
// ### Investigate why VS uses 10056 first
|
||||
libDirs << kitDir + QStringLiteral("lib/10.0.10056.0/ucrt/") + arch;
|
||||
libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/ucrt/") + arch;
|
||||
libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/um/") + arch;
|
||||
|
||||
libDirs << crtLib + QStringLiteral("/ucrt/") + arch;
|
||||
libDirs << crtLib + QStringLiteral("/um/") + arch;
|
||||
} else if (isPhone) {
|
||||
QString sdkDir = vcInstallDir;
|
||||
if (!QDir(sdkDir).exists()) {
|
||||
|
@ -1307,7 +1307,8 @@ void VcprojGenerator::initDeploymentTool()
|
||||
}
|
||||
ProStringList dllPaths = project->values("QMAKE_DLL_PATHS");
|
||||
// Only deploy Qt libs for shared build
|
||||
if (!dllPaths.isEmpty()) {
|
||||
if (!dllPaths.isEmpty() &&
|
||||
!(conf.WinRT && project->first("MSVC_VER").toQString() == "14.0")) {
|
||||
// FIXME: This code should actually resolve the libraries from all Qt modules.
|
||||
ProStringList arg = project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE");
|
||||
for (ProStringList::ConstIterator it = arg.constBegin(); it != arg.constEnd(); ++it) {
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 121e4d1ad09bdbfeb8a871d4f2c3ffe1acb8e2d6 Mon Sep 17 00:00:00 2001
|
||||
From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||
Date: Tue, 30 Jun 2015 09:41:39 +0200
|
||||
Subject: [PATCH] Re-fix X86 Wince builds.
|
||||
|
||||
eebb8de21ce4845866f15e444a4c78fc2cbb7f3f fixed the PCRE
|
||||
build, but was accidentally overwritten by a subsequent
|
||||
import of the PCRE tarball.
|
||||
|
||||
Now put the same patch also into patches/ so that we don't
|
||||
forget it needs to be manually applied.
|
||||
|
||||
Change-Id: I93c2ee9c2e2dd1c48d391ce7e16d33208fb2cbbb
|
||||
---
|
||||
src/3rdparty/pcre/sljit/sljitNativeX86_common.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
|
||||
index 22a163f..21b276f 100644
|
||||
--- a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
|
||||
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
|
||||
@@ -273,7 +273,9 @@ static sljit_si cpu_has_sse2 = -1;
|
||||
#endif
|
||||
static sljit_si cpu_has_cmov = -1;
|
||||
|
||||
-#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
+#ifdef _WIN32_WCE
|
||||
+#include <cmnintrin.h>
|
||||
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
--
|
||||
1.9.1
|
||||
|
6
src/3rdparty/pcre/pcre.h
vendored
6
src/3rdparty/pcre/pcre.h
vendored
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE_MAJOR 8
|
||||
#define PCRE_MINOR 37
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2015-04-28
|
||||
#define PCRE_MINOR 38
|
||||
#define PCRE_PRERELEASE -RC1
|
||||
#define PCRE_DATE 2015-05-03
|
||||
|
||||
/* 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
|
||||
|
271
src/3rdparty/pcre/pcre_compile.c
vendored
271
src/3rdparty/pcre/pcre_compile.c
vendored
@ -174,7 +174,7 @@ static const short int escapes[] = {
|
||||
-ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
|
||||
CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
|
||||
CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
|
||||
CHAR_GRAVE_ACCENT, 7,
|
||||
CHAR_GRAVE_ACCENT, ESC_a,
|
||||
-ESC_b, 0,
|
||||
-ESC_d, ESC_e,
|
||||
ESC_f, 0,
|
||||
@ -202,9 +202,9 @@ static const short int escapes[] = {
|
||||
/* 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,
|
||||
/* 80 */ 0, ESC_a, -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,
|
||||
/* 90 */ 0, 0, -ESC_k, 0, 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,
|
||||
@ -219,6 +219,12 @@ static const short int escapes[] = {
|
||||
/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* We also need a table of characters that may follow \c in an EBCDIC
|
||||
environment for characters 0-31. */
|
||||
|
||||
static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -458,7 +464,7 @@ static const char error_texts[] =
|
||||
"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: invalid forward reference offset\0"
|
||||
"internal error: unexpected repeat\0"
|
||||
"unrecognized character after (? or (?-\0"
|
||||
"POSIX named classes are supported only within a class\0"
|
||||
@ -527,7 +533,11 @@ static const char error_texts[] =
|
||||
"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"
|
||||
#ifndef EBCDIC
|
||||
"\\c must be followed by an ASCII character\0"
|
||||
#else
|
||||
"\\c must be followed by a letter or one of [\\]^_?\0"
|
||||
#endif
|
||||
"\\k is not followed by a braced, angle-bracketed, or quoted name\0"
|
||||
/* 70 */
|
||||
"internal error: unknown opcode in find_fixedlength()\0"
|
||||
@ -1425,7 +1435,16 @@ else
|
||||
c ^= 0x40;
|
||||
#else /* EBCDIC coding */
|
||||
if (c >= CHAR_a && c <= CHAR_z) c += 64;
|
||||
c ^= 0xC0;
|
||||
if (c == CHAR_QUESTION_MARK)
|
||||
c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (c == ebcdic_escape_c[i]) break;
|
||||
}
|
||||
if (i < 32) c = i; else *errorcodeptr = ERR68;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1799,7 +1818,7 @@ for (;;)
|
||||
case OP_ASSERTBACK:
|
||||
case OP_ASSERTBACK_NOT:
|
||||
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
||||
cc += PRIV(OP_lengths)[*cc];
|
||||
cc += 1 + LINK_SIZE;
|
||||
break;
|
||||
|
||||
/* Skip over things that don't match chars */
|
||||
@ -2487,7 +2506,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
|
||||
if (c == OP_BRA || c == OP_BRAPOS ||
|
||||
c == OP_CBRA || c == OP_CBRAPOS ||
|
||||
c == OP_ONCE || c == OP_ONCE_NC ||
|
||||
c == OP_COND)
|
||||
c == OP_COND || c == OP_SCOND)
|
||||
{
|
||||
BOOL empty_branch;
|
||||
if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
|
||||
@ -3886,11 +3905,11 @@ 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 than not diagnosing bad classes when Perl does,
|
||||
I think.
|
||||
below handles the special cases \\ and \], 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 than 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
|
||||
@ -3917,21 +3936,16 @@ pcre_uchar terminator; /* Don't combine these lines; the Solaris cc */
|
||||
terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
|
||||
for (++ptr; *ptr != CHAR_NULL; ptr++)
|
||||
{
|
||||
if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
if (*ptr == CHAR_BACKSLASH &&
|
||||
(ptr[1] == CHAR_RIGHT_SQUARE_BRACKET ||
|
||||
ptr[1] == CHAR_BACKSLASH))
|
||||
ptr++;
|
||||
else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
|
||||
else
|
||||
else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
|
||||
*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
|
||||
else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
{
|
||||
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;
|
||||
*endptr = ptr;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
@ -3985,11 +3999,12 @@ 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).
|
||||
This function has been extended to cope with forward references for recursions
|
||||
and subroutine calls. It must 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 does not adjust the value in the reference
|
||||
(which is a group number). After the group has been scanned, all the offsets in
|
||||
the forward reference list for the group are adjusted.
|
||||
|
||||
Arguments:
|
||||
group points to the start of the group
|
||||
@ -4005,29 +4020,21 @@ static void
|
||||
adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
|
||||
size_t save_hwm_offset)
|
||||
{
|
||||
int offset;
|
||||
pcre_uchar *hc;
|
||||
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 = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
offset = (int)GET(hc, 0);
|
||||
if (cd->start_code + offset == ptr + 1)
|
||||
{
|
||||
PUT(hc, 0, offset + adjust);
|
||||
break;
|
||||
}
|
||||
if (cd->start_code + offset == ptr + 1) break;
|
||||
}
|
||||
|
||||
/* Otherwise, adjust the recursion offset if it's after the start of this
|
||||
group. */
|
||||
/* If we have not found this recursion on the forward reference list, adjust
|
||||
the recursion's offset if it's after the start of this group. */
|
||||
|
||||
if (hc >= cd->hwm)
|
||||
{
|
||||
@ -4037,6 +4044,15 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
|
||||
|
||||
ptr += 1 + LINK_SIZE;
|
||||
}
|
||||
|
||||
/* Now adjust all forward reference offsets for the group. */
|
||||
|
||||
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
offset = (int)GET(hc, 0);
|
||||
PUT(hc, 0, offset + adjust);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4465,7 +4481,7 @@ const pcre_uchar *tempptr;
|
||||
const pcre_uchar *nestptr = NULL;
|
||||
pcre_uchar *previous = NULL;
|
||||
pcre_uchar *previous_callout = NULL;
|
||||
size_t save_hwm_offset = 0;
|
||||
size_t item_hwm_offset = 0;
|
||||
pcre_uint8 classbits[32];
|
||||
|
||||
/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
|
||||
@ -4767,6 +4783,7 @@ for (;; ptr++)
|
||||
zeroreqchar = reqchar;
|
||||
zeroreqcharflags = reqcharflags;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
|
||||
break;
|
||||
|
||||
@ -4818,6 +4835,7 @@ for (;; ptr++)
|
||||
/* Handle a real character class. */
|
||||
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
|
||||
/* 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. */
|
||||
@ -5195,9 +5213,9 @@ for (;; ptr++)
|
||||
cd, PRIV(vspace_list));
|
||||
continue;
|
||||
|
||||
#ifdef SUPPORT_UCP
|
||||
case ESC_p:
|
||||
case ESC_P:
|
||||
#ifdef SUPPORT_UCP
|
||||
{
|
||||
BOOL negated;
|
||||
unsigned int ptype = 0, pdata = 0;
|
||||
@ -5211,6 +5229,9 @@ for (;; ptr++)
|
||||
class_has_8bitchar--; /* Undo! */
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
*errorcodeptr = ERR45;
|
||||
goto FAILED;
|
||||
#endif
|
||||
/* Unrecognized escapes are faulted if PCRE is running in its
|
||||
strict mode. By default, for compatibility with Perl, they are
|
||||
@ -5930,7 +5951,7 @@ for (;; ptr++)
|
||||
{
|
||||
register int i;
|
||||
int len = (int)(code - previous);
|
||||
size_t base_hwm_offset = save_hwm_offset;
|
||||
size_t base_hwm_offset = item_hwm_offset;
|
||||
pcre_uchar *bralink = NULL;
|
||||
pcre_uchar *brazeroptr = NULL;
|
||||
|
||||
@ -5985,7 +6006,7 @@ for (;; ptr++)
|
||||
if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
|
||||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(previous, 1, utf, cd, item_hwm_offset);
|
||||
memmove(previous + 1, previous, IN_UCHARS(len));
|
||||
code++;
|
||||
if (repeat_max == 0)
|
||||
@ -6009,7 +6030,7 @@ for (;; ptr++)
|
||||
{
|
||||
int offset;
|
||||
*code = OP_END;
|
||||
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
|
||||
code += 2 + LINK_SIZE;
|
||||
*previous++ = OP_BRAZERO + repeat_type;
|
||||
@ -6254,6 +6275,12 @@ for (;; ptr++)
|
||||
while (*scode == OP_ALT);
|
||||
}
|
||||
|
||||
/* A conditional group with only one branch has an implicit empty
|
||||
alternative branch. */
|
||||
|
||||
if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
|
||||
*bracode = OP_SCOND;
|
||||
|
||||
/* Handle possessive quantifiers. */
|
||||
|
||||
if (possessive_quantifier)
|
||||
@ -6267,11 +6294,11 @@ for (;; ptr++)
|
||||
{
|
||||
int nlen = (int)(code - bracode);
|
||||
*code = OP_END;
|
||||
adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
|
||||
code += 1 + LINK_SIZE;
|
||||
nlen += 1 + LINK_SIZE;
|
||||
*bracode = OP_BRAPOS;
|
||||
*bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
|
||||
*code++ = OP_KETRPOS;
|
||||
PUTINC(code, 0, nlen);
|
||||
PUT(bracode, 1, nlen);
|
||||
@ -6401,7 +6428,7 @@ for (;; ptr++)
|
||||
else
|
||||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
||||
code += 1 + LINK_SIZE;
|
||||
len += 1 + LINK_SIZE;
|
||||
@ -6450,7 +6477,7 @@ for (;; ptr++)
|
||||
|
||||
default:
|
||||
*code = OP_END;
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
||||
code += 1 + LINK_SIZE;
|
||||
len += 1 + LINK_SIZE;
|
||||
@ -6623,7 +6650,7 @@ for (;; ptr++)
|
||||
newoptions = options;
|
||||
skipbytes = 0;
|
||||
bravalue = OP_CBRA;
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
reset_bracount = FALSE;
|
||||
|
||||
/* Deal with the extended parentheses; all are introduced by '?', and the
|
||||
@ -6641,6 +6668,7 @@ for (;; ptr++)
|
||||
/* ------------------------------------------------------------ */
|
||||
case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
|
||||
reset_bracount = TRUE;
|
||||
cd->dupgroups = TRUE; /* Record (?| encountered */
|
||||
/* Fall through */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -6741,6 +6769,12 @@ for (;; ptr++)
|
||||
{
|
||||
while (IS_DIGIT(*ptr))
|
||||
{
|
||||
if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
||||
{
|
||||
while (IS_DIGIT(*ptr)) ptr++;
|
||||
*errorcodeptr = ERR61;
|
||||
goto FAILED;
|
||||
}
|
||||
recno = recno * 10 + (int)(*ptr - CHAR_0);
|
||||
ptr++;
|
||||
}
|
||||
@ -6769,7 +6803,7 @@ for (;; ptr++)
|
||||
ptr++;
|
||||
}
|
||||
namelen = (int)(ptr - name);
|
||||
if (lengthptr != NULL) *lengthptr += IMM2_SIZE;
|
||||
if (lengthptr != NULL) skipbytes += IMM2_SIZE;
|
||||
}
|
||||
|
||||
/* Check the terminator */
|
||||
@ -6875,6 +6909,11 @@ for (;; ptr++)
|
||||
*errorcodeptr = ERR15;
|
||||
goto FAILED;
|
||||
}
|
||||
if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
||||
{
|
||||
*errorcodeptr = ERR61;
|
||||
goto FAILED;
|
||||
}
|
||||
recno = recno * 10 + name[i] - CHAR_0;
|
||||
}
|
||||
if (recno == 0) recno = RREF_ANY;
|
||||
@ -7151,7 +7190,8 @@ for (;; ptr++)
|
||||
if (lengthptr != NULL)
|
||||
{
|
||||
named_group *ng;
|
||||
|
||||
recno = 0;
|
||||
|
||||
if (namelen == 0)
|
||||
{
|
||||
*errorcodeptr = ERR62;
|
||||
@ -7168,20 +7208,6 @@ for (;; ptr++)
|
||||
goto FAILED;
|
||||
}
|
||||
|
||||
/* The name table does not exist in the first pass; instead we must
|
||||
scan the list of names encountered so far in order to get the
|
||||
number. If the name is not found, set the value to 0 for a forward
|
||||
reference. */
|
||||
|
||||
ng = cd->named_groups;
|
||||
for (i = 0; i < cd->names_found; i++, ng++)
|
||||
{
|
||||
if (namelen == ng->length &&
|
||||
STRNCMP_UC_UC(name, ng->name, namelen) == 0)
|
||||
break;
|
||||
}
|
||||
recno = (i < cd->names_found)? ng->number : 0;
|
||||
|
||||
/* Count named back references. */
|
||||
|
||||
if (!is_recurse) cd->namedrefcount++;
|
||||
@ -7191,6 +7217,56 @@ for (;; ptr++)
|
||||
16-bit data item. */
|
||||
|
||||
*lengthptr += IMM2_SIZE;
|
||||
|
||||
/* If this is a forward reference and we are within a (?|...) group,
|
||||
the reference may end up as the number of a group which we are
|
||||
currently inside, that is, it could be a recursive reference. In the
|
||||
real compile this will be picked up and the reference wrapped with
|
||||
OP_ONCE to make it atomic, so we must space in case this occurs. */
|
||||
|
||||
/* In fact, this can happen for a non-forward reference because
|
||||
another group with the same number might be created later. This
|
||||
issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
|
||||
only mode, we finesse the bug by allowing more memory always. */
|
||||
|
||||
*lengthptr += 2 + 2*LINK_SIZE;
|
||||
|
||||
/* It is even worse than that. The current reference may be to an
|
||||
existing named group with a different number (so apparently not
|
||||
recursive) but which later on is also attached to a group with the
|
||||
current number. This can only happen if $(| has been previous
|
||||
encountered. In that case, we allow yet more memory, just in case.
|
||||
(Again, this is fixed "properly" in PCRE2. */
|
||||
|
||||
if (cd->dupgroups) *lengthptr += 4 + 4*LINK_SIZE;
|
||||
|
||||
/* Otherwise, check for recursion here. The name table does not exist
|
||||
in the first pass; instead we must scan the list of names encountered
|
||||
so far in order to get the number. If the name is not found, leave
|
||||
the value of recno as 0 for a forward reference. */
|
||||
|
||||
else
|
||||
{
|
||||
ng = cd->named_groups;
|
||||
for (i = 0; i < cd->names_found; i++, ng++)
|
||||
{
|
||||
if (namelen == ng->length &&
|
||||
STRNCMP_UC_UC(name, ng->name, namelen) == 0)
|
||||
{
|
||||
open_capitem *oc;
|
||||
recno = ng->number;
|
||||
if (is_recurse) break;
|
||||
for (oc = cd->open_caps; oc != NULL; oc = oc->next)
|
||||
{
|
||||
if (oc->number == recno)
|
||||
{
|
||||
oc->flag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In the real compile, search the name table. We check the name
|
||||
@ -7237,8 +7313,6 @@ for (;; ptr++)
|
||||
for (i++; i < cd->names_found; i++)
|
||||
{
|
||||
if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
|
||||
|
||||
|
||||
count++;
|
||||
cslot += cd->name_entry_size;
|
||||
}
|
||||
@ -7247,6 +7321,7 @@ for (;; ptr++)
|
||||
{
|
||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
|
||||
PUT2INC(code, 0, index);
|
||||
PUT2INC(code, 0, count);
|
||||
@ -7284,9 +7359,14 @@ for (;; ptr++)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
case CHAR_R: /* Recursion */
|
||||
ptr++; /* Same as (?0) */
|
||||
/* Fall through */
|
||||
case CHAR_R: /* Recursion, same as (?0) */
|
||||
recno = 0;
|
||||
if (*(++ptr) != CHAR_RIGHT_PARENTHESIS)
|
||||
{
|
||||
*errorcodeptr = ERR29;
|
||||
goto FAILED;
|
||||
}
|
||||
goto HANDLE_RECURSION;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -7323,7 +7403,15 @@ for (;; ptr++)
|
||||
|
||||
recno = 0;
|
||||
while(IS_DIGIT(*ptr))
|
||||
{
|
||||
if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
||||
{
|
||||
while (IS_DIGIT(*ptr)) ptr++;
|
||||
*errorcodeptr = ERR61;
|
||||
goto FAILED;
|
||||
}
|
||||
recno = recno * 10 + *ptr++ - CHAR_0;
|
||||
}
|
||||
|
||||
if (*ptr != (pcre_uchar)terminator)
|
||||
{
|
||||
@ -7360,6 +7448,7 @@ for (;; ptr++)
|
||||
HANDLE_RECURSION:
|
||||
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
called = cd->start_code;
|
||||
|
||||
/* When we are actually compiling, find the bracket that is being
|
||||
@ -7561,7 +7650,11 @@ for (;; ptr++)
|
||||
previous = NULL;
|
||||
cd->iscondassert = FALSE;
|
||||
}
|
||||
else previous = code;
|
||||
else
|
||||
{
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
}
|
||||
|
||||
*code = bravalue;
|
||||
tempcode = code;
|
||||
@ -7809,7 +7902,7 @@ for (;; ptr++)
|
||||
const pcre_uchar *p;
|
||||
pcre_uint32 cf;
|
||||
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
||||
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
||||
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
|
||||
|
||||
@ -7838,7 +7931,7 @@ for (;; ptr++)
|
||||
if (*p != (pcre_uchar)terminator)
|
||||
{
|
||||
*errorcodeptr = ERR57;
|
||||
break;
|
||||
goto FAILED;
|
||||
}
|
||||
ptr++;
|
||||
goto HANDLE_NUMERICAL_RECURSION;
|
||||
@ -7853,7 +7946,7 @@ for (;; ptr++)
|
||||
ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
|
||||
{
|
||||
*errorcodeptr = ERR69;
|
||||
break;
|
||||
goto FAILED;
|
||||
}
|
||||
is_recurse = FALSE;
|
||||
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
||||
@ -7877,6 +7970,7 @@ for (;; ptr++)
|
||||
HANDLE_REFERENCE:
|
||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
||||
PUT2INC(code, 0, recno);
|
||||
cd->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||
@ -7906,6 +8000,7 @@ for (;; ptr++)
|
||||
if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr))
|
||||
goto FAILED;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
|
||||
*code++ = ptype;
|
||||
*code++ = pdata;
|
||||
@ -7946,6 +8041,7 @@ for (;; ptr++)
|
||||
|
||||
{
|
||||
previous = (escape > ESC_b && escape < ESC_Z)? code : NULL;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape;
|
||||
}
|
||||
}
|
||||
@ -7989,6 +8085,7 @@ for (;; ptr++)
|
||||
|
||||
ONE_CHAR:
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
|
||||
/* For caseless UTF-8 mode when UCP support is available, check whether
|
||||
this character has more than one other case. If so, generate a special
|
||||
@ -9164,6 +9261,7 @@ cd->names_found = 0;
|
||||
cd->name_entry_size = 0;
|
||||
cd->name_table = NULL;
|
||||
cd->dupnames = FALSE;
|
||||
cd->dupgroups = FALSE;
|
||||
cd->namedrefcount = 0;
|
||||
cd->start_code = cworkspace;
|
||||
cd->hwm = cworkspace;
|
||||
@ -9198,7 +9296,7 @@ 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;
|
||||
@ -9336,6 +9434,16 @@ if (cd->hwm > cd->start_workspace)
|
||||
int offset, recno;
|
||||
cd->hwm -= LINK_SIZE;
|
||||
offset = GET(cd->hwm, 0);
|
||||
|
||||
/* Check that the hwm handling hasn't gone wrong. This whole area is
|
||||
rewritten in PCRE2 because there are some obscure cases. */
|
||||
|
||||
if (offset == 0 || codestart[offset-1] != OP_RECURSE)
|
||||
{
|
||||
errorcode = ERR10;
|
||||
break;
|
||||
}
|
||||
|
||||
recno = GET(codestart, offset);
|
||||
if (recno != prev_recno)
|
||||
{
|
||||
@ -9366,7 +9474,7 @@ used in this code because at least one compiler gives a warning about loss of
|
||||
"const" attribute if the cast (pcre_uchar *)codestart is used directly in the
|
||||
function call. */
|
||||
|
||||
if ((options & PCRE_NO_AUTO_POSSESS) == 0)
|
||||
if (errorcode == 0 && (options & PCRE_NO_AUTO_POSSESS) == 0)
|
||||
{
|
||||
pcre_uchar *temp = (pcre_uchar *)codestart;
|
||||
auto_possessify(temp, utf, cd);
|
||||
@ -9380,7 +9488,7 @@ 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)
|
||||
if (errorcode == 0 && cd->check_lookbehind)
|
||||
{
|
||||
pcre_uchar *cc = (pcre_uchar *)codestart;
|
||||
|
||||
@ -9593,4 +9701,3 @@ return (pcre32 *)re;
|
||||
}
|
||||
|
||||
/* End of pcre_compile.c */
|
||||
|
||||
|
3
src/3rdparty/pcre/pcre_exec.c
vendored
3
src/3rdparty/pcre/pcre_exec.c
vendored
@ -6685,7 +6685,8 @@ if (md->offset_vector != NULL)
|
||||
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;
|
||||
if (offsetcount > 0) md->offset_vector[0] = -1;
|
||||
if (offsetcount > 1) md->offset_vector[1] = -1;
|
||||
}
|
||||
|
||||
/* Set up the first character to match, if available. The first_char value is
|
||||
|
17
src/3rdparty/pcre/pcre_internal.h
vendored
17
src/3rdparty/pcre/pcre_internal.h
vendored
@ -984,7 +984,7 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
|
||||
#ifndef EBCDIC
|
||||
|
||||
#define HSPACE_LIST \
|
||||
CHAR_HT, CHAR_SPACE, 0xa0, \
|
||||
CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
|
||||
0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
|
||||
0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
|
||||
NOTACHAR
|
||||
@ -1010,7 +1010,7 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
|
||||
#define HSPACE_BYTE_CASES \
|
||||
case CHAR_HT: \
|
||||
case CHAR_SPACE: \
|
||||
case 0xa0 /* NBSP */
|
||||
case CHAR_NBSP
|
||||
|
||||
#define HSPACE_CASES \
|
||||
HSPACE_BYTE_CASES: \
|
||||
@ -1037,11 +1037,12 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
|
||||
/* ------ EBCDIC environments ------ */
|
||||
|
||||
#else
|
||||
#define HSPACE_LIST CHAR_HT, CHAR_SPACE
|
||||
#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR
|
||||
|
||||
#define HSPACE_BYTE_CASES \
|
||||
case CHAR_HT: \
|
||||
case CHAR_SPACE
|
||||
case CHAR_SPACE: \
|
||||
case CHAR_NBSP
|
||||
|
||||
#define HSPACE_CASES HSPACE_BYTE_CASES
|
||||
|
||||
@ -1215,6 +1216,7 @@ same code point. */
|
||||
|
||||
#define CHAR_ESC '\047'
|
||||
#define CHAR_DEL '\007'
|
||||
#define CHAR_NBSP '\x41'
|
||||
#define STR_ESC "\047"
|
||||
#define STR_DEL "\007"
|
||||
|
||||
@ -1229,6 +1231,7 @@ a positive value. */
|
||||
#define CHAR_NEL ((unsigned char)'\x85')
|
||||
#define CHAR_ESC '\033'
|
||||
#define CHAR_DEL '\177'
|
||||
#define CHAR_NBSP ((unsigned char)'\xa0')
|
||||
|
||||
#define STR_LF "\n"
|
||||
#define STR_NL STR_LF
|
||||
@ -1606,6 +1609,7 @@ only. */
|
||||
#define CHAR_VERTICAL_LINE '\174'
|
||||
#define CHAR_RIGHT_CURLY_BRACKET '\175'
|
||||
#define CHAR_TILDE '\176'
|
||||
#define CHAR_NBSP ((unsigned char)'\xa0')
|
||||
|
||||
#define STR_HT "\011"
|
||||
#define STR_VT "\013"
|
||||
@ -1762,6 +1766,10 @@ only. */
|
||||
|
||||
/* Escape items that are just an encoding of a particular data value. */
|
||||
|
||||
#ifndef ESC_a
|
||||
#define ESC_a CHAR_BEL
|
||||
#endif
|
||||
|
||||
#ifndef ESC_e
|
||||
#define ESC_e CHAR_ESC
|
||||
#endif
|
||||
@ -2446,6 +2454,7 @@ typedef struct compile_data {
|
||||
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
|
||||
BOOL check_lookbehind; /* Lookbehinds need later checking */
|
||||
BOOL dupnames; /* Duplicate names exist */
|
||||
BOOL dupgroups; /* Duplicate groups exist: (?| found */
|
||||
BOOL iscondassert; /* Next assert is a condition */
|
||||
int nltype; /* Newline type */
|
||||
int nllen; /* Newline string length */
|
||||
|
58
src/3rdparty/pcre/pcre_jit_compile.c
vendored
58
src/3rdparty/pcre/pcre_jit_compile.c
vendored
@ -1064,6 +1064,7 @@ pcre_uchar *alternative;
|
||||
pcre_uchar *end = NULL;
|
||||
int private_data_ptr = *private_data_start;
|
||||
int space, size, bracketlen;
|
||||
BOOL repeat_check = TRUE;
|
||||
|
||||
while (cc < ccend)
|
||||
{
|
||||
@ -1071,9 +1072,10 @@ while (cc < ccend)
|
||||
size = 0;
|
||||
bracketlen = 0;
|
||||
if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
|
||||
return;
|
||||
break;
|
||||
|
||||
if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
|
||||
if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
|
||||
{
|
||||
if (detect_repeat(common, cc))
|
||||
{
|
||||
/* These brackets are converted to repeats, so no global
|
||||
@ -1081,6 +1083,8 @@ while (cc < ccend)
|
||||
if (cc >= end)
|
||||
end = bracketend(cc);
|
||||
}
|
||||
}
|
||||
repeat_check = TRUE;
|
||||
|
||||
switch(*cc)
|
||||
{
|
||||
@ -1136,6 +1140,13 @@ while (cc < ccend)
|
||||
bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_BRAZERO:
|
||||
case OP_BRAMINZERO:
|
||||
case OP_BRAPOSZERO:
|
||||
repeat_check = FALSE;
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
CASE_ITERATOR_PRIVATE_DATA_1
|
||||
space = 1;
|
||||
size = -2;
|
||||
@ -1162,12 +1173,17 @@ while (cc < ccend)
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
|
||||
case OP_TYPEUPTO:
|
||||
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
|
||||
space = 2;
|
||||
size = 1 + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_TYPEMINUPTO:
|
||||
space = 2;
|
||||
size = 1 + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_CLASS:
|
||||
case OP_NCLASS:
|
||||
size += 1 + 32 / sizeof(pcre_uchar);
|
||||
@ -1316,6 +1332,13 @@ while (cc < ccend)
|
||||
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_THEN:
|
||||
stack_restore = TRUE;
|
||||
if (common->control_head_ptr != 0)
|
||||
*needs_control_head = TRUE;
|
||||
cc ++;
|
||||
break;
|
||||
|
||||
default:
|
||||
stack_restore = TRUE;
|
||||
/* Fall through. */
|
||||
@ -2220,6 +2243,7 @@ while (current != NULL)
|
||||
SLJIT_ASSERT_STOP();
|
||||
break;
|
||||
}
|
||||
SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
|
||||
current = (sljit_sw*)current[-1];
|
||||
}
|
||||
return -1;
|
||||
@ -3209,7 +3233,7 @@ bytes[len] = byte;
|
||||
bytes[0] = len;
|
||||
}
|
||||
|
||||
static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)
|
||||
static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count)
|
||||
{
|
||||
/* Recursive function, which scans prefix literals. */
|
||||
BOOL last, any, caseless;
|
||||
@ -3227,9 +3251,14 @@ pcre_uchar othercase[1];
|
||||
repeat = 1;
|
||||
while (TRUE)
|
||||
{
|
||||
if (*rec_count == 0)
|
||||
return 0;
|
||||
(*rec_count)--;
|
||||
|
||||
last = TRUE;
|
||||
any = FALSE;
|
||||
caseless = FALSE;
|
||||
|
||||
switch (*cc)
|
||||
{
|
||||
case OP_CHARI:
|
||||
@ -3291,7 +3320,7 @@ while (TRUE)
|
||||
#ifdef SUPPORT_UTF
|
||||
if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
|
||||
#endif
|
||||
max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);
|
||||
max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
|
||||
if (max_chars == 0)
|
||||
return consumed;
|
||||
last = FALSE;
|
||||
@ -3314,7 +3343,7 @@ while (TRUE)
|
||||
alternative = cc + GET(cc, 1);
|
||||
while (*alternative == OP_ALT)
|
||||
{
|
||||
max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);
|
||||
max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
|
||||
if (max_chars == 0)
|
||||
return consumed;
|
||||
alternative += GET(alternative, 1);
|
||||
@ -3556,6 +3585,7 @@ int i, max, from;
|
||||
int range_right = -1, range_len = 3 - 1;
|
||||
sljit_ub *update_table = NULL;
|
||||
BOOL in_range;
|
||||
pcre_uint32 rec_count;
|
||||
|
||||
for (i = 0; i < MAX_N_CHARS; i++)
|
||||
{
|
||||
@ -3564,7 +3594,8 @@ for (i = 0; i < MAX_N_CHARS; i++)
|
||||
bytes[i * MAX_N_BYTES] = 0;
|
||||
}
|
||||
|
||||
max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);
|
||||
rec_count = 10000;
|
||||
max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);
|
||||
|
||||
if (max <= 1)
|
||||
return FALSE;
|
||||
@ -7665,6 +7696,10 @@ while (*cc != OP_KETRPOS)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
|
||||
}
|
||||
|
||||
/* Even if the match is empty, we need to reset the control head. */
|
||||
if (needs_control_head)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
||||
|
||||
if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
|
||||
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
|
||||
|
||||
@ -7692,6 +7727,10 @@ while (*cc != OP_KETRPOS)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
|
||||
}
|
||||
|
||||
/* Even if the match is empty, we need to reset the control head. */
|
||||
if (needs_control_head)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
||||
|
||||
if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
|
||||
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
|
||||
|
||||
@ -7704,9 +7743,6 @@ while (*cc != OP_KETRPOS)
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_control_head)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
||||
|
||||
JUMPTO(SLJIT_JUMP, loop);
|
||||
flush_stubs(common);
|
||||
|
||||
@ -9648,6 +9684,7 @@ set_jumps(common->currententry->calls, common->currententry->entry);
|
||||
|
||||
sljit_emit_fast_enter(compiler, TMP2, 0);
|
||||
allocate_stack(common, private_data_size + framesize + alternativesize);
|
||||
count_match(common);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
|
||||
copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
|
||||
if (needs_control_head)
|
||||
@ -9992,6 +10029,7 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
||||
|
||||
if (mode == JIT_PARTIAL_SOFT_COMPILE)
|
||||
|
19
src/3rdparty/pcre/pcre_study.c
vendored
19
src/3rdparty/pcre/pcre_study.c
vendored
@ -71,6 +71,7 @@ Arguments:
|
||||
startcode pointer to start of the whole pattern's code
|
||||
options the compiling options
|
||||
recurses chain of recurse_check to catch mutual recursion
|
||||
countptr pointer to call count (to catch over complexity)
|
||||
|
||||
Returns: the minimum length
|
||||
-1 if \C in UTF-8 mode or (*ACCEPT) was encountered
|
||||
@ -80,7 +81,8 @@ Returns: the minimum length
|
||||
|
||||
static int
|
||||
find_minlength(const REAL_PCRE *re, const pcre_uchar *code,
|
||||
const pcre_uchar *startcode, int options, recurse_check *recurses)
|
||||
const pcre_uchar *startcode, int options, recurse_check *recurses,
|
||||
int *countptr)
|
||||
{
|
||||
int length = -1;
|
||||
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
|
||||
@ -90,6 +92,8 @@ recurse_check this_recurse;
|
||||
register int branchlength = 0;
|
||||
register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
|
||||
|
||||
if ((*countptr)++ > 1000) return -1; /* too complex */
|
||||
|
||||
if (*code == OP_CBRA || *code == OP_SCBRA ||
|
||||
*code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
|
||||
|
||||
@ -131,7 +135,7 @@ for (;;)
|
||||
case OP_SBRAPOS:
|
||||
case OP_ONCE:
|
||||
case OP_ONCE_NC:
|
||||
d = find_minlength(re, cc, startcode, options, recurses);
|
||||
d = find_minlength(re, cc, startcode, options, recurses, countptr);
|
||||
if (d < 0) return d;
|
||||
branchlength += d;
|
||||
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
||||
@ -415,7 +419,8 @@ for (;;)
|
||||
int dd;
|
||||
this_recurse.prev = recurses;
|
||||
this_recurse.group = cs;
|
||||
dd = find_minlength(re, cs, startcode, options, &this_recurse);
|
||||
dd = find_minlength(re, cs, startcode, options, &this_recurse,
|
||||
countptr);
|
||||
if (dd < d) d = dd;
|
||||
}
|
||||
}
|
||||
@ -451,7 +456,8 @@ for (;;)
|
||||
{
|
||||
this_recurse.prev = recurses;
|
||||
this_recurse.group = cs;
|
||||
d = find_minlength(re, cs, startcode, options, &this_recurse);
|
||||
d = find_minlength(re, cs, startcode, options, &this_recurse,
|
||||
countptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -514,7 +520,7 @@ for (;;)
|
||||
this_recurse.prev = recurses;
|
||||
this_recurse.group = cs;
|
||||
branchlength += find_minlength(re, cs, startcode, options,
|
||||
&this_recurse);
|
||||
&this_recurse, countptr);
|
||||
}
|
||||
}
|
||||
cc += 1 + LINK_SIZE;
|
||||
@ -1453,6 +1459,7 @@ pcre32_study(const pcre32 *external_re, int options, const char **errorptr)
|
||||
#endif
|
||||
{
|
||||
int min;
|
||||
int count = 0;
|
||||
BOOL bits_set = FALSE;
|
||||
pcre_uint8 start_bits[32];
|
||||
PUBL(extra) *extra = NULL;
|
||||
@ -1539,7 +1546,7 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
|
||||
|
||||
/* Find the minimum length of subject string. */
|
||||
|
||||
switch(min = find_minlength(re, code, code, re->options, NULL))
|
||||
switch(min = find_minlength(re, code, code, re->options, NULL, &count))
|
||||
{
|
||||
case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
|
||||
case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
|
||||
|
9
src/3rdparty/pcre/sljit/sljitConfig.h
vendored
9
src/3rdparty/pcre/sljit/sljitConfig.h
vendored
@ -96,6 +96,15 @@
|
||||
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
||||
#endif
|
||||
|
||||
/* Force cdecl calling convention even if a better calling
|
||||
convention (e.g. fastcall) is supported by the C compiler.
|
||||
If this option is enabled, C functions without
|
||||
SLJIT_CALL can also be called from JIT code. */
|
||||
#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
|
||||
/* Disabled by default */
|
||||
#define SLJIT_USE_CDECL_CALLING_CONVENTION 0
|
||||
#endif
|
||||
|
||||
/* Return with error when an invalid argument is passed. */
|
||||
#ifndef SLJIT_ARGUMENT_CHECKS
|
||||
/* Disabled by default */
|
||||
|
13
src/3rdparty/pcre/sljit/sljitConfigInternal.h
vendored
13
src/3rdparty/pcre/sljit/sljitConfigInternal.h
vendored
@ -468,7 +468,12 @@ typedef double sljit_d;
|
||||
|
||||
#ifndef SLJIT_CALL
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
|
||||
|
||||
/* Force cdecl. */
|
||||
#define SLJIT_CALL
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
@ -608,6 +613,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 10
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 0
|
||||
|
10
src/3rdparty/pcre/sljit/sljitLir.c
vendored
10
src/3rdparty/pcre/sljit/sljitLir.c
vendored
@ -845,8 +845,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp
|
||||
}
|
||||
|
||||
static SLJIT_CONST char* op0_names[] = {
|
||||
(char*)"breakpoint", (char*)"nop",
|
||||
(char*)"lumul", (char*)"lsmul", (char*)"ludiv", (char*)"lsdiv",
|
||||
(char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul",
|
||||
(char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi"
|
||||
};
|
||||
|
||||
static SLJIT_CONST char* op1_names[] = {
|
||||
@ -1036,7 +1036,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL)
|
||||
|| ((op & ~SLJIT_INT_OP) >= SLJIT_LUDIV && (op & ~SLJIT_INT_OP) <= SLJIT_LSDIV));
|
||||
|| ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI));
|
||||
CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
@ -1447,6 +1447,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(offset);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_DST(dst, dstw);
|
||||
#endif
|
||||
@ -1462,6 +1464,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(init_value);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_DST(dst, dstw);
|
||||
#endif
|
||||
|
40
src/3rdparty/pcre/sljit/sljitLir.h
vendored
40
src/3rdparty/pcre/sljit/sljitLir.h
vendored
@ -687,7 +687,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
#define SLJIT_OP0_BASE 0
|
||||
|
||||
/* Flags: - (never set any flags)
|
||||
Note: breakpoint instruction is not supported by all architectures (namely ppc)
|
||||
Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
|
||||
It falls back to SLJIT_NOP in those cases. */
|
||||
#define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
|
||||
/* Flags: - (never set any flags)
|
||||
@ -696,24 +696,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
#define SLJIT_NOP (SLJIT_OP0_BASE + 1)
|
||||
/* Flags: - (may destroy flags)
|
||||
Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2)
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
||||
Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_LUDIV (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_ILUDIV (SLJIT_LUDIV | SLJIT_INT_OP)
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
||||
#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
||||
Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_LSDIV (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_ILSDIV (SLJIT_LSDIV | SLJIT_INT_OP)
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: SLJIT_SDIV is single precision divide. */
|
||||
#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6)
|
||||
#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined.
|
||||
Note: SLJIT_SDIV is single precision divide. */
|
||||
#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7)
|
||||
#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
|
||||
|
||||
|
27
src/3rdparty/pcre/sljit/sljitNativeARM_32.c
vendored
27
src/3rdparty/pcre/sljit/sljitNativeARM_32.c
vendored
@ -1833,18 +1833,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
| (reg_map[SLJIT_R0] << 8)
|
||||
| reg_map[TMP_REG1]);
|
||||
#endif
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
if (compiler->scratches >= 3)
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping);
|
||||
|
||||
if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) {
|
||||
FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */));
|
||||
FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */));
|
||||
}
|
||||
else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3))
|
||||
FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */));
|
||||
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
(op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
if (compiler->scratches >= 3)
|
||||
return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */);
|
||||
|
||||
if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) {
|
||||
FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */));
|
||||
FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */));
|
||||
}
|
||||
else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3))
|
||||
return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
48
src/3rdparty/pcre/sljit/sljitNativeARM_64.c
vendored
48
src/3rdparty/pcre/sljit/sljitNativeARM_64.c
vendored
@ -1087,14 +1087,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
saved_regs_size += sizeof(sljit_sw);
|
||||
}
|
||||
local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
|
||||
FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
||||
if (saved_regs_size > 0)
|
||||
FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
||||
}
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
prev = -1;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1104,7 +1110,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1112,8 +1123,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
if (prev != -1)
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
||||
SLJIT_ASSERT(prev == -1);
|
||||
|
||||
if (compiler->local_size > (63 * sizeof(sljit_sw))) {
|
||||
/* The local_size is already adjusted by the saved registers. */
|
||||
@ -1188,7 +1198,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
prev = -1;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1198,7 +1213,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
|
||||
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1206,13 +1226,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
if (prev != -1)
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
||||
SLJIT_ASSERT(prev == -1);
|
||||
|
||||
if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
|
||||
FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
|
||||
| RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
|
||||
} else {
|
||||
} else if (saved_regs_size > 0) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
||||
}
|
||||
|
||||
@ -1242,12 +1261,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_LUDIV ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
58
src/3rdparty/pcre/sljit/sljitNativeARM_T2_32.c
vendored
58
src/3rdparty/pcre/sljit/sljitNativeARM_T2_32.c
vendored
@ -1239,6 +1239,9 @@ extern int __aeabi_idivmod(int numerator, int denominator);
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
{
|
||||
sljit_sw saved_reg_list[3];
|
||||
sljit_sw saved_reg_count;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
@ -1255,24 +1258,53 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 16)
|
||||
| reg_map[SLJIT_R1]);
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
if (compiler->scratches >= 4) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
|
||||
FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
|
||||
} else if (compiler->scratches >= 3)
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping);
|
||||
|
||||
saved_reg_count = 0;
|
||||
if (compiler->scratches >= 4)
|
||||
saved_reg_list[saved_reg_count++] = 12;
|
||||
if (compiler->scratches >= 3)
|
||||
saved_reg_list[saved_reg_count++] = 2;
|
||||
if (op >= SLJIT_UDIVI)
|
||||
saved_reg_list[saved_reg_count++] = 1;
|
||||
|
||||
if (saved_reg_count > 0) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)
|
||||
| (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
|
||||
if (saved_reg_count >= 2) {
|
||||
SLJIT_ASSERT(saved_reg_list[1] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));
|
||||
}
|
||||
if (saved_reg_count >= 3) {
|
||||
SLJIT_ASSERT(saved_reg_list[2] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
(op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
if (compiler->scratches >= 4) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */));
|
||||
return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */);
|
||||
} else if (compiler->scratches >= 3)
|
||||
return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */);
|
||||
|
||||
if (saved_reg_count > 0) {
|
||||
if (saved_reg_count >= 3) {
|
||||
SLJIT_ASSERT(saved_reg_list[2] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));
|
||||
}
|
||||
if (saved_reg_count >= 2) {
|
||||
SLJIT_ASSERT(saved_reg_list[1] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));
|
||||
}
|
||||
return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)
|
||||
| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
15
src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
vendored
15
src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
vendored
@ -1053,8 +1053,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
#endif
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
@ -1062,15 +1065,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (int_op)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#endif
|
||||
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
23
src/3rdparty/pcre/sljit/sljitNativePPC_common.c
vendored
23
src/3rdparty/pcre/sljit/sljitNativePPC_common.c
vendored
@ -1267,22 +1267,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
|
||||
#endif
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
if (int_op) {
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
} else {
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVDU : DIVD) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
}
|
||||
return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
|
||||
FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
||||
#endif
|
||||
return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
|
||||
#else
|
||||
return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -777,20 +777,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
if (op == SLJIT_LUDIV)
|
||||
if ((op | 0x2) == SLJIT_UDIVI)
|
||||
FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
if (op <= SLJIT_SDIVMOD)
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
if (op >= SLJIT_UDIVI)
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
|
311
src/3rdparty/pcre/sljit/sljitNativeTILEGX_64.c
vendored
311
src/3rdparty/pcre/sljit/sljitNativeTILEGX_64.c
vendored
@ -35,21 +35,21 @@
|
||||
#define SIMM_16BIT_MIN (-0x8000)
|
||||
#define SIMM_17BIT_MAX (0xffff)
|
||||
#define SIMM_17BIT_MIN (-0x10000)
|
||||
#define SIMM_32BIT_MIN (-0x80000000)
|
||||
#define SIMM_32BIT_MAX (0x7fffffff)
|
||||
#define SIMM_48BIT_MIN (0x800000000000L)
|
||||
#define SIMM_32BIT_MIN (-0x7fffffff - 1)
|
||||
#define SIMM_48BIT_MAX (0x7fffffff0000L)
|
||||
#define SIMM_48BIT_MIN (-0x800000000000L)
|
||||
#define IMM16(imm) ((imm) & 0xffff)
|
||||
|
||||
#define UIMM_16BIT_MAX (0xffff)
|
||||
|
||||
#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
||||
#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
||||
#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
||||
#define ADDR_TMP (SLJIT_NO_REGISTERS + 4)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
#define PIC_ADDR_REG TMP_REG2
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7
|
||||
};
|
||||
|
||||
@ -58,11 +58,6 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
||||
#define TMP_REG2_mapped 16
|
||||
#define TMP_REG3_mapped 6
|
||||
#define ADDR_TMP_mapped 7
|
||||
#define SLJIT_SAVED_REG1_mapped 30
|
||||
#define SLJIT_SAVED_REG2_mapped 31
|
||||
#define SLJIT_SAVED_REG3_mapped 32
|
||||
#define SLJIT_SAVED_EREG1_mapped 33
|
||||
#define SLJIT_SAVED_EREG2_mapped 34
|
||||
|
||||
/* Flags are keept in volatile registers. */
|
||||
#define EQUAL_FLAG 8
|
||||
@ -399,6 +394,9 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
|
||||
#define SUB(dst, srca, srcb) \
|
||||
push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)
|
||||
|
||||
#define MUL(dst, srca, srcb) \
|
||||
push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__)
|
||||
|
||||
#define NOR(dst, srca, srcb) \
|
||||
push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)
|
||||
|
||||
@ -547,8 +545,8 @@ const struct Format* compute_format()
|
||||
|
||||
const struct Format* match = NULL;
|
||||
const struct Format *b = NULL;
|
||||
unsigned int i = 0;
|
||||
for (i; i < sizeof formats / sizeof formats[0]; i++) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof formats / sizeof formats[0]; i++) {
|
||||
b = &formats[i];
|
||||
if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {
|
||||
match = b;
|
||||
@ -625,7 +623,6 @@ tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst)
|
||||
|
||||
static sljit_si update_buffer(struct sljit_compiler *compiler)
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
int orig_index = inst_buf_index;
|
||||
struct jit_instr inst0 = inst_buf[0];
|
||||
@ -738,8 +735,10 @@ static sljit_si update_buffer(struct sljit_compiler *compiler)
|
||||
|
||||
static sljit_si flush_buffer(struct sljit_compiler *compiler)
|
||||
{
|
||||
while (inst_buf_index != 0)
|
||||
update_buffer(compiler);
|
||||
while (inst_buf_index != 0) {
|
||||
FAIL_IF(update_buffer(compiler));
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)
|
||||
@ -787,6 +786,7 @@ static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o
|
||||
case TILEGX_OPC_ADD:
|
||||
case TILEGX_OPC_AND:
|
||||
case TILEGX_OPC_SUB:
|
||||
case TILEGX_OPC_MULX:
|
||||
case TILEGX_OPC_OR:
|
||||
case TILEGX_OPC_XOR:
|
||||
case TILEGX_OPC_NOR:
|
||||
@ -905,7 +905,6 @@ static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_
|
||||
sljit_sw diff;
|
||||
sljit_uw target_addr;
|
||||
sljit_ins *inst;
|
||||
sljit_ins saved_inst;
|
||||
|
||||
if (jump->flags & SLJIT_REWRITABLE_JUMP)
|
||||
return code_ptr;
|
||||
@ -1009,7 +1008,7 @@ SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compi
|
||||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_generate_code(compiler);
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
@ -1178,13 +1177,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_ins base;
|
||||
sljit_ins bundle = 0;
|
||||
|
||||
sljit_si i, tmp;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += (saveds + 1) * sizeof(sljit_sw);
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
local_size = (local_size + 7) & ~7;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
@ -1200,56 +1199,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
local_size = 0;
|
||||
}
|
||||
|
||||
/* Save the return address. */
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));
|
||||
|
||||
if (saveds >= 1)
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG1_mapped, -8));
|
||||
/* Save the S registers. */
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
|
||||
}
|
||||
|
||||
if (saveds >= 2)
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG2_mapped, -8));
|
||||
/* Save the R registers that need to be reserved. */
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
|
||||
}
|
||||
|
||||
if (saveds >= 3)
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG3_mapped, -8));
|
||||
|
||||
if (saveds >= 4)
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG1_mapped, -8));
|
||||
|
||||
if (saveds >= 5)
|
||||
FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG2_mapped, -8));
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(ADD(SLJIT_SAVED_REG1_mapped, 0, ZERO));
|
||||
|
||||
if (args >= 2)
|
||||
FAIL_IF(ADD(SLJIT_SAVED_REG2_mapped, 1, ZERO));
|
||||
|
||||
if (args >= 3)
|
||||
FAIL_IF(ADD(SLJIT_SAVED_REG3_mapped, 2, ZERO));
|
||||
/* Move the arguments to S registers. */
|
||||
for (i = 0; i < args; i++) {
|
||||
FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += (saveds + 1) * sizeof(sljit_sw);
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
compiler->local_size = (local_size + 7) & ~7;
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si local_size;
|
||||
sljit_ins base;
|
||||
int addr_initialized = 0;
|
||||
sljit_si i, tmp;
|
||||
sljit_si saveds;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
@ -1263,50 +1258,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
local_size = 0;
|
||||
}
|
||||
|
||||
/* Restore the return address. */
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
|
||||
FAIL_IF(LD(RA, ADDR_TMP_mapped));
|
||||
FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8));
|
||||
|
||||
if (compiler->saveds >= 5) {
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 48));
|
||||
addr_initialized = 1;
|
||||
|
||||
FAIL_IF(LD_ADD(SLJIT_SAVED_EREG2_mapped, ADDR_TMP_mapped, 8));
|
||||
/* Restore the S registers. */
|
||||
saveds = compiler->saveds;
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
|
||||
}
|
||||
|
||||
if (compiler->saveds >= 4) {
|
||||
if (addr_initialized == 0) {
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 40));
|
||||
addr_initialized = 1;
|
||||
}
|
||||
|
||||
FAIL_IF(LD_ADD(SLJIT_SAVED_EREG1_mapped, ADDR_TMP_mapped, 8));
|
||||
}
|
||||
|
||||
if (compiler->saveds >= 3) {
|
||||
if (addr_initialized == 0) {
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 32));
|
||||
addr_initialized = 1;
|
||||
}
|
||||
|
||||
FAIL_IF(LD_ADD(SLJIT_SAVED_REG3_mapped, ADDR_TMP_mapped, 8));
|
||||
}
|
||||
|
||||
if (compiler->saveds >= 2) {
|
||||
if (addr_initialized == 0) {
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 24));
|
||||
addr_initialized = 1;
|
||||
}
|
||||
|
||||
FAIL_IF(LD_ADD(SLJIT_SAVED_REG2_mapped, ADDR_TMP_mapped, 8));
|
||||
}
|
||||
|
||||
if (compiler->saveds >= 1) {
|
||||
if (addr_initialized == 0) {
|
||||
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 16));
|
||||
/* addr_initialized = 1; no need to initialize as it's the last one. */
|
||||
}
|
||||
|
||||
FAIL_IF(LD_ADD(SLJIT_SAVED_REG1_mapped, ADDR_TMP_mapped, 8));
|
||||
/* Restore the R registers that need to be reserved. */
|
||||
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
|
||||
}
|
||||
|
||||
if (compiler->local_size <= SIMM_16BIT_MAX)
|
||||
@ -1585,7 +1550,7 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
@ -1602,7 +1567,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
@ -1636,9 +1601,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
if (op == SLJIT_MOV_SI)
|
||||
return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);
|
||||
|
||||
return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
|
||||
} else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
|
||||
} else if (dst != src2) {
|
||||
SLJIT_ASSERT(src2 == 0);
|
||||
return ADD(reg_map[dst], reg_map[src2], ZERO);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
@ -1650,8 +1617,10 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);
|
||||
|
||||
return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);
|
||||
} else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
} else if (dst != src2) {
|
||||
SLJIT_ASSERT(src2 == 0);
|
||||
return ADD(reg_map[dst], reg_map[src2], ZERO);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
@ -1663,8 +1632,10 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);
|
||||
|
||||
return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);
|
||||
} else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
} else if (dst != src2) {
|
||||
SLJIT_ASSERT(src2 == 0);
|
||||
return ADD(reg_map[dst], reg_map[src2], ZERO);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
@ -1811,7 +1782,6 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
else {
|
||||
/* Rare ocasion. */
|
||||
FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
|
||||
|
||||
overflow_ra = TMP_EREG2;
|
||||
}
|
||||
}
|
||||
@ -1903,6 +1873,17 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MUL:
|
||||
if (flags & SRC2_IMM) {
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2));
|
||||
src2 = TMP_REG2;
|
||||
flags &= ~SRC2_IMM;
|
||||
}
|
||||
|
||||
FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2]));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#define EMIT_LOGICAL(op_imm, op_norm) \
|
||||
if (flags & SRC2_IMM) { \
|
||||
FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \
|
||||
@ -1950,8 +1931,8 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
} else { \
|
||||
if (op & SLJIT_SET_E) \
|
||||
FAIL_IF(push_3_buffer( \
|
||||
compiler, op_imm, reg_map[dst], reg_map[src1], \
|
||||
src2 & 0x3F, __LINE__)); \
|
||||
compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
|
||||
reg_map[src2], __LINE__)); \
|
||||
if (CHECK_FLAGS(SLJIT_SET_E)) \
|
||||
FAIL_IF(push_3_buffer( \
|
||||
compiler, op_norm, reg_map[dst], reg_map[src1], \
|
||||
@ -2105,66 +2086,61 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
{
|
||||
sljit_si sugg_dst_ar, dst_ar;
|
||||
sljit_si flags = GET_ALL_FLAGS(op);
|
||||
sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI)
|
||||
mem_type = INT_DATA | SIGNED_DATA;
|
||||
sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2];
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
|
||||
FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
|
||||
src = TMP_REG1;
|
||||
srcw = 0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
switch (type & 0xff) {
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));
|
||||
dst_ar = sugg_dst_ar;
|
||||
break;
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_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:
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
dst_ar = UGREATER_FLAG;
|
||||
break;
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_LESS:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
dst_ar = LESS_FLAG;
|
||||
break;
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_GREATER:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
dst_ar = GREATER_FLAG;
|
||||
break;
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
dst_ar = OVERFLOW_FLAG;
|
||||
break;
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));
|
||||
dst_ar = sugg_dst_ar;
|
||||
type ^= 0x1; /* Flip type bit for the XORI below. */
|
||||
break;
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
dst_ar = EQUAL_FLAG;
|
||||
break;
|
||||
|
||||
default:
|
||||
SLJIT_ASSERT_STOP();
|
||||
@ -2180,11 +2156,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
if (op >= SLJIT_ADD) {
|
||||
if (TMP_REG2_mapped != dst_ar)
|
||||
FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));
|
||||
return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
|
||||
return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
|
||||
}
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw);
|
||||
return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
|
||||
|
||||
if (sugg_dst_ar != dst_ar)
|
||||
return ADD(sugg_dst_ar, dst_ar, ZERO);
|
||||
@ -2194,7 +2170,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) {
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op0(compiler, op);
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
@ -2204,10 +2180,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
case SLJIT_BREAKPOINT:
|
||||
return PI(BPT);
|
||||
|
||||
case SLJIT_UMUL:
|
||||
case SLJIT_SMUL:
|
||||
case SLJIT_UDIV:
|
||||
case SLJIT_SDIV:
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_ASSERT_STOP();
|
||||
}
|
||||
|
||||
@ -2217,7 +2193,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
@ -2273,7 +2249,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
|
||||
|
||||
case SLJIT_CLZ:
|
||||
return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
return emit_op(compiler, op, (op & SLJIT_INT_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -2282,7 +2258,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||
@ -2325,7 +2301,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_comp
|
||||
flush_buffer(compiler);
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_label(compiler);
|
||||
CHECK_PTR(check_sljit_emit_label(compiler));
|
||||
|
||||
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
||||
return compiler->last_label;
|
||||
@ -2344,7 +2320,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
||||
flush_buffer(compiler);
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_ijump(compiler, type, src, srcw);
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
@ -2404,8 +2380,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
} else if (src & SLJIT_MEM)
|
||||
} else if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
||||
flush_buffer(compiler);
|
||||
}
|
||||
|
||||
FAIL_IF(JR_SOLO(reg_map[src_r]));
|
||||
|
||||
@ -2432,7 +2410,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil
|
||||
flush_buffer(compiler);
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_jump(compiler, type);
|
||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||
|
||||
jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
@ -2440,48 +2418,42 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil
|
||||
type &= 0xff;
|
||||
|
||||
switch (type) {
|
||||
case SLJIT_C_EQUAL:
|
||||
case SLJIT_C_FLOAT_NOT_EQUAL:
|
||||
case SLJIT_EQUAL:
|
||||
BR_NZ(EQUAL_FLAG);
|
||||
break;
|
||||
case SLJIT_C_NOT_EQUAL:
|
||||
case SLJIT_C_FLOAT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL:
|
||||
BR_Z(EQUAL_FLAG);
|
||||
break;
|
||||
case SLJIT_C_LESS:
|
||||
case SLJIT_C_FLOAT_LESS:
|
||||
case SLJIT_LESS:
|
||||
BR_Z(ULESS_FLAG);
|
||||
break;
|
||||
case SLJIT_C_GREATER_EQUAL:
|
||||
case SLJIT_C_FLOAT_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
BR_NZ(ULESS_FLAG);
|
||||
break;
|
||||
case SLJIT_C_GREATER:
|
||||
case SLJIT_C_FLOAT_GREATER:
|
||||
case SLJIT_GREATER:
|
||||
BR_Z(UGREATER_FLAG);
|
||||
break;
|
||||
case SLJIT_C_LESS_EQUAL:
|
||||
case SLJIT_C_FLOAT_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL:
|
||||
BR_NZ(UGREATER_FLAG);
|
||||
break;
|
||||
case SLJIT_C_SIG_LESS:
|
||||
case SLJIT_SIG_LESS:
|
||||
BR_Z(LESS_FLAG);
|
||||
break;
|
||||
case SLJIT_C_SIG_GREATER_EQUAL:
|
||||
case SLJIT_SIG_GREATER_EQUAL:
|
||||
BR_NZ(LESS_FLAG);
|
||||
break;
|
||||
case SLJIT_C_SIG_GREATER:
|
||||
case SLJIT_SIG_GREATER:
|
||||
BR_Z(GREATER_FLAG);
|
||||
break;
|
||||
case SLJIT_C_SIG_LESS_EQUAL:
|
||||
case SLJIT_SIG_LESS_EQUAL:
|
||||
BR_NZ(GREATER_FLAG);
|
||||
break;
|
||||
case SLJIT_C_OVERFLOW:
|
||||
case SLJIT_C_MUL_OVERFLOW:
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
BR_Z(OVERFLOW_FLAG);
|
||||
break;
|
||||
case SLJIT_C_NOT_OVERFLOW:
|
||||
case SLJIT_C_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
BR_NZ(OVERFLOW_FLAG);
|
||||
break;
|
||||
default:
|
||||
@ -2536,7 +2508,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_comp
|
||||
flush_buffer(compiler);
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
check_sljit_emit_const(compiler, dst, dstw, init_value);
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
@ -2572,3 +2544,18 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
59
src/3rdparty/pcre/sljit/sljitNativeX86_common.c
vendored
59
src/3rdparty/pcre/sljit/sljitNativeX86_common.c
vendored
@ -744,8 +744,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
break;
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
compiler->flags_saved = 0;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
#ifdef _WIN64
|
||||
@ -763,9 +765,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
#endif
|
||||
compiler->mode32 = op & SLJIT_INT_OP;
|
||||
#endif
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
if (op == SLJIT_LUDIV) {
|
||||
if ((op | 0x2) == SLJIT_UDIVI) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);
|
||||
@ -776,7 +779,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
*inst = XOR_r_rm;
|
||||
}
|
||||
|
||||
if (op == SLJIT_LSDIV) {
|
||||
if ((op | 0x2) == SLJIT_SDIVI) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
|
||||
#endif
|
||||
@ -807,10 +810,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
*inst++ = GROUP_F7;
|
||||
*inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
|
||||
*inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
|
||||
#else
|
||||
#ifdef _WIN64
|
||||
size = (!compiler->mode32 || op >= SLJIT_LUDIV) ? 3 : 2;
|
||||
size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2;
|
||||
#else
|
||||
size = (!compiler->mode32) ? 3 : 2;
|
||||
#endif
|
||||
@ -819,11 +822,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
INC_SIZE(size);
|
||||
#ifdef _WIN64
|
||||
if (!compiler->mode32)
|
||||
*inst++ = REX_W | ((op >= SLJIT_LUDIV) ? REX_B : 0);
|
||||
else if (op >= SLJIT_LUDIV)
|
||||
*inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0);
|
||||
else if (op >= SLJIT_UDIVMOD)
|
||||
*inst++ = REX_B;
|
||||
*inst++ = GROUP_F7;
|
||||
*inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
|
||||
*inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
|
||||
#else
|
||||
if (!compiler->mode32)
|
||||
*inst++ = REX_W;
|
||||
@ -838,15 +841,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
case SLJIT_LSMUL:
|
||||
*inst |= IMUL;
|
||||
break;
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
*inst |= DIV;
|
||||
break;
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_SDIVI:
|
||||
*inst |= IDIV;
|
||||
break;
|
||||
}
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
|
||||
EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
||||
if (op <= SLJIT_SDIVMOD)
|
||||
EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
||||
#else
|
||||
if (op >= SLJIT_UDIVI)
|
||||
EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -1907,60 +1916,62 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler,
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (FAST_IS_REG(src1)) {
|
||||
if (!(src1 & SLJIT_IMM)) {
|
||||
if (src2 & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (IS_HALFWORD(src2w) || compiler->mode32) {
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = GROUP_F7;
|
||||
}
|
||||
else {
|
||||
FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = TEST_rm_r;
|
||||
}
|
||||
#else
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = GROUP_F7;
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
else if (FAST_IS_REG(src1)) {
|
||||
inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = TEST_rm_r;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (FAST_IS_REG(src2)) {
|
||||
if (!(src2 & SLJIT_IMM)) {
|
||||
if (src1 & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (IS_HALFWORD(src1w) || compiler->mode32) {
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = GROUP_F7;
|
||||
}
|
||||
else {
|
||||
FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = TEST_rm_r;
|
||||
}
|
||||
#else
|
||||
inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
|
||||
inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = GROUP_F7;
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
else if (FAST_IS_REG(src2)) {
|
||||
inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
|
||||
FAIL_IF(!inst);
|
||||
*inst = TEST_rm_r;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
|
@ -40,15 +40,15 @@ SOURCES += \
|
||||
$$ANGLE_DIR/src/compiler/preprocessor/Preprocessor.cpp \
|
||||
$$ANGLE_DIR/src/compiler/preprocessor/Token.cpp
|
||||
|
||||
# NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
|
||||
flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
|
||||
# NOTE: 'flex' and 'bison' can be found in qt5/gnuwin32/bin
|
||||
flex.commands = $$addGnuPath(flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
|
||||
flex.output = ${QMAKE_FILE_BASE}.cpp
|
||||
flex.input = FLEX_SOURCES
|
||||
flex.dependency_type = TYPE_C
|
||||
flex.variable_out = GENERATED_SOURCES
|
||||
QMAKE_EXTRA_COMPILERS += flex
|
||||
|
||||
bison.commands = $$addGnuPath(win_bison) --no-lines --skeleton=yacc.c --output=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
|
||||
bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --output=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
|
||||
bison.output = ${QMAKE_FILE_BASE}.cpp
|
||||
bison.input = BISON_SOURCES
|
||||
bison.dependency_type = TYPE_C
|
||||
|
@ -162,15 +162,15 @@ SOURCES += \
|
||||
$$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
|
||||
|
||||
|
||||
# NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
|
||||
flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
|
||||
# NOTE: 'flex' and 'bison' can be found in qt5/gnuwin32/bin
|
||||
flex.commands = $$addGnuPath(flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
|
||||
flex.output = ${QMAKE_FILE_BASE}_lex.cpp
|
||||
flex.input = FLEX_SOURCES
|
||||
flex.dependency_type = TYPE_C
|
||||
flex.variable_out = GENERATED_SOURCES
|
||||
QMAKE_EXTRA_COMPILERS += flex
|
||||
|
||||
bison.commands = $$addGnuPath(win_bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_BASE}_tab.h \
|
||||
bison.commands = $$addGnuPath(bison) --no-lines --skeleton=yacc.c --defines=${QMAKE_FILE_BASE}_tab.h \
|
||||
--output=${QMAKE_FILE_BASE}_tab.cpp ${QMAKE_FILE_NAME}
|
||||
bison.output = ${QMAKE_FILE_BASE}_tab.h
|
||||
bison.input = BISON_SOURCES
|
||||
|
@ -2658,6 +2658,7 @@
|
||||
\value ItemIsTristate \e{This enum value is deprecated.} Use Qt::ItemIsAutoTristate
|
||||
instead.
|
||||
\value ItemNeverHasChildren The item never has child items.
|
||||
This is used for optimization purposes only.
|
||||
\value ItemIsUserTristate The user can cycle through three separate states.
|
||||
This value has been added in Qt 5.5.
|
||||
|
||||
|
@ -263,6 +263,7 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request)
|
||||
groupId(). You can examine a file's permissions and ownership in a
|
||||
single statement using the permission() function.
|
||||
|
||||
\target NTFS permissions
|
||||
\note On NTFS file systems, ownership and permissions checking is
|
||||
disabled by default for performance reasons. To enable it,
|
||||
include the following line:
|
||||
@ -893,6 +894,9 @@ QDir QFileInfo::absoluteDir() const
|
||||
/*!
|
||||
Returns \c true if the user can read the file; otherwise returns \c false.
|
||||
|
||||
\note If the \l{NTFS permissions} check has not been enabled, the result
|
||||
on Windows will merely reflect whether the file exists.
|
||||
|
||||
\sa isWritable(), isExecutable(), permission()
|
||||
*/
|
||||
bool QFileInfo::isReadable() const
|
||||
@ -911,6 +915,9 @@ bool QFileInfo::isReadable() const
|
||||
/*!
|
||||
Returns \c true if the user can write to the file; otherwise returns \c false.
|
||||
|
||||
\note If the \l{NTFS permissions} check has not been enabled, the result on
|
||||
Windows will merely reflect whether the file is marked as Read Only.
|
||||
|
||||
\sa isReadable(), isExecutable(), permission()
|
||||
*/
|
||||
bool QFileInfo::isWritable() const
|
||||
@ -1137,7 +1144,8 @@ QString QFileInfo::readLink() const
|
||||
returned.
|
||||
|
||||
This function can be time consuming under Unix (in the order of
|
||||
milliseconds).
|
||||
milliseconds). On Windows, it will return an empty string unless
|
||||
the \l{NTFS permissions} check has been enabled.
|
||||
|
||||
\sa ownerId(), group(), groupId()
|
||||
*/
|
||||
@ -1217,6 +1225,9 @@ uint QFileInfo::groupId() const
|
||||
On systems where files do not have permissions this function
|
||||
always returns \c true.
|
||||
|
||||
\note The result might be inaccurate on Windows if the
|
||||
\l{NTFS permissions} check has not been enabled.
|
||||
|
||||
Example:
|
||||
\snippet code/src_corelib_io_qfileinfo.cpp 10
|
||||
|
||||
@ -1240,6 +1251,9 @@ bool QFileInfo::permission(QFile::Permissions permissions) const
|
||||
/*!
|
||||
Returns the complete OR-ed together combination of
|
||||
QFile::Permissions for the file.
|
||||
|
||||
\note The result might be inaccurate on Windows if the
|
||||
\l{NTFS permissions} check has not been enabled.
|
||||
*/
|
||||
QFile::Permissions QFileInfo::permissions() const
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Copyright (C) 2014 Intel Corporation
|
||||
** Copyright (C) 2015 Intel Corporation
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -139,7 +139,7 @@ QT_BEGIN_NAMESPACE
|
||||
Unix environment allows both variable names and contents to contain arbitrary
|
||||
binary data (except for the NUL character). QProcessEnvironment will preserve
|
||||
such variables, but does not support manipulating variables whose names or
|
||||
values are not encodable by the current locale settings (see
|
||||
values cannot be encoded by the current locale settings (see
|
||||
QTextCodec::codecForLocale).
|
||||
|
||||
On Windows, the variable names are case-insensitive, but case-preserving.
|
||||
@ -395,8 +395,8 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa
|
||||
Use with the QProcess::setEnvironment function is not recommended due to
|
||||
potential encoding problems under Unix, and worse performance.
|
||||
|
||||
\sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(),
|
||||
QProcess::setEnvironment()
|
||||
\sa systemEnvironment(), QProcess::systemEnvironment(),
|
||||
QProcess::setProcessEnvironment()
|
||||
*/
|
||||
QStringList QProcessEnvironment::toStringList() const
|
||||
{
|
||||
@ -545,7 +545,7 @@ void QProcessPrivate::Channel::clear()
|
||||
QProcess can merge the two output channels, so that standard
|
||||
output and standard error data from the running process both use
|
||||
the standard output channel. Call setProcessChannelMode() with
|
||||
MergedChannels before starting the process to activative
|
||||
MergedChannels before starting the process to activate
|
||||
this feature. You also have the option of forwarding the output of
|
||||
the running process to the calling, main process, by passing
|
||||
ForwardedChannels as the argument. It is also possible to forward
|
||||
@ -556,7 +556,7 @@ void QProcessPrivate::Channel::clear()
|
||||
|
||||
Certain processes need special environment settings in order to
|
||||
operate. You can set environment variables for your process by
|
||||
calling setEnvironment(). To set a working directory, call
|
||||
calling setProcessEnvironment(). To set a working directory, call
|
||||
setWorkingDirectory(). By default, processes are run in the
|
||||
current working directory of the calling process.
|
||||
|
||||
@ -1328,7 +1328,7 @@ QProcess::InputChannelMode QProcess::inputChannelMode() const
|
||||
/*!
|
||||
\since 5.2
|
||||
|
||||
Sets the channel mode of the QProcess standard intput
|
||||
Sets the channel mode of the QProcess standard input
|
||||
channel to the \a mode specified.
|
||||
This mode will be used the next time start() is called.
|
||||
|
||||
@ -2195,6 +2195,7 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
|
||||
qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')';
|
||||
#endif
|
||||
|
||||
stdinChannel.buffer.clear();
|
||||
stdoutChannel.buffer.clear();
|
||||
stderrChannel.buffer.clear();
|
||||
|
||||
@ -2393,7 +2394,7 @@ void QProcess::setArguments(const QStringList &arguments)
|
||||
The process may not exit as a result of calling this function (it is given
|
||||
the chance to prompt the user for any unsaved files, etc).
|
||||
|
||||
On Windows, terminate() posts a WM_CLOSE message to all toplevel windows
|
||||
On Windows, terminate() posts a WM_CLOSE message to all top-level windows
|
||||
of the process and then to the main thread of the process itself. On Unix
|
||||
and OS X the \c SIGTERM signal is sent.
|
||||
|
||||
@ -2589,14 +2590,14 @@ QT_END_INCLUDE_NAMESPACE
|
||||
|
||||
This function does not cache the system environment. Therefore, it's
|
||||
possible to obtain an updated version of the environment if low-level C
|
||||
library functions like \tt setenv ot \tt putenv have been called.
|
||||
library functions like \tt setenv or \tt putenv have been called.
|
||||
|
||||
However, note that repeated calls to this function will recreate the
|
||||
list of environment variables, which is a non-trivial operation.
|
||||
|
||||
\note For new code, it is recommended to use QProcessEnvironment::systemEnvironment()
|
||||
|
||||
\sa QProcessEnvironment::systemEnvironment(), environment(), setEnvironment()
|
||||
\sa QProcessEnvironment::systemEnvironment(), setProcessEnvironment()
|
||||
*/
|
||||
QStringList QProcess::systemEnvironment()
|
||||
{
|
||||
@ -2619,7 +2620,7 @@ QStringList QProcess::systemEnvironment()
|
||||
It is returned as a QProcessEnvironment. This function does not
|
||||
cache the system environment. Therefore, it's possible to obtain
|
||||
an updated version of the environment if low-level C library
|
||||
functions like \tt setenv ot \tt putenv have been called.
|
||||
functions like \tt setenv or \tt putenv have been called.
|
||||
|
||||
However, note that repeated calls to this function will recreate the
|
||||
QProcessEnvironment object, which is a non-trivial operation.
|
||||
|
@ -694,13 +694,15 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
|
||||
return true;
|
||||
|
||||
// If we wouldn't write anything, check if we can read stdout.
|
||||
if (bytesAvailableInChannel(&stdoutChannel) != 0) {
|
||||
if (stdoutChannel.pipe[0] != INVALID_Q_PIPE
|
||||
&& bytesAvailableInChannel(&stdoutChannel) != 0) {
|
||||
tryReadFromChannel(&stdoutChannel);
|
||||
timer.resetIncrements();
|
||||
}
|
||||
|
||||
// Check if we can read stderr.
|
||||
if (bytesAvailableInChannel(&stderrChannel) != 0) {
|
||||
if (stderrChannel.pipe[0] != INVALID_Q_PIPE
|
||||
&& bytesAvailableInChannel(&stderrChannel) != 0) {
|
||||
tryReadFromChannel(&stderrChannel);
|
||||
timer.resetIncrements();
|
||||
}
|
||||
|
@ -507,9 +507,9 @@ void QStorageInfoPrivate::retrieveVolumeInfo()
|
||||
valid = true;
|
||||
ready = true;
|
||||
|
||||
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize;
|
||||
bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize;
|
||||
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize;
|
||||
bytesTotal = statfs_buf.f_blocks * statfs_buf.f_frsize;
|
||||
bytesFree = statfs_buf.f_bfree * statfs_buf.f_frsize;
|
||||
bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_frsize;
|
||||
blockSize = statfs_buf.f_bsize;
|
||||
#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4)
|
||||
#if defined(_STATFS_F_FLAGS)
|
||||
|
@ -85,7 +85,7 @@ qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
|
||||
return -1;
|
||||
|
||||
QMutexLocker locker(&lock);
|
||||
data.append(QByteArray(ptr, maxlen));
|
||||
data.append(ptr, maxlen);
|
||||
waitCondition.wakeOne();
|
||||
return maxlen;
|
||||
}
|
||||
|
@ -1395,6 +1395,8 @@ bool QObject::eventFilter(QObject * /* watched */, QEvent * /* event */)
|
||||
Note that the destroyed() signal will be emitted even if the signals
|
||||
for this object have been blocked.
|
||||
|
||||
Signals emitted while being blocked are not buffered.
|
||||
|
||||
\sa signalsBlocked()
|
||||
*/
|
||||
|
||||
|
@ -79,10 +79,9 @@ Q_CORE_EXPORT int qmime_secondsBetweenChecks = 5; // exported for the unit test
|
||||
|
||||
bool QMimeProviderBase::shouldCheck()
|
||||
{
|
||||
const QDateTime now = QDateTime::currentDateTime();
|
||||
if (m_lastCheck.isValid() && m_lastCheck.secsTo(now) < qmime_secondsBetweenChecks)
|
||||
if (m_lastCheck.isValid() && m_lastCheck.elapsed() < qmime_secondsBetweenChecks * 1000)
|
||||
return false;
|
||||
m_lastCheck = now;
|
||||
m_lastCheck.start();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -562,10 +561,13 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
|
||||
// load comment and globPatterns
|
||||
|
||||
const QString file = data.name + QLatin1String(".xml");
|
||||
const QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file);
|
||||
// shared-mime-info since 1.3 lowercases the xml files
|
||||
QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file.toLower());
|
||||
if (mimeFiles.isEmpty()) {
|
||||
// TODO: ask Thiago about this
|
||||
qWarning() << "No file found for" << file << ", even though the file appeared in a directory listing.";
|
||||
mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QString::fromLatin1("mime/") + file); // pre-1.3
|
||||
}
|
||||
if (mimeFiles.isEmpty()) {
|
||||
qWarning() << "No file found for" << file << ", even though update-mime-info said it would exist.";
|
||||
qWarning() << "Either it was just removed, or the directory doesn't have executable permission...";
|
||||
qWarning() << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
|
||||
return;
|
||||
@ -626,7 +628,7 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
|
||||
// Let's assume that shared-mime-info is at least version 0.70
|
||||
// Otherwise we would need 1) a version check, and 2) code for parsing patterns from the globs file.
|
||||
#if 1
|
||||
if (!mainPattern.isEmpty() && data.globPatterns.first() != mainPattern) {
|
||||
if (!mainPattern.isEmpty() && (data.globPatterns.isEmpty() || data.globPatterns.first() != mainPattern)) {
|
||||
// ensure it's first in the list of patterns
|
||||
data.globPatterns.removeAll(mainPattern);
|
||||
data.globPatterns.prepend(mainPattern);
|
||||
|
@ -51,6 +51,7 @@
|
||||
|
||||
#include <QtCore/qdatetime.h>
|
||||
#include <QtCore/qset.h>
|
||||
#include <QtCore/qelapsedtimer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -77,7 +78,7 @@ public:
|
||||
QMimeDatabasePrivate *m_db;
|
||||
protected:
|
||||
bool shouldCheck();
|
||||
QDateTime m_lastCheck;
|
||||
QElapsedTimer m_lastCheck;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -563,7 +563,28 @@ const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = {
|
||||
};
|
||||
|
||||
typedef QFreeList<QMutexPrivate, FreeListConstants> FreeList;
|
||||
Q_GLOBAL_STATIC(FreeList, freelist);
|
||||
// We cannot use Q_GLOBAL_STATIC because it uses QMutex
|
||||
#if defined(Q_COMPILER_THREADSAFE_STATICS)
|
||||
FreeList *freelist()
|
||||
{
|
||||
static FreeList list;
|
||||
return &list;
|
||||
}
|
||||
#else
|
||||
FreeList *freelist()
|
||||
{
|
||||
static QAtomicPointer<FreeList> list;
|
||||
FreeList *local = list.loadAcquire();
|
||||
if (!local) {
|
||||
local = new FreeList;
|
||||
if (!list.testAndSetRelease(0, local)) {
|
||||
delete local;
|
||||
local = list.loadAcquire();
|
||||
}
|
||||
}
|
||||
return local;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QMutexPrivate *QMutexPrivate::allocate()
|
||||
|
@ -46,21 +46,21 @@ SOURCES += thread/qatomic.cpp \
|
||||
unix:SOURCES += thread/qthread_unix.cpp \
|
||||
thread/qwaitcondition_unix.cpp
|
||||
|
||||
win32:SOURCES += thread/qmutex_win.cpp \
|
||||
thread/qthread_win.cpp \
|
||||
win32:SOURCES += thread/qthread_win.cpp \
|
||||
thread/qwaitcondition_win.cpp
|
||||
|
||||
integrity:SOURCES += thread/qmutex_unix.cpp \
|
||||
thread/qthread_unix.cpp \
|
||||
integrity:SOURCES += thread/qthread_unix.cpp \
|
||||
thread/qwaitcondition_unix.cpp
|
||||
|
||||
unix: {
|
||||
mac {
|
||||
SOURCES += thread/qmutex_mac.cpp
|
||||
} else:linux-*:!linux-lsb-* {
|
||||
SOURCES += thread/qmutex_linux.cpp
|
||||
} else {
|
||||
SOURCES += thread/qmutex_unix.cpp
|
||||
}
|
||||
false {
|
||||
# files #included by others, but listed here so IDEs parsing this file know
|
||||
# they are part of QtCore. Usually, qmake can find out that certain files
|
||||
# are #included by others and thus remove from SOURCES, but it gets lost
|
||||
# with qmutex.cpp.
|
||||
SOURCES += \
|
||||
thread/qmutex_linux.cpp \
|
||||
thread/qmutex_mac.cpp \
|
||||
thread/qmutex_unix.cpp \
|
||||
thread/qmutex_win.cpp
|
||||
}
|
||||
|
||||
|
@ -598,12 +598,22 @@ QT_BEGIN_NAMESPACE
|
||||
\fn QChar::QChar(char ch)
|
||||
|
||||
Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
|
||||
|
||||
\note This constructor is not available when \c QT_NO_CAST_FROM_ASCII
|
||||
is defined.
|
||||
|
||||
\sa QT_NO_CAST_FROM_ASCII
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QChar::QChar(uchar ch)
|
||||
|
||||
Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
|
||||
|
||||
\note This constructor is not available when \c QT_NO_CAST_FROM_ASCII
|
||||
is defined.
|
||||
|
||||
\sa QT_NO_CAST_FROM_ASCII
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -1681,6 +1681,7 @@ bool QTime::setHMS(int h, int m, int s, int ms)
|
||||
|
||||
QTime QTime::addSecs(int s) const
|
||||
{
|
||||
s %= SECS_PER_DAY;
|
||||
return addMSecs(s * 1000);
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,13 @@ static qint64 absoluteToNSecs(qint64 cpuTime)
|
||||
{
|
||||
if (info.denom == 0)
|
||||
mach_timebase_info(&info);
|
||||
#ifdef __LP64__
|
||||
__uint128_t nsecs = static_cast<__uint128_t>(cpuTime) * info.numer / info.denom;
|
||||
return static_cast<qint64>(nsecs);
|
||||
#else
|
||||
qint64 nsecs = cpuTime * info.numer / info.denom;
|
||||
return nsecs;
|
||||
#endif
|
||||
}
|
||||
|
||||
static qint64 absoluteToMSecs(qint64 cpuTime)
|
||||
|
@ -116,6 +116,10 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
|
||||
A good text on regexps is \e {Mastering Regular Expressions}
|
||||
(Third Edition) by Jeffrey E. F. Friedl, ISBN 0-596-52812-4.
|
||||
|
||||
\note In Qt 5, the new QRegularExpression class provides a Perl
|
||||
compatible implementation of regular expressions and is recommended
|
||||
in place of QRegExp.
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\section1 Introduction
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>.
|
||||
** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||
** Copyright (C) 2015 Giuseppe D'Angelo <dangelog@gmail.com>.
|
||||
** Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
@ -1326,48 +1326,45 @@ QRegularExpressionMatchPrivate *QRegularExpressionPrivate::doMatch(const QString
|
||||
int * const captureOffsets = priv->capturedOffsets.data();
|
||||
const int captureOffsetsCount = priv->capturedOffsets.size();
|
||||
|
||||
int realOffset = offset + subjectStart;
|
||||
const int realSubjectLength = subjectLength + subjectStart;
|
||||
|
||||
const unsigned short * const subjectUtf16 = subject.utf16();
|
||||
const unsigned short * const subjectUtf16 = subject.utf16() + subjectStart;
|
||||
|
||||
int result;
|
||||
|
||||
if (!previousMatchWasEmpty) {
|
||||
result = pcre16SafeExec(compiledPattern, currentStudyData,
|
||||
subjectUtf16, realSubjectLength,
|
||||
realOffset, pcreOptions,
|
||||
subjectUtf16, subjectLength,
|
||||
offset, pcreOptions,
|
||||
captureOffsets, captureOffsetsCount);
|
||||
} else {
|
||||
result = pcre16SafeExec(compiledPattern, currentStudyData,
|
||||
subjectUtf16, realSubjectLength,
|
||||
realOffset, pcreOptions | PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED,
|
||||
subjectUtf16, subjectLength,
|
||||
offset, pcreOptions | PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED,
|
||||
captureOffsets, captureOffsetsCount);
|
||||
|
||||
if (result == PCRE_ERROR_NOMATCH) {
|
||||
++realOffset;
|
||||
++offset;
|
||||
|
||||
if (usingCrLfNewlines
|
||||
&& realOffset < realSubjectLength
|
||||
&& subjectUtf16[realOffset - 1] == QLatin1Char('\r')
|
||||
&& subjectUtf16[realOffset] == QLatin1Char('\n')) {
|
||||
++realOffset;
|
||||
} else if (realOffset < realSubjectLength
|
||||
&& QChar::isLowSurrogate(subjectUtf16[realOffset])) {
|
||||
++realOffset;
|
||||
&& offset < subjectLength
|
||||
&& subjectUtf16[offset - 1] == QLatin1Char('\r')
|
||||
&& subjectUtf16[offset] == QLatin1Char('\n')) {
|
||||
++offset;
|
||||
} else if (offset < subjectLength
|
||||
&& QChar::isLowSurrogate(subjectUtf16[offset])) {
|
||||
++offset;
|
||||
}
|
||||
|
||||
result = pcre16SafeExec(compiledPattern, currentStudyData,
|
||||
subjectUtf16, realSubjectLength,
|
||||
realOffset, pcreOptions,
|
||||
subjectUtf16, subjectLength,
|
||||
offset, pcreOptions,
|
||||
captureOffsets, captureOffsetsCount);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef QREGULAREXPRESSION_DEBUG
|
||||
qDebug() << "Matching" << pattern << "against" << subject
|
||||
<< "starting at" << subjectStart << "len" << subjectLength << "real len" << realSubjectLength
|
||||
<< "offset" << offset << "real offset" << realOffset
|
||||
<< "starting at" << subjectStart << "len" << subjectLength
|
||||
<< "offset" << offset
|
||||
<< matchType << matchOptions << previousMatchWasEmpty
|
||||
<< "result" << result;
|
||||
#endif
|
||||
@ -2057,7 +2054,7 @@ QString QRegularExpressionMatch::captured(int nth) const
|
||||
if (start == -1) // didn't capture
|
||||
return QString();
|
||||
|
||||
return d->subject.mid(start, capturedLength(nth));
|
||||
return d->subject.mid(start + d->subjectStart, capturedLength(nth));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2078,7 +2075,7 @@ QStringRef QRegularExpressionMatch::capturedRef(int nth) const
|
||||
if (start == -1) // didn't capture
|
||||
return QStringRef();
|
||||
|
||||
return d->subject.midRef(start, capturedLength(nth));
|
||||
return d->subject.midRef(start + d->subjectStart, capturedLength(nth));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -212,6 +212,9 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
||||
int blue_scale = 0;
|
||||
int alpha_scale = 0;
|
||||
|
||||
if (!d->isSequential())
|
||||
d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4 ? BMP_WIN : bi.biSize)); // goto start of colormap or masks
|
||||
|
||||
if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) {
|
||||
if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
|
||||
return false;
|
||||
@ -299,9 +302,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
|
||||
image.setDotsPerMeterX(bi.biXPelsPerMeter);
|
||||
image.setDotsPerMeterY(bi.biYPelsPerMeter);
|
||||
|
||||
if (!d->isSequential())
|
||||
d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
|
||||
|
||||
if (ncols > 0) { // read color table
|
||||
uchar rgb[4];
|
||||
int rgb_len = t == BMP_OLD ? 3 : 4;
|
||||
|
@ -4237,9 +4237,6 @@ QImage QImage::alphaChannel() const
|
||||
if (!d)
|
||||
return QImage();
|
||||
|
||||
if (d->format == QImage::Format_Alpha8)
|
||||
return *this;
|
||||
|
||||
int w = d->width;
|
||||
int h = d->height;
|
||||
|
||||
@ -4269,6 +4266,10 @@ QImage QImage::alphaChannel() const
|
||||
src_data += d->bytes_per_line;
|
||||
dest_data += image.d->bytes_per_line;
|
||||
}
|
||||
} else if (d->format == Format_Alpha8) {
|
||||
const uchar *src_data = d->data;
|
||||
uchar *dest_data = image.d->data;
|
||||
memcpy(dest_data, src_data, d->bytes_per_line * h);
|
||||
} else {
|
||||
QImage alpha32 = *this;
|
||||
bool canSkipConversion = (d->format == Format_ARGB32 || d->format == Format_ARGB32_Premultiplied);
|
||||
|
@ -449,8 +449,7 @@ static QWindowGeometrySpecification windowGeometrySpecification;
|
||||
\row
|
||||
\li Miscellaneous
|
||||
\li startingUp(),
|
||||
closingDown(),
|
||||
type().
|
||||
closingDown().
|
||||
\endtable
|
||||
|
||||
\sa QCoreApplication, QAbstractEventDispatcher, QEventLoop
|
||||
|
@ -386,9 +386,7 @@ QKeySequence::SequenceMatch QShortcutMap::nextState(QKeyEvent *e)
|
||||
result = find(e);
|
||||
if (result == QKeySequence::NoMatch && (e->modifiers() & Qt::KeypadModifier)) {
|
||||
// Try to find a match without keypad modifier
|
||||
QKeyEvent event = *e;
|
||||
event.setModifiers(e->modifiers() & ~Qt::KeypadModifier);
|
||||
result = find(&event);
|
||||
result = find(e, Qt::KeypadModifier);
|
||||
}
|
||||
if (result == QKeySequence::NoMatch && e->modifiers() & Qt::ShiftModifier) {
|
||||
// If Shift + Key_Backtab, also try Shift + Qt::Key_Tab
|
||||
@ -441,13 +439,13 @@ bool QShortcutMap::hasShortcutForKeySequence(const QKeySequence &seq) const
|
||||
which can be access through matches().
|
||||
\sa matches
|
||||
*/
|
||||
QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e)
|
||||
QKeySequence::SequenceMatch QShortcutMap::find(QKeyEvent *e, int ignoredModifiers)
|
||||
{
|
||||
Q_D(QShortcutMap);
|
||||
if (!d->sequences.count())
|
||||
return QKeySequence::NoMatch;
|
||||
|
||||
createNewSequences(e, d->newEntries);
|
||||
createNewSequences(e, d->newEntries, ignoredModifiers);
|
||||
#if defined(DEBUG_QSHORTCUTMAP)
|
||||
qDebug() << "Possible shortcut key sequences:" << d->newEntries;
|
||||
#endif
|
||||
@ -549,7 +547,7 @@ void QShortcutMap::clearSequence(QVector<QKeySequence> &ksl)
|
||||
Alters \a seq to the new sequence state, based on the
|
||||
current sequence state, and the new key event \a e.
|
||||
*/
|
||||
void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl)
|
||||
void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl, int ignoredModifiers)
|
||||
{
|
||||
Q_D(QShortcutMap);
|
||||
QList<int> possibleKeys = QKeyMapper::possibleKeys(e);
|
||||
@ -579,7 +577,7 @@ void QShortcutMap::createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl)
|
||||
curKsl.setKey(0, 2);
|
||||
curKsl.setKey(0, 3);
|
||||
}
|
||||
curKsl.setKey(possibleKeys.at(pkNum), index);
|
||||
curKsl.setKey(possibleKeys.at(pkNum) & ~ignoredModifiers, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +88,10 @@ private:
|
||||
QKeySequence::SequenceMatch state();
|
||||
void dispatchEvent(QKeyEvent *e);
|
||||
|
||||
QKeySequence::SequenceMatch find(QKeyEvent *e);
|
||||
QKeySequence::SequenceMatch find(QKeyEvent *e, int ignoredModifiers = 0);
|
||||
QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const;
|
||||
QVector<const QShortcutEntry *> matches() const;
|
||||
void createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl);
|
||||
void createNewSequences(QKeyEvent *e, QVector<QKeySequence> &ksl, int ignoredModifiers);
|
||||
void clearSequence(QVector<QKeySequence> &ksl);
|
||||
int translateModifiers(Qt::KeyboardModifiers modifiers);
|
||||
|
||||
|
@ -525,7 +525,8 @@ bool QOpenGLShader::compileSourceCode(const char *source)
|
||||
|
||||
// The precision qualifiers are useful on OpenGL/ES systems,
|
||||
// but usually not present on desktop systems.
|
||||
const QSurfaceFormat currentSurfaceFormat = QOpenGLContext::currentContext()->format();
|
||||
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
||||
const QSurfaceFormat currentSurfaceFormat = ctx->format();
|
||||
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(QOpenGLContext::currentContext());
|
||||
if (currentSurfaceFormat.renderableType() == QSurfaceFormat::OpenGL
|
||||
|| ctx_d->workaround_missingPrecisionQualifiers
|
||||
@ -545,10 +546,16 @@ bool QOpenGLShader::compileSourceCode(const char *source)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Append #line directive in order to compensate for text insertion
|
||||
QByteArray lineDirective = QStringLiteral("#line %1\n").arg(versionDirectivePosition.line).toUtf8();
|
||||
sourceChunks.append(lineDirective.constData());
|
||||
sourceChunkLengths.append(GLint(lineDirective.length()));
|
||||
QByteArray lineDirective;
|
||||
// #line is rejected by some drivers:
|
||||
// "2.1 Mesa 8.1-devel (git-48a3d4e)" or "MESA 2.1 Mesa 8.1-devel"
|
||||
const char *version = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_VERSION));
|
||||
if (!version || !strstr(version, "2.1 Mesa 8")) {
|
||||
// Append #line directive in order to compensate for text insertion
|
||||
lineDirective = QStringLiteral("#line %1\n").arg(versionDirectivePosition.line).toUtf8();
|
||||
sourceChunks.append(lineDirective.constData());
|
||||
sourceChunkLengths.append(GLint(lineDirective.length()));
|
||||
}
|
||||
|
||||
// Append rest of shader code
|
||||
sourceChunks.append(source + versionDirectivePosition.position);
|
||||
|
@ -305,7 +305,10 @@ static void qt_qimageScaleAARGBA_up_xy(QImageScaleInfo *isi, unsigned int *dest,
|
||||
for (int x = 0; x < dw; x++) {
|
||||
const unsigned int *pix = sptr + xpoints[x];
|
||||
const int xap = xapoints[x];
|
||||
*dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - xap, pix[1], xap);
|
||||
if (xap > 0)
|
||||
*dptr = INTERPOLATE_PIXEL_256(pix[0], 256 - xap, pix[1], xap);
|
||||
else
|
||||
*dptr = pix[0];
|
||||
dptr++;
|
||||
}
|
||||
}
|
||||
|
@ -863,8 +863,8 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
|
||||
const Q16Dot16 iLeft = int(left);
|
||||
const Q16Dot16 iRight = int(right);
|
||||
const Q16Dot16 leftWidth = IntToQ16Dot16(iLeft + 1)
|
||||
- FloatToQ16Dot16(left);
|
||||
const Q16Dot16 rightWidth = FloatToQ16Dot16(right)
|
||||
- qSafeFloatToQ16Dot16(left);
|
||||
const Q16Dot16 rightWidth = qSafeFloatToQ16Dot16(right)
|
||||
- IntToQ16Dot16(iRight);
|
||||
|
||||
Q16Dot16 coverage[3];
|
||||
@ -898,8 +898,8 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
|
||||
|
||||
const Q16Dot16 iTopFP = IntToQ16Dot16(int(pa.y()));
|
||||
const Q16Dot16 iBottomFP = IntToQ16Dot16(int(pb.y()));
|
||||
const Q16Dot16 yPa = FloatToQ16Dot16(pa.y());
|
||||
const Q16Dot16 yPb = FloatToQ16Dot16(pb.y());
|
||||
const Q16Dot16 yPa = qSafeFloatToQ16Dot16(pa.y());
|
||||
const Q16Dot16 yPb = qSafeFloatToQ16Dot16(pb.y());
|
||||
for (Q16Dot16 yFP = iTopFP; yFP <= iBottomFP; yFP += Q16Dot16Factor) {
|
||||
const Q16Dot16 rowHeight = qMin(yFP + Q16Dot16Factor, yPb)
|
||||
- qMax(yFP, yPa);
|
||||
@ -983,16 +983,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
|
||||
const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y()));
|
||||
const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound));
|
||||
|
||||
Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope);
|
||||
Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope);
|
||||
Q16Dot16 leftIntersectAf = qSafeFloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope);
|
||||
Q16Dot16 rightIntersectAf = qSafeFloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope);
|
||||
Q16Dot16 leftIntersectBf = 0;
|
||||
Q16Dot16 rightIntersectBf = 0;
|
||||
|
||||
if (iLeftFP < iTopFP)
|
||||
leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
|
||||
leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope);
|
||||
|
||||
if (iRightFP < iTopFP)
|
||||
rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
|
||||
rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope);
|
||||
|
||||
Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom;
|
||||
Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf;
|
||||
@ -1000,10 +1000,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
|
||||
|
||||
int leftMin, leftMax, rightMin, rightMax;
|
||||
|
||||
const Q16Dot16 yTopFP = FloatToQ16Dot16(top.y());
|
||||
const Q16Dot16 yLeftFP = FloatToQ16Dot16(left.y());
|
||||
const Q16Dot16 yRightFP = FloatToQ16Dot16(right.y());
|
||||
const Q16Dot16 yBottomFP = FloatToQ16Dot16(bottom.y());
|
||||
const Q16Dot16 yTopFP = qSafeFloatToQ16Dot16(top.y());
|
||||
const Q16Dot16 yLeftFP = qSafeFloatToQ16Dot16(left.y());
|
||||
const Q16Dot16 yRightFP = qSafeFloatToQ16Dot16(right.y());
|
||||
const Q16Dot16 yBottomFP = qSafeFloatToQ16Dot16(bottom.y());
|
||||
|
||||
rowTop = qMax(iTopFP, yTopFP);
|
||||
topLeftIntersectAf = leftIntersectAf +
|
||||
@ -1021,7 +1021,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
|
||||
|
||||
if (yFP == iLeftFP) {
|
||||
const int y = Q16Dot16ToInt(yFP);
|
||||
leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope);
|
||||
leftIntersectBf = qSafeFloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope);
|
||||
topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP);
|
||||
bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP);
|
||||
} else {
|
||||
@ -1031,7 +1031,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width,
|
||||
|
||||
if (yFP == iRightFP) {
|
||||
const int y = Q16Dot16ToInt(yFP);
|
||||
rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope);
|
||||
rightIntersectBf = qSafeFloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope);
|
||||
topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP);
|
||||
bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP);
|
||||
} else {
|
||||
|
@ -74,6 +74,16 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline bool qSafeFromBigEndian(const uchar *source, const uchar *end, T *output)
|
||||
{
|
||||
if (source + sizeof(T) > end)
|
||||
return false;
|
||||
|
||||
*output = qFromBigEndian<T>(source);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Harfbuzz helper functions
|
||||
|
||||
#ifdef QT_ENABLE_HARFBUZZ_NG
|
||||
@ -1039,26 +1049,38 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
|
||||
return;
|
||||
|
||||
const uchar *table = reinterpret_cast<const uchar *>(tab.constData());
|
||||
const uchar *end = table + tab.size();
|
||||
|
||||
quint16 version;
|
||||
if (!qSafeFromBigEndian(table, end, &version))
|
||||
return;
|
||||
|
||||
unsigned short version = qFromBigEndian<quint16>(table);
|
||||
if (version != 0) {
|
||||
// qDebug("wrong version");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned short numTables = qFromBigEndian<quint16>(table + 2);
|
||||
quint16 numTables;
|
||||
if (!qSafeFromBigEndian(table + 2, end, &numTables))
|
||||
return;
|
||||
|
||||
{
|
||||
int offset = 4;
|
||||
for(int i = 0; i < numTables; ++i) {
|
||||
if (offset + 6 > tab.size()) {
|
||||
// qDebug("offset out of bounds");
|
||||
goto end;
|
||||
}
|
||||
const uchar *header = table + offset;
|
||||
|
||||
ushort version = qFromBigEndian<quint16>(header);
|
||||
ushort length = qFromBigEndian<quint16>(header+2);
|
||||
ushort coverage = qFromBigEndian<quint16>(header+4);
|
||||
quint16 version;
|
||||
if (!qSafeFromBigEndian(header, end, &version))
|
||||
goto end;
|
||||
|
||||
quint16 length;
|
||||
if (!qSafeFromBigEndian(header + 2, end, &length))
|
||||
goto end;
|
||||
|
||||
quint16 coverage;
|
||||
if (!qSafeFromBigEndian(header + 4, end, &coverage))
|
||||
goto end;
|
||||
|
||||
// qDebug("subtable: version=%d, coverage=%x",version, coverage);
|
||||
if(version == 0 && coverage == 0x0001) {
|
||||
if (offset + length > tab.size()) {
|
||||
@ -1067,7 +1089,10 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
|
||||
}
|
||||
const uchar *data = table + offset + 6;
|
||||
|
||||
ushort nPairs = qFromBigEndian<quint16>(data);
|
||||
quint16 nPairs;
|
||||
if (!qSafeFromBigEndian(data, end, &nPairs))
|
||||
goto end;
|
||||
|
||||
if(nPairs * 6 + 8 > length - 6) {
|
||||
// qDebug("corrupt table!");
|
||||
// corrupt table
|
||||
@ -1077,8 +1102,21 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor)
|
||||
int off = 8;
|
||||
for(int i = 0; i < nPairs; ++i) {
|
||||
QFontEngine::KernPair p;
|
||||
p.left_right = (((uint)qFromBigEndian<quint16>(data+off)) << 16) + qFromBigEndian<quint16>(data+off+2);
|
||||
p.adjust = QFixed(((int)(short)qFromBigEndian<quint16>(data+off+4))) / scalingFactor;
|
||||
|
||||
quint16 tmp;
|
||||
if (!qSafeFromBigEndian(data + off, end, &tmp))
|
||||
goto end;
|
||||
|
||||
p.left_right = uint(tmp) << 16;
|
||||
if (!qSafeFromBigEndian(data + off + 2, end, &tmp))
|
||||
goto end;
|
||||
|
||||
p.left_right |= tmp;
|
||||
|
||||
if (!qSafeFromBigEndian(data + off + 4, end, &tmp))
|
||||
goto end;
|
||||
|
||||
p.adjust = QFixed(int(short(tmp))) / scalingFactor;
|
||||
kerning_pairs.append(p);
|
||||
off += 6;
|
||||
}
|
||||
@ -1098,26 +1136,31 @@ int QFontEngine::glyphCount() const
|
||||
QByteArray maxpTable = getSfntTable(MAKE_TAG('m', 'a', 'x', 'p'));
|
||||
if (maxpTable.size() < 6)
|
||||
return 0;
|
||||
return qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(maxpTable.constData() + 4));
|
||||
|
||||
const uchar *source = reinterpret_cast<const uchar *>(maxpTable.constData() + 4);
|
||||
const uchar *end = source + maxpTable.size();
|
||||
|
||||
quint16 count = 0;
|
||||
qSafeFromBigEndian(source, end, &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize)
|
||||
{
|
||||
const uchar *header = table;
|
||||
if (tableSize < 4)
|
||||
return 0;
|
||||
|
||||
const uchar *endPtr = table + tableSize;
|
||||
|
||||
// version check
|
||||
if (qFromBigEndian<quint16>(header) != 0)
|
||||
quint16 version;
|
||||
if (!qSafeFromBigEndian(header, endPtr, &version) || version != 0)
|
||||
return 0;
|
||||
|
||||
unsigned short numTables = qFromBigEndian<quint16>(header + 2);
|
||||
const uchar *maps = table + 4;
|
||||
if (maps + 8 * numTables > endPtr)
|
||||
quint16 numTables;
|
||||
if (!qSafeFromBigEndian(header + 2, endPtr, &numTables))
|
||||
return 0;
|
||||
|
||||
const uchar *maps = table + 4;
|
||||
|
||||
enum {
|
||||
Invalid,
|
||||
AppleRoman,
|
||||
@ -1132,8 +1175,14 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
|
||||
int tableToUse = -1;
|
||||
int score = Invalid;
|
||||
for (int n = 0; n < numTables; ++n) {
|
||||
const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);
|
||||
const quint16 platformSpecificId = qFromBigEndian<quint16>(maps + 8 * n + 2);
|
||||
quint16 platformId;
|
||||
if (!qSafeFromBigEndian(maps + 8 * n, endPtr, &platformId))
|
||||
return 0;
|
||||
|
||||
quint16 platformSpecificId;
|
||||
if (!qSafeFromBigEndian(maps + 8 * n + 2, endPtr, &platformSpecificId))
|
||||
return 0;
|
||||
|
||||
switch (platformId) {
|
||||
case 0: // Unicode
|
||||
if (score < Unicode &&
|
||||
@ -1187,20 +1236,30 @@ const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSy
|
||||
resolveTable:
|
||||
*isSymbolFont = (symbolTable > -1);
|
||||
|
||||
unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);
|
||||
quint32 unicode_table;
|
||||
if (!qSafeFromBigEndian(maps + 8 * tableToUse + 4, endPtr, &unicode_table))
|
||||
return 0;
|
||||
|
||||
if (!unicode_table || unicode_table + 8 > tableSize)
|
||||
if (!unicode_table)
|
||||
return 0;
|
||||
|
||||
// get the header of the unicode table
|
||||
header = table + unicode_table;
|
||||
|
||||
unsigned short format = qFromBigEndian<quint16>(header);
|
||||
unsigned int length;
|
||||
if(format < 8)
|
||||
length = qFromBigEndian<quint16>(header + 2);
|
||||
else
|
||||
length = qFromBigEndian<quint32>(header + 4);
|
||||
quint16 format;
|
||||
if (!qSafeFromBigEndian(header, endPtr, &format))
|
||||
return 0;
|
||||
|
||||
quint32 length;
|
||||
if (format < 8) {
|
||||
quint16 tmp;
|
||||
if (!qSafeFromBigEndian(header + 2, endPtr, &tmp))
|
||||
return 0;
|
||||
length = tmp;
|
||||
} else {
|
||||
if (!qSafeFromBigEndian(header + 4, endPtr, &length))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (table + unicode_table + length > endPtr)
|
||||
return 0;
|
||||
@ -1215,7 +1274,7 @@ resolveTable:
|
||||
// Check that none of the latin1 range are in the unicode table
|
||||
bool unicodeTableHasLatin1 = false;
|
||||
for (int uc=0x00; uc<0x100; ++uc) {
|
||||
if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
|
||||
if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
|
||||
unicodeTableHasLatin1 = true;
|
||||
break;
|
||||
}
|
||||
@ -1225,7 +1284,7 @@ resolveTable:
|
||||
bool unicodeTableHasSymbols = false;
|
||||
if (!unicodeTableHasLatin1) {
|
||||
for (int uc=0xf000; uc<0xf100; ++uc) {
|
||||
if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
|
||||
if (getTrueTypeGlyphIndex(selectedTable, length, uc) != 0) {
|
||||
unicodeTableHasSymbols = true;
|
||||
break;
|
||||
}
|
||||
@ -1243,12 +1302,17 @@ resolveTable:
|
||||
return table + unicode_table;
|
||||
}
|
||||
|
||||
quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
|
||||
quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode)
|
||||
{
|
||||
unsigned short format = qFromBigEndian<quint16>(cmap);
|
||||
const uchar *end = cmap + cmapSize;
|
||||
quint16 format;
|
||||
if (!qSafeFromBigEndian(cmap, end, &format))
|
||||
return 0;
|
||||
|
||||
if (format == 0) {
|
||||
if (unicode < 256)
|
||||
return (int) *(cmap+6+unicode);
|
||||
const uchar *ptr = cmap + 6 + unicode;
|
||||
if (unicode < 256 && ptr < end)
|
||||
return quint32(*ptr);
|
||||
} else if (format == 4) {
|
||||
/* some fonts come with invalid cmap tables, where the last segment
|
||||
specified end = start = rangeoffset = 0xffff, delta = 0x0001
|
||||
@ -1257,25 +1321,49 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
|
||||
*/
|
||||
if(unicode >= 0xffff)
|
||||
return 0;
|
||||
quint16 segCountX2 = qFromBigEndian<quint16>(cmap + 6);
|
||||
|
||||
quint16 segCountX2;
|
||||
if (!qSafeFromBigEndian(cmap + 6, end, &segCountX2))
|
||||
return 0;
|
||||
|
||||
const unsigned char *ends = cmap + 14;
|
||||
|
||||
int i = 0;
|
||||
for (; i < segCountX2/2 && qFromBigEndian<quint16>(ends + 2*i) < unicode; i++) {}
|
||||
for (; i < segCountX2/2; ++i) {
|
||||
quint16 codePoint;
|
||||
if (!qSafeFromBigEndian(ends + 2 * i, end, &codePoint))
|
||||
return 0;
|
||||
if (codePoint >= unicode)
|
||||
break;
|
||||
}
|
||||
|
||||
const unsigned char *idx = ends + segCountX2 + 2 + 2*i;
|
||||
quint16 startIndex = qFromBigEndian<quint16>(idx);
|
||||
|
||||
quint16 startIndex;
|
||||
if (!qSafeFromBigEndian(idx, end, &startIndex))
|
||||
return 0;
|
||||
if (startIndex > unicode)
|
||||
return 0;
|
||||
|
||||
idx += segCountX2;
|
||||
qint16 idDelta = (qint16)qFromBigEndian<quint16>(idx);
|
||||
|
||||
quint16 tmp;
|
||||
if (!qSafeFromBigEndian(idx, end, &tmp))
|
||||
return 0;
|
||||
qint16 idDelta = qint16(tmp);
|
||||
|
||||
idx += segCountX2;
|
||||
quint16 idRangeoffset_t = (quint16)qFromBigEndian<quint16>(idx);
|
||||
|
||||
quint16 idRangeoffset_t;
|
||||
if (!qSafeFromBigEndian(idx, end, &idRangeoffset_t))
|
||||
return 0;
|
||||
|
||||
quint16 glyphIndex;
|
||||
if (idRangeoffset_t) {
|
||||
quint16 id = qFromBigEndian<quint16>(idRangeoffset_t + 2*(unicode - startIndex) + idx);
|
||||
quint16 id;
|
||||
if (!qSafeFromBigEndian(idRangeoffset_t + 2 * (unicode - startIndex) + idx, end, &id))
|
||||
return 0;
|
||||
|
||||
if (id)
|
||||
glyphIndex = (idDelta + id) % 0x10000;
|
||||
else
|
||||
@ -1285,13 +1373,19 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
|
||||
}
|
||||
return glyphIndex;
|
||||
} else if (format == 6) {
|
||||
quint16 tableSize = qFromBigEndian<quint16>(cmap + 2);
|
||||
quint16 tableSize;
|
||||
if (!qSafeFromBigEndian(cmap + 2, end, &tableSize))
|
||||
return 0;
|
||||
|
||||
quint16 firstCode6 = qFromBigEndian<quint16>(cmap + 6);
|
||||
quint16 firstCode6;
|
||||
if (!qSafeFromBigEndian(cmap + 6, end, &firstCode6))
|
||||
return 0;
|
||||
if (unicode < firstCode6)
|
||||
return 0;
|
||||
|
||||
quint16 entryCount6 = qFromBigEndian<quint16>(cmap + 8);
|
||||
quint16 entryCount6;
|
||||
if (!qSafeFromBigEndian(cmap + 8, end, &entryCount6))
|
||||
return 0;
|
||||
if (entryCount6 * 2 + 10 > tableSize)
|
||||
return 0;
|
||||
|
||||
@ -1300,9 +1394,14 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
|
||||
return 0;
|
||||
|
||||
quint16 entryIndex6 = unicode - firstCode6;
|
||||
return qFromBigEndian<quint16>(cmap + 10 + (entryIndex6 * 2));
|
||||
|
||||
quint16 index = 0;
|
||||
qSafeFromBigEndian(cmap + 10 + (entryIndex6 * 2), end, &index);
|
||||
return index;
|
||||
} else if (format == 12) {
|
||||
quint32 nGroups = qFromBigEndian<quint32>(cmap + 12);
|
||||
quint32 nGroups;
|
||||
if (!qSafeFromBigEndian(cmap + 12, end, &nGroups))
|
||||
return 0;
|
||||
|
||||
cmap += 16; // move to start of groups
|
||||
|
||||
@ -1310,13 +1409,24 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode)
|
||||
while (left <= right) {
|
||||
int middle = left + ( ( right - left ) >> 1 );
|
||||
|
||||
quint32 startCharCode = qFromBigEndian<quint32>(cmap + 12*middle);
|
||||
quint32 startCharCode;
|
||||
if (!qSafeFromBigEndian(cmap + 12 * middle, end, &startCharCode))
|
||||
return 0;
|
||||
|
||||
if(unicode < startCharCode)
|
||||
right = middle - 1;
|
||||
else {
|
||||
quint32 endCharCode = qFromBigEndian<quint32>(cmap + 12*middle + 4);
|
||||
if(unicode <= endCharCode)
|
||||
return qFromBigEndian<quint32>(cmap + 12*middle + 8) + unicode - startCharCode;
|
||||
quint32 endCharCode;
|
||||
if (!qSafeFromBigEndian(cmap + 12 * middle + 4, end, &endCharCode))
|
||||
return 0;
|
||||
|
||||
if (unicode <= endCharCode) {
|
||||
quint32 index;
|
||||
if (!qSafeFromBigEndian(cmap + 12 * middle + 8, end, &index))
|
||||
return 0;
|
||||
|
||||
return index + unicode - startCharCode;
|
||||
}
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ public:
|
||||
QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform) const;
|
||||
|
||||
static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
|
||||
static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode);
|
||||
static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode);
|
||||
|
||||
static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily);
|
||||
|
||||
|
@ -322,9 +322,9 @@ bool QFontEngineQPF2::getSfntTableData(uint tag, uchar *buffer, uint *length) co
|
||||
|
||||
glyph_t QFontEngineQPF2::glyphIndex(uint ucs4) const
|
||||
{
|
||||
glyph_t glyph = getTrueTypeGlyphIndex(cmap, ucs4);
|
||||
glyph_t glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
|
||||
if (glyph == 0 && symbol && ucs4 < 0x100)
|
||||
glyph = getTrueTypeGlyphIndex(cmap, ucs4 + 0xf000);
|
||||
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
|
||||
if (!findGlyph(glyph))
|
||||
glyph = 0;
|
||||
|
||||
@ -348,16 +348,16 @@ bool QFontEngineQPF2::stringToCMap(const QChar *str, int len, QGlyphLayout *glyp
|
||||
QStringIterator it(str, str + len);
|
||||
while (it.hasNext()) {
|
||||
const uint uc = it.next();
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
|
||||
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
|
||||
++glyph_pos;
|
||||
}
|
||||
} else {
|
||||
QStringIterator it(str, str + len);
|
||||
while (it.hasNext()) {
|
||||
const uint uc = it.next();
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
|
||||
#if 0 && defined(DEBUG_FONTENGINE)
|
||||
QChar c(uc);
|
||||
if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
|
||||
|
@ -1656,8 +1656,8 @@ namespace {
|
||||
bool checkFullOtherwiseExtend(QScriptLine &line);
|
||||
|
||||
QFixed calculateNewWidth(const QScriptLine &line) const {
|
||||
return line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth
|
||||
- qMin(rightBearing, QFixed());
|
||||
return line.textWidth + tmpData.textWidth + spaceData.textWidth
|
||||
+ softHyphenWidth + negativeRightBearing();
|
||||
}
|
||||
|
||||
inline glyph_t currentGlyph() const
|
||||
@ -1677,33 +1677,51 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
inline void adjustRightBearing(glyph_t glyph)
|
||||
inline void calculateRightBearing(glyph_t glyph)
|
||||
{
|
||||
qreal rb;
|
||||
fontEngine->getGlyphBearings(glyph, 0, &rb);
|
||||
rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
|
||||
|
||||
// We only care about negative right bearings, so we limit the range
|
||||
// of the bearing here so that we can assume it's negative in the rest
|
||||
// of the code, as well ase use QFixed(1) as a sentinel to represent
|
||||
// the state where we have yet to compute the right bearing.
|
||||
rightBearing = qMin(QFixed::fromReal(rb), QFixed(0));
|
||||
}
|
||||
|
||||
inline void adjustRightBearing()
|
||||
inline void calculateRightBearing()
|
||||
{
|
||||
if (currentPosition <= 0)
|
||||
return;
|
||||
adjustRightBearing(currentGlyph());
|
||||
calculateRightBearing(currentGlyph());
|
||||
}
|
||||
|
||||
inline void adjustPreviousRightBearing()
|
||||
inline void calculateRightBearingForPreviousGlyph()
|
||||
{
|
||||
if (previousGlyph > 0)
|
||||
adjustRightBearing(previousGlyph);
|
||||
calculateRightBearing(previousGlyph);
|
||||
}
|
||||
|
||||
static const QFixed RightBearingNotCalculated;
|
||||
|
||||
inline void resetRightBearing()
|
||||
{
|
||||
rightBearing = QFixed(1); // Any positive number is defined as invalid since only
|
||||
// negative right bearings are interesting to us.
|
||||
rightBearing = RightBearingNotCalculated;
|
||||
}
|
||||
|
||||
// We express the negative right bearing as an absolute number
|
||||
// so that it can be applied to the width using addition.
|
||||
inline QFixed negativeRightBearing() const
|
||||
{
|
||||
if (rightBearing == RightBearingNotCalculated)
|
||||
return QFixed(0);
|
||||
|
||||
return qAbs(rightBearing);
|
||||
}
|
||||
};
|
||||
|
||||
const QFixed LineBreakHelper::RightBearingNotCalculated = QFixed(1);
|
||||
|
||||
inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line)
|
||||
{
|
||||
LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal());
|
||||
@ -1856,7 +1874,7 @@ void QTextLine::layout_helper(int maxGlyphs)
|
||||
current, lbh.logClusters, lbh.glyphs);
|
||||
} else {
|
||||
lbh.tmpData.length++;
|
||||
lbh.adjustPreviousRightBearing();
|
||||
lbh.calculateRightBearingForPreviousGlyph();
|
||||
}
|
||||
line += lbh.tmpData;
|
||||
goto found;
|
||||
@ -1938,22 +1956,29 @@ void QTextLine::layout_helper(int maxGlyphs)
|
||||
lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
|
||||
}
|
||||
|
||||
// The actual width of the text needs to take the right bearing into account. The
|
||||
// right bearing is left-ward, which means that if the rightmost pixel is to the right
|
||||
// of the advance of the glyph, the bearing will be negative. We flip the sign
|
||||
// for the code to be more readable. Logic borrowed from qfontmetrics.cpp.
|
||||
// We ignore the right bearing if the minimum negative bearing is too little to
|
||||
// expand the text beyond the edge.
|
||||
if (sb_or_ws|breakany) {
|
||||
QFixed rightBearing = lbh.rightBearing; // store previous right bearing
|
||||
// To compute the final width of the text we need to take negative right bearing
|
||||
// into account (negative right bearing means the glyph has pixel data past the
|
||||
// advance length). Note that the negative right bearing is an absolute number,
|
||||
// so that we can apply it to the width using straight forward addition.
|
||||
|
||||
// Store previous right bearing (for the already accepted glyph) in case we
|
||||
// end up breaking due to the current glyph being too wide.
|
||||
QFixed previousRightBearing = lbh.rightBearing;
|
||||
|
||||
// We ignore the right bearing if the minimum negative bearing is too little to
|
||||
// expand the text beyond the edge.
|
||||
if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width)
|
||||
lbh.adjustRightBearing();
|
||||
lbh.calculateRightBearing();
|
||||
|
||||
if (lbh.checkFullOtherwiseExtend(line)) {
|
||||
// we are too wide, fix right bearing
|
||||
if (rightBearing <= 0)
|
||||
lbh.rightBearing = rightBearing; // take from cache
|
||||
// We are too wide to accept the next glyph with its bearing, so we restore the
|
||||
// right bearing to that of the previous glyph (the one that was already accepted),
|
||||
// so that the bearing can be be applied to the final width of the text below.
|
||||
if (previousRightBearing != LineBreakHelper::RightBearingNotCalculated)
|
||||
lbh.rightBearing = previousRightBearing;
|
||||
else
|
||||
lbh.adjustPreviousRightBearing();
|
||||
lbh.calculateRightBearingForPreviousGlyph();
|
||||
|
||||
if (!breakany) {
|
||||
line.textWidth += lbh.softHyphenWidth;
|
||||
@ -1970,10 +1995,14 @@ void QTextLine::layout_helper(int maxGlyphs)
|
||||
LB_DEBUG("reached end of line");
|
||||
lbh.checkFullOtherwiseExtend(line);
|
||||
found:
|
||||
if (lbh.rightBearing > 0 && !lbh.whiteSpaceOrObject) // If right bearing has not yet been adjusted
|
||||
lbh.adjustRightBearing();
|
||||
line.textAdvance = line.textWidth;
|
||||
line.textWidth -= qMin(QFixed(), lbh.rightBearing);
|
||||
|
||||
// If right bearing has not been calculated yet, do that now
|
||||
if (lbh.rightBearing == LineBreakHelper::RightBearingNotCalculated && !lbh.whiteSpaceOrObject)
|
||||
lbh.calculateRightBearing();
|
||||
|
||||
// Then apply any negative right bearing
|
||||
line.textWidth += lbh.negativeRightBearing();
|
||||
|
||||
if (line.length == 0) {
|
||||
LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f",
|
||||
|
@ -971,7 +971,6 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest()
|
||||
for (int i = 0; i < channelCount; ++i) {
|
||||
if (channels[i].resendCurrent && (channels[i].state != QHttpNetworkConnectionChannel::ClosingState)) {
|
||||
channels[i].resendCurrent = false;
|
||||
channels[i].state = QHttpNetworkConnectionChannel::IdleState;
|
||||
|
||||
// if this is not possible, error will be emitted and connection terminated
|
||||
if (!channels[i].resetUploadData())
|
||||
|
@ -58,6 +58,11 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
// TODO: Put channel specific stuff here so it does not polute qhttpnetworkconnection.cpp
|
||||
|
||||
// Because in-flight when sending a request, the server might close our connection (because the persistent HTTP
|
||||
// connection times out)
|
||||
// We use 3 because we can get a _q_error 3 times depending on the timing:
|
||||
static const int reconnectAttemptsDefault = 3;
|
||||
|
||||
QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
|
||||
: socket(0)
|
||||
, ssl(false)
|
||||
@ -69,7 +74,7 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
|
||||
, resendCurrent(false)
|
||||
, lastStatus(0)
|
||||
, pendingEncrypt(false)
|
||||
, reconnectAttempts(2)
|
||||
, reconnectAttempts(reconnectAttemptsDefault)
|
||||
, authMethod(QAuthenticatorPrivate::None)
|
||||
, proxyAuthMethod(QAuthenticatorPrivate::None)
|
||||
, authenticationCredentialsSent(false)
|
||||
@ -106,19 +111,18 @@ void QHttpNetworkConnectionChannel::init()
|
||||
socket->setProxy(QNetworkProxy::NoProxy);
|
||||
#endif
|
||||
|
||||
// We want all signals (except the interactive ones) be connected as QueuedConnection
|
||||
// because else we're falling into cases where we recurse back into the socket code
|
||||
// and mess up the state. Always going to the event loop (and expecting that when reading/writing)
|
||||
// is safer.
|
||||
// After some back and forth in all the last years, this is now a DirectConnection because otherwise
|
||||
// the state inside the *Socket classes gets messed up, also in conjunction with the socket notifiers
|
||||
// which behave slightly differently on Windows vs Linux
|
||||
QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
|
||||
this, SLOT(_q_bytesWritten(qint64)),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
QObject::connect(socket, SIGNAL(connected()),
|
||||
this, SLOT(_q_connected()),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
QObject::connect(socket, SIGNAL(readyRead()),
|
||||
this, SLOT(_q_readyRead()),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
|
||||
// The disconnected() and error() signals may already come
|
||||
// while calling connectToHost().
|
||||
@ -129,10 +133,10 @@ void QHttpNetworkConnectionChannel::init()
|
||||
qRegisterMetaType<QAbstractSocket::SocketError>();
|
||||
QObject::connect(socket, SIGNAL(disconnected()),
|
||||
this, SLOT(_q_disconnected()),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this, SLOT(_q_error(QAbstractSocket::SocketError)),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
@ -147,7 +151,7 @@ void QHttpNetworkConnectionChannel::init()
|
||||
// won't be a sslSocket if encrypt is false
|
||||
QObject::connect(sslSocket, SIGNAL(encrypted()),
|
||||
this, SLOT(_q_encrypted()),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
QObject::connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)),
|
||||
this, SLOT(_q_sslErrors(QList<QSslError>)),
|
||||
Qt::DirectConnection);
|
||||
@ -156,7 +160,7 @@ void QHttpNetworkConnectionChannel::init()
|
||||
Qt::DirectConnection);
|
||||
QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)),
|
||||
this, SLOT(_q_encryptedBytesWritten(qint64)),
|
||||
Qt::QueuedConnection);
|
||||
Qt::DirectConnection);
|
||||
|
||||
if (ignoreAllSslErrors)
|
||||
sslSocket->ignoreSslErrors();
|
||||
@ -400,7 +404,7 @@ void QHttpNetworkConnectionChannel::allDone()
|
||||
|
||||
// reset the reconnection attempts after we receive a complete reply.
|
||||
// in case of failures, each channel will attempt two reconnects before emitting error.
|
||||
reconnectAttempts = 2;
|
||||
reconnectAttempts = reconnectAttemptsDefault;
|
||||
|
||||
// now the channel can be seen as free/idle again, all signal emissions for the reply have been done
|
||||
if (state != QHttpNetworkConnectionChannel::ClosingState)
|
||||
@ -668,6 +672,15 @@ void QHttpNetworkConnectionChannel::closeAndResendCurrentRequest()
|
||||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void QHttpNetworkConnectionChannel::resendCurrentRequest()
|
||||
{
|
||||
requeueCurrentlyPipelinedRequests();
|
||||
if (reply)
|
||||
resendCurrent = true;
|
||||
if (qobject_cast<QHttpNetworkConnection*>(connection))
|
||||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
bool QHttpNetworkConnectionChannel::isSocketBusy() const
|
||||
{
|
||||
return (state & QHttpNetworkConnectionChannel::BusyState);
|
||||
@ -711,8 +724,8 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
|
||||
return;
|
||||
}
|
||||
|
||||
// read the available data before closing
|
||||
if (isSocketWaiting() || isSocketReading()) {
|
||||
// read the available data before closing (also done in _q_error for other codepaths)
|
||||
if ((isSocketWaiting() || isSocketReading()) && socket->bytesAvailable()) {
|
||||
if (reply) {
|
||||
state = QHttpNetworkConnectionChannel::ReadingState;
|
||||
_q_receiveReply();
|
||||
@ -724,7 +737,8 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
|
||||
state = QHttpNetworkConnectionChannel::IdleState;
|
||||
|
||||
requeueCurrentlyPipelinedRequests();
|
||||
close();
|
||||
|
||||
pendingEncrypt = false;
|
||||
}
|
||||
|
||||
|
||||
@ -806,11 +820,19 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
errorCode = QNetworkReply::ConnectionRefusedError;
|
||||
break;
|
||||
case QAbstractSocket::RemoteHostClosedError:
|
||||
// try to reconnect/resend before sending an error.
|
||||
// while "Reading" the _q_disconnected() will handle this.
|
||||
if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) {
|
||||
// This error for SSL comes twice in a row, first from SSL layer ("The TLS/SSL connection has been closed") then from TCP layer.
|
||||
// Depending on timing it can also come three times in a row (first time when we try to write into a closing QSslSocket).
|
||||
// The reconnectAttempts handling catches the cases where we can re-send the request.
|
||||
if (!reply && state == QHttpNetworkConnectionChannel::IdleState) {
|
||||
// Not actually an error, it is normal for Keep-Alive connections to close after some time if no request
|
||||
// is sent on them. No need to error the other replies below. Just bail out here.
|
||||
// The _q_disconnected will handle the possibly pipelined replies
|
||||
return;
|
||||
} else if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) {
|
||||
// Try to reconnect/resend before sending an error.
|
||||
// While "Reading" the _q_disconnected() will handle this.
|
||||
if (reconnectAttempts-- > 0) {
|
||||
closeAndResendCurrentRequest();
|
||||
resendCurrentRequest();
|
||||
return;
|
||||
} else {
|
||||
errorCode = QNetworkReply::RemoteHostClosedError;
|
||||
@ -821,11 +843,15 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
|
||||
if (!reply->d_func()->expectContent()) {
|
||||
// No content expected, this is a valid way to have the connection closed by the server
|
||||
// We need to invoke this asynchronously to make sure the state() of the socket is on QAbstractSocket::UnconnectedState
|
||||
QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
if (reply->contentLength() == -1 && !reply->d_func()->isChunked()) {
|
||||
// There was no content-length header and it's not chunked encoding,
|
||||
// so this is a valid way to have the connection closed by the server
|
||||
// We need to invoke this asynchronously to make sure the state() of the socket is on QAbstractSocket::UnconnectedState
|
||||
QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
// ok, we got a disconnect even though we did not expect it
|
||||
@ -835,24 +861,15 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
// we can ignore the readbuffersize as the data is already
|
||||
// in memory and we will not receive more data on the socket.
|
||||
reply->setReadBufferSize(0);
|
||||
reply->setDownstreamLimited(false);
|
||||
_q_receiveReply();
|
||||
#ifndef QT_NO_SSL
|
||||
if (ssl) {
|
||||
// QT_NO_OPENSSL. The QSslSocket can still have encrypted bytes in the plainsocket.
|
||||
// So we need to check this if the socket is a QSslSocket. When the socket is flushed
|
||||
// it will force a decrypt of the encrypted data in the plainsocket.
|
||||
QSslSocket *sslSocket = static_cast<QSslSocket*>(socket);
|
||||
qint64 beforeFlush = sslSocket->encryptedBytesAvailable();
|
||||
while (sslSocket->encryptedBytesAvailable()) {
|
||||
sslSocket->flush();
|
||||
_q_receiveReply();
|
||||
qint64 afterFlush = sslSocket->encryptedBytesAvailable();
|
||||
if (afterFlush == beforeFlush)
|
||||
break;
|
||||
beforeFlush = afterFlush;
|
||||
}
|
||||
if (!reply) {
|
||||
// No more reply assigned after the previous call? Then it had been finished successfully.
|
||||
requeueCurrentlyPipelinedRequests();
|
||||
state = QHttpNetworkConnectionChannel::IdleState;
|
||||
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
errorCode = QNetworkReply::RemoteHostClosedError;
|
||||
@ -863,7 +880,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
case QAbstractSocket::SocketTimeoutError:
|
||||
// try to reconnect/resend before sending an error.
|
||||
if (state == QHttpNetworkConnectionChannel::WritingState && (reconnectAttempts-- > 0)) {
|
||||
closeAndResendCurrentRequest();
|
||||
resendCurrentRequest();
|
||||
return;
|
||||
}
|
||||
errorCode = QNetworkReply::TimeoutError;
|
||||
@ -877,7 +894,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
case QAbstractSocket::ProxyConnectionClosedError:
|
||||
// try to reconnect/resend before sending an error.
|
||||
if (reconnectAttempts-- > 0) {
|
||||
closeAndResendCurrentRequest();
|
||||
resendCurrentRequest();
|
||||
return;
|
||||
}
|
||||
errorCode = QNetworkReply::ProxyConnectionClosedError;
|
||||
@ -885,7 +902,7 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
case QAbstractSocket::ProxyConnectionTimeoutError:
|
||||
// try to reconnect/resend before sending an error.
|
||||
if (reconnectAttempts-- > 0) {
|
||||
closeAndResendCurrentRequest();
|
||||
resendCurrentRequest();
|
||||
return;
|
||||
}
|
||||
errorCode = QNetworkReply::ProxyTimeoutError;
|
||||
@ -933,8 +950,18 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
|
||||
// send the next request
|
||||
QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
|
||||
|
||||
if (that) //signal emission triggered event loop
|
||||
close();
|
||||
if (that) {
|
||||
//signal emission triggered event loop
|
||||
if (!socket)
|
||||
state = QHttpNetworkConnectionChannel::IdleState;
|
||||
else if (socket->state() == QAbstractSocket::UnconnectedState)
|
||||
state = QHttpNetworkConnectionChannel::IdleState;
|
||||
else
|
||||
state = QHttpNetworkConnectionChannel::ClosingState;
|
||||
|
||||
// pendingEncrypt must only be true in between connected and encrypted states
|
||||
pendingEncrypt = false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_NETWORKPROXY
|
||||
@ -958,7 +985,8 @@ void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetwor
|
||||
|
||||
void QHttpNetworkConnectionChannel::_q_uploadDataReadyRead()
|
||||
{
|
||||
sendRequest();
|
||||
if (reply)
|
||||
sendRequest();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
|
@ -169,6 +169,7 @@ public:
|
||||
|
||||
void handleUnexpectedEOF();
|
||||
void closeAndResendCurrentRequest();
|
||||
void resendCurrentRequest();
|
||||
|
||||
bool isSocketBusy() const;
|
||||
bool isSocketWriting() const;
|
||||
|
@ -208,7 +208,7 @@ QByteArray QHttpNetworkReply::readAny()
|
||||
return QByteArray();
|
||||
|
||||
// we'll take the last buffer, so schedule another read from http
|
||||
if (d->downstreamLimited && d->responseData.bufferCount() == 1)
|
||||
if (d->downstreamLimited && d->responseData.bufferCount() == 1 && !isFinished())
|
||||
d->connection->d_func()->readMoreLater(this);
|
||||
return d->responseData.read();
|
||||
}
|
||||
|
@ -237,7 +237,12 @@ void QHttpProtocolHandler::_q_readyRead()
|
||||
}
|
||||
|
||||
if (m_channel->isSocketWaiting() || m_channel->isSocketReading()) {
|
||||
m_channel->state = QHttpNetworkConnectionChannel::ReadingState;
|
||||
if (m_socket->bytesAvailable()) {
|
||||
// We might get a spurious call from readMoreLater()
|
||||
// call of the QHttpNetworkConnection even while the socket is disconnecting.
|
||||
// Therefore check if there is actually bytes available before changing the channel state.
|
||||
m_channel->state = QHttpNetworkConnectionChannel::ReadingState;
|
||||
}
|
||||
if (m_reply)
|
||||
_q_receiveReply();
|
||||
}
|
||||
@ -250,7 +255,6 @@ bool QHttpProtocolHandler::sendRequest()
|
||||
if (!m_reply) {
|
||||
// heh, how should that happen!
|
||||
qWarning() << "QAbstractProtocolHandler::sendRequest() called without QHttpNetworkReply";
|
||||
m_channel->state = QHttpNetworkConnectionChannel::IdleState;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -466,15 +466,18 @@ QList<QBearerEngine *> QNetworkConfigurationManagerPrivate::engines() const
|
||||
void QNetworkConfigurationManagerPrivate::startPolling()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if(!pollTimer) {
|
||||
if (!pollTimer) {
|
||||
pollTimer = new QTimer(this);
|
||||
pollTimer->setInterval(10000);
|
||||
bool ok;
|
||||
int interval = qgetenv("QT_BEARER_POLL_TIMEOUT").toInt(&ok);
|
||||
if (!ok)
|
||||
interval = 10000;//default 10 seconds
|
||||
pollTimer->setInterval(interval);
|
||||
pollTimer->setSingleShot(true);
|
||||
connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines()));
|
||||
}
|
||||
|
||||
if(pollTimer->isActive())
|
||||
if (pollTimer->isActive())
|
||||
return;
|
||||
|
||||
foreach (QBearerEngine *engine, sessionEngines) {
|
||||
@ -483,6 +486,7 @@ void QNetworkConfigurationManagerPrivate::startPolling()
|
||||
break;
|
||||
}
|
||||
}
|
||||
performAsyncConfigurationUpdate();
|
||||
}
|
||||
|
||||
void QNetworkConfigurationManagerPrivate::pollEngines()
|
||||
|
@ -774,6 +774,7 @@ bool QAbstractSocketPrivate::canReadNotification()
|
||||
void QAbstractSocketPrivate::canCloseNotification()
|
||||
{
|
||||
Q_Q(QAbstractSocket);
|
||||
// Note that this method is only called on Windows. Other platforms close in the canReadNotification()
|
||||
|
||||
#if defined (QABSTRACTSOCKET_DEBUG)
|
||||
qDebug("QAbstractSocketPrivate::canCloseNotification()");
|
||||
@ -783,7 +784,11 @@ void QAbstractSocketPrivate::canCloseNotification()
|
||||
if (isBuffered) {
|
||||
// Try to read to the buffer, if the read fail we can close the socket.
|
||||
newBytes = buffer.size();
|
||||
if (!readFromSocket()) {
|
||||
qint64 oldReadBufferMaxSize = readBufferMaxSize;
|
||||
readBufferMaxSize = 0; // temporarily disable max read buffer, we want to empty the OS buffer
|
||||
bool hadReadFromSocket = readFromSocket();
|
||||
readBufferMaxSize = oldReadBufferMaxSize;
|
||||
if (!hadReadFromSocket) {
|
||||
q->disconnectFromHost();
|
||||
return;
|
||||
}
|
||||
|
@ -2408,6 +2408,14 @@ void QSslSocketPrivate::_q_errorSlot(QAbstractSocket::SocketError error)
|
||||
qCDebug(lcSsl) << "\tstate =" << q->state();
|
||||
qCDebug(lcSsl) << "\terrorString =" << q->errorString();
|
||||
#endif
|
||||
// this moves encrypted bytes from plain socket into our buffer
|
||||
if (plainSocket->bytesAvailable()) {
|
||||
qint64 tmpReadBufferMaxSize = readBufferMaxSize;
|
||||
readBufferMaxSize = 0; // reset temporarily so the plain sockets completely drained drained
|
||||
transmit();
|
||||
readBufferMaxSize = tmpReadBufferMaxSize;
|
||||
}
|
||||
|
||||
q->setSocketError(plainSocket->error());
|
||||
q->setErrorString(plainSocket->errorString());
|
||||
emit q->error(error);
|
||||
|
@ -1513,6 +1513,13 @@ void QSslSocketBackendPrivate::disconnected()
|
||||
{
|
||||
if (plainSocket->bytesAvailable() <= 0)
|
||||
destroySslContext();
|
||||
else {
|
||||
// Move all bytes into the plain buffer
|
||||
qint64 tmpReadBufferMaxSize = readBufferMaxSize;
|
||||
readBufferMaxSize = 0; // reset temporarily so the plain socket buffer is completely drained
|
||||
transmit();
|
||||
readBufferMaxSize = tmpReadBufferMaxSize;
|
||||
}
|
||||
//if there is still buffered data in the plain socket, don't destroy the ssl context yet.
|
||||
//it will be destroyed when the socket is deleted.
|
||||
}
|
||||
|
@ -241,7 +241,8 @@ void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLCon
|
||||
|
||||
void QEGLPlatformContext::initialize()
|
||||
{
|
||||
updateFormatFromGL();
|
||||
if (m_eglContext != EGL_NO_CONTEXT)
|
||||
updateFormatFromGL();
|
||||
}
|
||||
|
||||
// Base implementation for pbuffers. Subclasses will handle the specialized cases for
|
||||
|
@ -44,6 +44,8 @@ QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
|
||||
|
||||
QCocoaBackingStore::~QCocoaBackingStore()
|
||||
{
|
||||
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()))
|
||||
[cocoaWindow->m_qtView clearBackingStore:this];
|
||||
}
|
||||
|
||||
QPaintDevice *QCocoaBackingStore::paintDevice()
|
||||
|
@ -51,8 +51,7 @@ QT_END_NAMESPACE
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> {
|
||||
QImage m_backingStore;
|
||||
qreal m_pixelRatio;
|
||||
QCocoaBackingStore* m_backingStore;
|
||||
QPoint m_backingStoreOffset;
|
||||
CGImageRef m_maskImage;
|
||||
uchar *m_maskData;
|
||||
@ -86,6 +85,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
||||
- (void)setQCocoaGLContext:(QCocoaGLContext *)context;
|
||||
#endif
|
||||
- (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset;
|
||||
- (void)clearBackingStore:(QCocoaBackingStore *)backingStore;
|
||||
- (void)setMaskRegion:(const QRegion *)region;
|
||||
- (void)invalidateWindowShadowIfNeeded;
|
||||
- (void)drawRect:(NSRect)dirtyRect;
|
||||
|
@ -134,7 +134,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
{
|
||||
self = [super initWithFrame : NSMakeRect(0,0, 300,300)];
|
||||
if (self) {
|
||||
m_pixelRatio = 1.;
|
||||
m_backingStore = 0;
|
||||
m_maskImage = 0;
|
||||
m_shouldInvalidateWindowShadow = false;
|
||||
m_window = 0;
|
||||
@ -376,7 +376,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
if (!m_platformWindow->m_inSetGeometry)
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
else
|
||||
m_backingStore = QImage();
|
||||
m_backingStore = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -481,12 +481,16 @@ QT_WARNING_POP
|
||||
|
||||
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
|
||||
{
|
||||
m_backingStore = backingStore->toImage();
|
||||
m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio();
|
||||
m_backingStoreOffset = offset * m_pixelRatio;
|
||||
foreach (QRect rect, region.rects()) {
|
||||
m_backingStore = backingStore;
|
||||
m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
|
||||
foreach (QRect rect, region.rects())
|
||||
[self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)clearBackingStore:(QCocoaBackingStore *)backingStore
|
||||
{
|
||||
if (backingStore == m_backingStore)
|
||||
m_backingStore = 0;
|
||||
}
|
||||
|
||||
- (BOOL) hasMask
|
||||
@ -549,7 +553,7 @@ QT_WARNING_POP
|
||||
if (m_platformWindow->m_drawContentBorderGradient)
|
||||
NSDrawWindowBackground(dirtyRect);
|
||||
|
||||
if (m_backingStore.isNull())
|
||||
if (!m_backingStore)
|
||||
return;
|
||||
|
||||
// Calculate source and target rects. The target rect is the dirtyRect:
|
||||
@ -557,10 +561,11 @@ QT_WARNING_POP
|
||||
|
||||
// The backing store source rect will be larger on retina displays.
|
||||
// Scale dirtyRect by the device pixel ratio:
|
||||
CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * m_pixelRatio,
|
||||
dirtyRect.origin.y * m_pixelRatio,
|
||||
dirtyRect.size.width * m_pixelRatio,
|
||||
dirtyRect.size.height * m_pixelRatio);
|
||||
const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio();
|
||||
CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio,
|
||||
dirtyRect.origin.y * devicePixelRatio,
|
||||
dirtyRect.size.width * devicePixelRatio,
|
||||
dirtyRect.size.height * devicePixelRatio);
|
||||
|
||||
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
|
||||
CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort];
|
||||
@ -586,7 +591,7 @@ QT_WARNING_POP
|
||||
dirtyBackingRect.size.width,
|
||||
dirtyBackingRect.size.height
|
||||
);
|
||||
CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore);
|
||||
CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore->toImage());
|
||||
CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect);
|
||||
|
||||
// Optimization: Copy frame buffer content instead of blending for
|
||||
|
@ -344,6 +344,46 @@
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)sendKeyPressRelease:(Qt::Key)key modifiers:(Qt::KeyboardModifiers)modifiers
|
||||
{
|
||||
QKeyEvent press(QEvent::KeyPress, key, modifiers);
|
||||
QKeyEvent release(QEvent::KeyRelease, key, modifiers);
|
||||
[self sendEventToFocusObject:press];
|
||||
[self sendEventToFocusObject:release];
|
||||
}
|
||||
|
||||
- (void)cut:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
[self sendKeyPressRelease:Qt::Key_X modifiers:Qt::ControlModifier];
|
||||
}
|
||||
|
||||
- (void)copy:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
[self sendKeyPressRelease:Qt::Key_C modifiers:Qt::ControlModifier];
|
||||
}
|
||||
|
||||
- (void)paste:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
[self sendKeyPressRelease:Qt::Key_V modifiers:Qt::ControlModifier];
|
||||
}
|
||||
|
||||
- (void)selectAll:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
[self sendKeyPressRelease:Qt::Key_A modifiers:Qt::ControlModifier];
|
||||
}
|
||||
|
||||
- (void)delete:(id)sender
|
||||
{
|
||||
Q_UNUSED(sender);
|
||||
[self sendKeyPressRelease:Qt::Key_Delete modifiers:Qt::ControlModifier];
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)notifyInputDelegate:(Qt::InputMethodQueries)updatedProperties
|
||||
{
|
||||
// As documented, we should not report textWillChange/textDidChange unless the text
|
||||
@ -560,7 +600,7 @@
|
||||
|
||||
if (cursorPos != int(r.location + r.length) || cursorPos != anchorPos) {
|
||||
attrs = QList<QInputMethodEvent::Attribute>();
|
||||
attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, cursorPos, (cursorPos - anchorPos), 0);
|
||||
attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, qMin(cursorPos, anchorPos), qAbs(cursorPos - anchorPos), 0);
|
||||
e = QInputMethodEvent(m_markedText, attrs);
|
||||
[self sendEventToFocusObject:e];
|
||||
}
|
||||
@ -678,10 +718,7 @@
|
||||
return;
|
||||
|
||||
if ([text isEqualToString:@"\n"]) {
|
||||
QKeyEvent press(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
|
||||
QKeyEvent release(QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier);
|
||||
[self sendEventToFocusObject:press];
|
||||
[self sendEventToFocusObject:release];
|
||||
[self sendKeyPressRelease:Qt::Key_Return modifiers:Qt::NoModifier];
|
||||
|
||||
if (self.returnKeyType == UIReturnKeyDone || self.returnKeyType == UIReturnKeyGo
|
||||
|| self.returnKeyType == UIReturnKeySend || self.returnKeyType == UIReturnKeySearch)
|
||||
@ -700,10 +737,7 @@
|
||||
// Since we're posting im events directly to the focus object, we should do the
|
||||
// same for key events. Otherwise they might end up in a different place or out
|
||||
// of sync with im events.
|
||||
QKeyEvent press(QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier);
|
||||
QKeyEvent release(QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier);
|
||||
[self sendEventToFocusObject:press];
|
||||
[self sendEventToFocusObject:release];
|
||||
[self sendKeyPressRelease:Qt::Key_Backspace modifiers:Qt::NoModifier];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -190,8 +190,9 @@
|
||||
|
||||
- (void)setBounds:(CGRect)newBounds
|
||||
{
|
||||
Q_UNUSED(newBounds);
|
||||
CGRect transformedWindowBounds = [self convertRect:self.window.bounds fromView:self.window];
|
||||
[super setBounds:CGRectMake(0, 0, CGRectGetWidth(newBounds), CGRectGetHeight(transformedWindowBounds))];
|
||||
[super setBounds:CGRectMake(0, 0, CGRectGetWidth(transformedWindowBounds), CGRectGetHeight(transformedWindowBounds))];
|
||||
}
|
||||
|
||||
- (void)setCenter:(CGPoint)newCenter
|
||||
|
@ -181,9 +181,8 @@ void QWindowsFontEngine::getCMap()
|
||||
bool symb = false;
|
||||
if (ttf) {
|
||||
cmapTable = getSfntTable(qbswap<quint32>(MAKE_TAG('c', 'm', 'a', 'p')));
|
||||
int size = 0;
|
||||
cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *>(cmapTable.constData()),
|
||||
cmapTable.size(), &symb, &size);
|
||||
cmapTable.size(), &symb, &cmapSize);
|
||||
}
|
||||
if (!cmap) {
|
||||
ttf = false;
|
||||
@ -218,16 +217,16 @@ int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLa
|
||||
QStringIterator it(str, str + numChars);
|
||||
while (it.hasNext()) {
|
||||
const uint uc = it.next();
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
|
||||
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000);
|
||||
++glyph_pos;
|
||||
}
|
||||
} else if (ttf) {
|
||||
QStringIterator it(str, str + numChars);
|
||||
while (it.hasNext()) {
|
||||
const uint uc = it.next();
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
|
||||
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc);
|
||||
++glyph_pos;
|
||||
}
|
||||
} else {
|
||||
@ -275,6 +274,7 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
|
||||
hasOutline(0),
|
||||
lw(0),
|
||||
cmap(0),
|
||||
cmapSize(0),
|
||||
lbearing(SHRT_MIN),
|
||||
rbearing(SHRT_MIN),
|
||||
x_height(-1),
|
||||
@ -346,11 +346,11 @@ glyph_t QWindowsFontEngine::glyphIndex(uint ucs4) const
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
if (symbol) {
|
||||
glyph = getTrueTypeGlyphIndex(cmap, ucs4);
|
||||
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
|
||||
if (glyph == 0 && ucs4 < 0x100)
|
||||
glyph = getTrueTypeGlyphIndex(cmap, ucs4 + 0xf000);
|
||||
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4 + 0xf000);
|
||||
} else if (ttf) {
|
||||
glyph = getTrueTypeGlyphIndex(cmap, ucs4);
|
||||
glyph = getTrueTypeGlyphIndex(cmap, cmapSize, ucs4);
|
||||
#else
|
||||
if (tm.tmFirstChar > 60000) {
|
||||
glyph = ucs4;
|
||||
|
@ -146,6 +146,7 @@ private:
|
||||
TEXTMETRIC tm;
|
||||
int lw;
|
||||
const unsigned char *cmap;
|
||||
int cmapSize;
|
||||
QByteArray cmapTable;
|
||||
mutable qreal lbearing;
|
||||
mutable qreal rbearing;
|
||||
|
@ -199,18 +199,27 @@ void QWindowsInputContext::reset()
|
||||
doneContext();
|
||||
}
|
||||
|
||||
void QWindowsInputContext::setFocusObject(QObject *object)
|
||||
void QWindowsInputContext::setFocusObject(QObject *)
|
||||
{
|
||||
// ### fixme: On Windows 8.1, it has been observed that the Input context
|
||||
// remains active when this happens resulting in a lock-up. Consecutive
|
||||
// key events still have VK_PROCESSKEY set and are thus ignored.
|
||||
if (m_compositionContext.isComposing)
|
||||
imeNotifyCancelComposition(m_compositionContext.hwnd);
|
||||
reset();
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
void QWindowsInputContext::updateEnabled()
|
||||
{
|
||||
if (!QGuiApplication::focusObject())
|
||||
return;
|
||||
const QWindow *window = QGuiApplication::focusWindow();
|
||||
if (object && window && window->handle()) {
|
||||
if (window && window->handle()) {
|
||||
QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window);
|
||||
if (inputMethodAccepted()) {
|
||||
const bool accepted = inputMethodAccepted();
|
||||
if (QWindowsContext::verbose > 1)
|
||||
qCDebug(lcQpaInputMethods) << __FUNCTION__ << window << "accepted=" << accepted;
|
||||
if (accepted) {
|
||||
// Re-enable IME by associating default context saved on first disabling.
|
||||
if (platformWindow->testFlag(QWindowsWindow::InputMethodDisabled)) {
|
||||
ImmAssociateContext(platformWindow->handle(), QWindowsInputContext::m_defaultContext);
|
||||
@ -234,6 +243,8 @@ void QWindowsInputContext::setFocusObject(QObject *object)
|
||||
|
||||
void QWindowsInputContext::update(Qt::InputMethodQueries queries)
|
||||
{
|
||||
if (queries & Qt::ImEnabled)
|
||||
updateEnabled();
|
||||
QPlatformInputContext::update(queries);
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,7 @@ private:
|
||||
void doneContext();
|
||||
void startContextComposition();
|
||||
void endContextComposition();
|
||||
void updateEnabled();
|
||||
|
||||
const DWORD m_WM_MSIME_MOUSE;
|
||||
static HIMC m_defaultContext;
|
||||
|
@ -990,12 +990,11 @@ QVector<FORMATETC> QWindowsMimeImage::formatsForMime(const QString &mimeType, co
|
||||
{
|
||||
QVector<FORMATETC> formatetcs;
|
||||
if (mimeData->hasImage() && mimeType == QLatin1String("application/x-qt-image")) {
|
||||
//add DIBV5 if image has alpha channel
|
||||
//add DIBV5 if image has alpha channel. Do not add CF_PNG here as it will confuse MS Office (QTBUG47656).
|
||||
QImage image = qvariant_cast<QImage>(mimeData->imageData());
|
||||
if (!image.isNull() && image.hasAlphaChannel())
|
||||
formatetcs += setCf(CF_DIBV5);
|
||||
formatetcs += setCf(CF_DIB);
|
||||
formatetcs += setCf(CF_PNG); // QTBUG-86848, Paste into GIMP queries for PNG.
|
||||
}
|
||||
return formatetcs;
|
||||
}
|
||||
@ -1024,11 +1023,7 @@ bool QWindowsMimeImage::canConvertFromMime(const FORMATETC &formatetc, const QMi
|
||||
const QImage image = qvariant_cast<QImage>(mimeData->imageData());
|
||||
if (image.isNull())
|
||||
return false;
|
||||
// QTBUG-11463, deny CF_DIB support for images with alpha to prevent loss of
|
||||
// transparency in conversion.
|
||||
return cf == CF_DIBV5
|
||||
|| (cf == CF_DIB && !image.hasAlphaChannel())
|
||||
|| cf == int(CF_PNG);
|
||||
return cf == CF_DIBV5 || (cf == CF_DIB) || cf == int(CF_PNG);
|
||||
}
|
||||
|
||||
bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const
|
||||
|
@ -1045,8 +1045,8 @@ void QWindowsWindow::setDropSiteEnabled(bool dropEnabled)
|
||||
RegisterDragDrop(m_data.hwnd, m_dropTarget);
|
||||
CoLockObjectExternal(m_dropTarget, true, true);
|
||||
} else {
|
||||
m_dropTarget->Release();
|
||||
CoLockObjectExternal(m_dropTarget, false, true);
|
||||
m_dropTarget->Release();
|
||||
RevokeDragDrop(m_data.hwnd);
|
||||
m_dropTarget = 0;
|
||||
}
|
||||
|
@ -967,15 +967,6 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
|
||||
xXIGenericDeviceEvent *xiEvent = static_cast<xXIGenericDeviceEvent *>(event);
|
||||
xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(xiEvent);
|
||||
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
// Synthesize mouse events since otherwise there are no mouse events from
|
||||
// the pen on the XI 2.2+ path.
|
||||
if (xi2MouseEvents() && eventListener)
|
||||
eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event));
|
||||
#else
|
||||
Q_UNUSED(eventListener);
|
||||
#endif
|
||||
|
||||
switch (xiEvent->evtype) {
|
||||
case XI_ButtonPress: {
|
||||
Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail);
|
||||
@ -1058,6 +1049,16 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q
|
||||
handled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
// Synthesize mouse events since otherwise there are no mouse events from
|
||||
// the pen on the XI 2.2+ path.
|
||||
if (xi2MouseEvents() && eventListener)
|
||||
eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event));
|
||||
#else
|
||||
Q_UNUSED(eventListener);
|
||||
#endif
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
@ -2208,17 +2208,17 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event)
|
||||
|
||||
switch (ev->evtype) {
|
||||
case XI_ButtonPress:
|
||||
qCDebug(lcQpaXInput, "XI2 mouse press, button %d", button);
|
||||
qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d", button, ev->time);
|
||||
conn->setButton(button, true);
|
||||
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time);
|
||||
break;
|
||||
case XI_ButtonRelease:
|
||||
qCDebug(lcQpaXInput, "XI2 mouse release, button %d", button);
|
||||
qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d", button, ev->time);
|
||||
conn->setButton(button, false);
|
||||
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time);
|
||||
break;
|
||||
case XI_Motion:
|
||||
qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d", event_x, event_y);
|
||||
qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d", event_x, event_y, ev->time);
|
||||
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time);
|
||||
break;
|
||||
default:
|
||||
|
@ -803,7 +803,7 @@ void QUnixPrintWidgetPrivate::applyPrinterProperties()
|
||||
QString cur = QDir::currentPath();
|
||||
if (home.at(home.length()-1) != QLatin1Char('/'))
|
||||
home += QLatin1Char('/');
|
||||
if (cur.at(cur.length()-1) != QLatin1Char('/'))
|
||||
if (!cur.isEmpty() && cur.at(cur.length()-1) != QLatin1Char('/'))
|
||||
cur += QLatin1Char('/');
|
||||
if (cur.left(home.length()) != home)
|
||||
cur = home;
|
||||
|
@ -1332,6 +1332,9 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
|
||||
if (r.isEmpty())
|
||||
r = QSqlDriver::formatValue(field, trimStrings);
|
||||
break;
|
||||
case QVariant::Uuid:
|
||||
r = QLatin1Char('\'') + field.value().toString() + QLatin1Char('\'');
|
||||
break;
|
||||
default:
|
||||
r = QSqlDriver::formatValue(field, trimStrings);
|
||||
break;
|
||||
|
@ -1425,10 +1425,13 @@ QGraphicsItem::~QGraphicsItem()
|
||||
QObjectPrivate *p = QObjectPrivate::get(o);
|
||||
p->wasDeleted = true;
|
||||
if (p->declarativeData) {
|
||||
if (QAbstractDeclarativeData::destroyed)
|
||||
QAbstractDeclarativeData::destroyed(p->declarativeData, o);
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(p->declarativeData, o);
|
||||
if (static_cast<QAbstractDeclarativeDataImpl*>(p->declarativeData)->ownedByQml1) {
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(p->declarativeData, o);
|
||||
} else {
|
||||
if (QAbstractDeclarativeData::destroyed)
|
||||
QAbstractDeclarativeData::destroyed(p->declarativeData, o);
|
||||
}
|
||||
p->declarativeData = 0;
|
||||
}
|
||||
}
|
||||
|
@ -433,6 +433,9 @@ void QTreeView::setRootIsDecorated(bool show)
|
||||
The height is obtained from the first item in the view. It is updated
|
||||
when the data changes on that item.
|
||||
|
||||
\note If the editor size hint is bigger than the cell size hint, then the
|
||||
size hint of the editor will be used.
|
||||
|
||||
By default, this property is \c false.
|
||||
*/
|
||||
bool QTreeView::uniformRowHeights() const
|
||||
|
@ -339,8 +339,7 @@ void QApplicationPrivate::createEventDispatcher()
|
||||
\li Miscellaneous
|
||||
\li closeAllWindows(),
|
||||
startingUp(),
|
||||
closingDown(),
|
||||
type().
|
||||
closingDown().
|
||||
\endtable
|
||||
|
||||
\sa QCoreApplication, QAbstractEventDispatcher, QEventLoop, QSettings
|
||||
|
@ -92,7 +92,7 @@ inline static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
|
||||
be expressed using hasHeightForWidth(), heightForWidth(), and
|
||||
minimumHeightForWidth(). For more explanation see the \e{Qt
|
||||
Quarterly} article
|
||||
\l{http://doc.qt.digia.com/qq/qq04-height-for-width.html}{Trading
|
||||
\l{http://doc.qt.io/archives/qq/qq04-height-for-width.html}{Trading
|
||||
Height for Width}.
|
||||
|
||||
\sa QLayout
|
||||
|
@ -1634,10 +1634,13 @@ QWidget::~QWidget()
|
||||
}
|
||||
|
||||
if (d->declarativeData) {
|
||||
if (QAbstractDeclarativeData::destroyed)
|
||||
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
|
||||
if (static_cast<QAbstractDeclarativeDataImpl*>(d->declarativeData)->ownedByQml1) {
|
||||
if (QAbstractDeclarativeData::destroyed_qml1)
|
||||
QAbstractDeclarativeData::destroyed_qml1(d->declarativeData, this);
|
||||
} else {
|
||||
if (QAbstractDeclarativeData::destroyed)
|
||||
QAbstractDeclarativeData::destroyed(d->declarativeData, this);
|
||||
}
|
||||
d->declarativeData = 0; // don't activate again in ~QObject
|
||||
}
|
||||
|
||||
|
@ -445,11 +445,11 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
|
||||
receiver = popupChild;
|
||||
if (receiver != popup)
|
||||
widgetPos = receiver->mapFromGlobal(event->globalPos());
|
||||
QWidget *alien = m_widget->childAt(m_widget->mapFromGlobal(event->globalPos()));
|
||||
QWidget *alien = receiver->childAt(receiver->mapFromGlobal(event->globalPos()));
|
||||
QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(),
|
||||
event->button(), event->buttons(), event->modifiers(), event->source());
|
||||
e.setTimestamp(event->timestamp());
|
||||
QApplicationPrivate::sendMouseEvent(receiver, &e, alien, m_widget, &qt_button_down, qt_last_mouse_receiver);
|
||||
QApplicationPrivate::sendMouseEvent(receiver, &e, alien, receiver->window(), &qt_button_down, qt_last_mouse_receiver);
|
||||
qt_last_mouse_receiver = receiver;
|
||||
} else {
|
||||
// close disabled popups when a mouse button is pressed or released
|
||||
|
@ -4682,7 +4682,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||
tdi.value = pb->progress;
|
||||
tdi.attributes = vertical ? 0 : kThemeTrackHorizontal;
|
||||
|
||||
if (isIndeterminate || tdi.value < tdi.max) {
|
||||
const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
|
||||
if (isIndeterminate || (tdi.value < tdi.max && !usingYosemiteOrLater)) {
|
||||
if (QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject)))
|
||||
tdi.trackInfo.progress.phase = animation->animationStep();
|
||||
else if (opt->styleObject)
|
||||
|
@ -541,17 +541,21 @@ QRect QStyle::itemPixmapRect(const QRect &rect, int alignment, const QPixmap &pi
|
||||
QRect result;
|
||||
int x, y, w, h;
|
||||
rect.getRect(&x, &y, &w, &h);
|
||||
|
||||
const int pixmapWidth = pixmap.width()/pixmap.devicePixelRatio();
|
||||
const int pixmapHeight = pixmap.height()/pixmap.devicePixelRatio();
|
||||
|
||||
if ((alignment & Qt::AlignVCenter) == Qt::AlignVCenter)
|
||||
y += h/2 - pixmap.height()/2;
|
||||
y += h/2 - pixmapHeight/2;
|
||||
else if ((alignment & Qt::AlignBottom) == Qt::AlignBottom)
|
||||
y += h - pixmap.height();
|
||||
y += h - pixmapHeight;
|
||||
if ((alignment & Qt::AlignRight) == Qt::AlignRight)
|
||||
x += w - pixmap.width();
|
||||
x += w - pixmapWidth;
|
||||
else if ((alignment & Qt::AlignHCenter) == Qt::AlignHCenter)
|
||||
x += w/2 - pixmap.width()/2;
|
||||
x += w/2 - pixmapWidth/2;
|
||||
else if ((alignment & Qt::AlignLeft) != Qt::AlignLeft && QApplication::isRightToLeft())
|
||||
x += w - pixmap.width();
|
||||
result = QRect(x, y, pixmap.width(), pixmap.height());
|
||||
x += w - pixmapWidth;
|
||||
result = QRect(x, y, pixmapWidth, pixmapHeight);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2263,8 +2267,9 @@ int QStyle::sliderValueFromPosition(int min, int max, int pos, int span, bool up
|
||||
standard palette is not used. In particular, the Windows XP,
|
||||
Vista, and Mac styles do not use the standard palette, but make
|
||||
use of native theme engines. With these styles, you should not set
|
||||
the palette with QApplication::setStandardPalette().
|
||||
the palette with QApplication::setPalette().
|
||||
|
||||
\sa QApplication::setPalette()
|
||||
*/
|
||||
QPalette QStyle::standardPalette() const
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user