Merge remote-tracking branch 'origin/5.11' into dev

Change-Id: I9f802cb9b4d9ccba77ca39428a5cb1afd2d01642
This commit is contained in:
Lars Knoll 2018-04-12 21:59:27 +02:00
commit 4f158ccee5
36 changed files with 5665 additions and 3120 deletions

View File

@ -98,14 +98,11 @@ my $showonly = 0;
my $verbose_level = 1;
my $remove_stale = 1;
my $force_win = 0;
my $force_relative = 0;
my $check_includes = 0;
my $copy_headers = 0;
my $create_private_headers = 1;
my $minimal = 0;
my $module_version = 0;
my @modules_to_sync ;
$force_relative = 1 if ( -d "/System/Library/Frameworks" );
# functions ----------------------------------------------------------
@ -124,7 +121,6 @@ sub showUsage
print " -copy Copy headers instead of include-fwd(default: " . ($copy_headers ? "yes" : "no") . ")\n";
print " -remove-stale Removes stale headers (default: " . ($remove_stale ? "yes" : "no") . ")\n";
print " -relative Force relative symlinks (default: " . ($force_relative ? "yes" : "no") . ")\n";
print " -windows Force platform to Windows (default: " . ($force_win ? "yes" : "no") . ")\n";
print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n";
print " -minimal Do not create CamelCase headers (default: " . ($minimal ? "yes" : "no") . ")\n";
@ -137,7 +133,6 @@ sub showUsage
print " -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR>\n";
print " Create headers for <NAME> with original headers in\n";
print " <HEADERDIR> relative to <PROFILEDIR> \n";
print " -private Force copy private headers (default: " . ($create_private_headers ? "yes" : "no") . ")\n";
print " -help This help\n";
exit 0;
}
@ -782,9 +777,6 @@ while ( @ARGV ) {
} elsif($arg eq "-minimal") {
$var = "minimal";
$val = "yes";
} elsif($arg eq "-private") {
$var = "create_private_headers";
$val = "yes";
} elsif($arg eq "-version") {
$var = "version";
$val = shift @ARGV;
@ -841,12 +833,6 @@ while ( @ARGV ) {
} elsif($force_win) {
$force_win--;
}
} elsif ($var eq "relative") {
if($val eq "yes") {
$force_relative++;
} elsif($force_relative) {
$force_relative--;
}
} elsif ($var eq "minimal") {
if($val eq "yes") {
$minimal++;
@ -934,7 +920,7 @@ foreach my $lib (@modules_to_sync) {
$allheadersprivate = 1 if $allmoduleheadersprivate{$lib};
#information used after the syncing
my $pri_install_classes = "";
my $pri_install_gfiles = "";
my $pri_install_files = "";
my $pri_install_ifiles = "";
my $pri_install_pfiles = "";
@ -1084,9 +1070,9 @@ foreach my $lib (@modules_to_sync) {
$header_copies++ if (!$shadow && syncHeader($lib, "$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts));
}
} elsif ($create_private_headers && !$qpa_header) {
} elsif (!$qpa_header) {
$oheader = "$out_basedir/include/$lib/$module_version/$lib/private/$header";
} elsif ($create_private_headers) {
} else {
$oheader = "$out_basedir/include/$lib/$module_version/$lib/qpa/$header";
}
$header_copies++ if (!$shadow && syncHeader($lib, $oheader, $iheader, $copy_headers, $ts));
@ -1100,9 +1086,9 @@ foreach my $lib (@modules_to_sync) {
# if ($class =~ m/::/) {
# $class =~ s,::,/,g;
# }
my $class_header = fixPaths("$out_basedir/include/$lib/$class", $dir) . " ";
$pri_install_classes .= $class_header
unless($pri_install_classes =~ $class_header);
my $class_header = "$class ";
$pri_install_gfiles .= $class_header
unless($pri_install_gfiles =~ $class_header);
$injection .= ":$class";
}
@ -1175,16 +1161,10 @@ foreach my $lib (@modules_to_sync) {
# create deprecated headers
my $first = 1;
while (my ($header, $include) = each %{$deprecatedheaders{$lib}}) {
my $public_header = 0;
$public_header = 1 unless ($allheadersprivate || ($header =~ /_p\.h$/));
next unless ($public_header || $create_private_headers);
my $header_path = "$out_basedir/include/$lib/";
unless ($public_header) {
$header_path .= "$module_version/$lib/private/";
}
$header_path .= "$header";
die "Attempting unsupported aliasing of private header $header.\n"
if ($allheadersprivate || ($header =~ /_p\.h$/));
my $header_path = "$out_basedir/include/$lib/$header";
unless (-e $header_path) {
my $guard = "DEPRECATED_HEADER_" . $lib . "_" . $header;
$guard =~ s/([^a-zA-Z0-9_])/_/g;
@ -1192,26 +1172,19 @@ foreach my $lib (@modules_to_sync) {
my $header_dir = dirname($header_path);
make_path($header_dir, $lib, $verbose_level);
my $warning = "Header <$lib/$header> is deprecated. Please include <$include> instead.";
my $hdrcont =
"#ifndef $guard\n" .
"#define $guard\n";
my $warning = "Header <$lib/";
$warning .= "private/" unless ($public_header);
$warning .= "$header> is deprecated. Please include <$include> instead.";
$hdrcont .=
"#define $guard\n" .
"#if defined(__GNUC__)\n" .
"# warning $warning\n" .
"#elif defined(_MSC_VER)\n" .
"# pragma message (\"$warning\")\n" .
"#endif\n" .
"#include <$include>\n";
if ($public_header) {
$hdrcont .=
"#if 0\n" .
"#pragma qt_no_master_include\n" .
"#endif\n";
}
$hdrcont .=
"#include <$include>\n" .
"#if 0\n" .
"#pragma qt_no_master_include\n" .
"#endif\n" .
"#endif\n";
if (writeFile($header_path, $hdrcont)) {
if ($verbose_level < 3) {
@ -1225,12 +1198,7 @@ foreach my $lib (@modules_to_sync) {
}
}
my $addendum = fixPaths($header_path, $dir) . " ";
if ($public_header) {
$pri_install_files .= $addendum;
} else {
$pri_install_pfiles .= $addendum;
}
$pri_install_gfiles .= "$header ";
}
if ($verbose_level < 3) {
print " }\n" unless ($first);
@ -1240,8 +1208,7 @@ foreach my $lib (@modules_to_sync) {
my $vheader = "$out_basedir/include/$lib/".lc($lib)."version.h";
my $VHeader = "$out_basedir/include/$lib/${lib}Version";
syncHeader($lib, $VHeader, $vheader, 0);
$pri_install_files .= fixPaths($vheader, $dir) . " ";
$pri_install_classes .= fixPaths($VHeader, $dir) . " ";
$pri_install_gfiles .= lc($lib)."version.h ${lib}Version ";
my @versions = split(/\./, $module_version);
my $modulehexstring = sprintf("0x%02X%02X%02X", $versions[0], $versions[1], $versions[2]);
my $vhdrcont =
@ -1257,7 +1224,7 @@ foreach my $lib (@modules_to_sync) {
writeFile($vheader, $vhdrcont, $lib, "version header");
my $master_include = "$out_basedir/include/$lib/$lib";
$pri_install_files .= fixPaths($master_include, $dir) . " ";
$pri_install_gfiles .= "$lib ";
writeFile($master_include, $master_contents, $lib, "master header");
}
@ -1266,7 +1233,7 @@ foreach my $lib (@modules_to_sync) {
my $headers_pri_contents = "";
$headers_pri_contents .= "SYNCQT.HEADER_FILES = $pri_install_files\n";
$headers_pri_contents .= "SYNCQT.INJECTED_HEADER_FILES = $pri_install_ifiles\n";
$headers_pri_contents .= "SYNCQT.HEADER_CLASSES = $pri_install_classes\n";
$headers_pri_contents .= "SYNCQT.GENERATED_HEADER_FILES = $pri_install_gfiles\n";
$headers_pri_contents .= "SYNCQT.PRIVATE_HEADER_FILES = $pri_install_pfiles\n";
$headers_pri_contents .= "SYNCQT.INJECTED_PRIVATE_HEADER_FILES = $pri_install_ipfiles\n";
$headers_pri_contents .= "SYNCQT.QPA_HEADER_FILES = $pri_install_qpafiles\n";

View File

@ -46,7 +46,7 @@
The \c Window class's constructors begins by creating a button.
This button is added to \c layout, which is a QVBoxLayout object.
Then two states are created: \s1 is the state
Then two states are created: \c s1 is the state
"Outside", and \c s2 is the state "Inside".
\snippet statemachine/eventtransitions/main.cpp 1

View File

@ -28,9 +28,9 @@
#headers
qt_install_headers {
class_headers.files = $$SYNCQT.HEADER_CLASSES
class_headers.path = $$[QT_INSTALL_HEADERS]/$$MODULE_INCNAME
INSTALLS += class_headers
gen_headers.files = $$SYNCQT.GENERATED_HEADER_FILES
gen_headers.path = $$[QT_INSTALL_HEADERS]/$$MODULE_INCNAME
INSTALLS += gen_headers
targ_headers.files = $$SYNCQT.HEADER_FILES $$SYNCQT.INJECTED_HEADER_FILES
targ_headers.path = $$[QT_INSTALL_HEADERS]/$$MODULE_INCNAME

View File

@ -136,7 +136,7 @@ lib_bundle {
if(if(!debug_and_release|CONFIG(release, debug|release))) {
FRAMEWORK_HEADERS.version = Versions
FRAMEWORK_HEADERS.files = \
$$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES $$SYNCQT.INJECTED_HEADER_FILES
$$SYNCQT.HEADER_FILES $$SYNCQT.GENERATED_HEADER_FILES $$SYNCQT.INJECTED_HEADER_FILES
FRAMEWORK_HEADERS.path = Headers
FRAMEWORK_PRIVATE_HEADERS.version = Versions
FRAMEWORK_PRIVATE_HEADERS.files = \
@ -224,7 +224,7 @@ android: CONFIG += qt_android_deps no_linker_version_script
private_api_headers = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.QPA_HEADER_FILES
for(header, private_api_headers): \
verscript_content += " @FILE:$${_PRO_FILE_PWD_}/$$header@"
verscript_content += " @FILE:$$header@"
verscript_content += "};"
current = Qt_$$QT_MAJOR_VERSION
@ -244,8 +244,7 @@ android: CONFIG += qt_android_deps no_linker_version_script
verscriptprocess.name = linker version script ${QMAKE_FILE_BASE}
verscriptprocess.input = verscript_in
verscriptprocess.CONFIG += no_link target_predeps
for(header, private_api_headers): \
verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header
verscriptprocess.depends = $$private_api_headers
verscriptprocess.output = $$verscript
verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@
silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands

View File

@ -96,12 +96,26 @@ MODULE_PRIVATE_INCLUDES += $$MODULE_PRIVATE_AUX_INCLUDES
minimal_syncqt: return()
defineTest(syncQtResolve) {
out =
for (f, SYNCQT.$$1): \
out += $$absolute_path($$f, $$2)
SYNCQT.$$1 = $$out
export(SYNCQT.$$1)
}
#load up the headers info
git_build: \
INC_PATH = $$MODULE_BASE_OUTDIR
else: \
INC_PATH = $$MODULE_BASE_INDIR
include($$INC_PATH/include/$$MODULE_INCNAME/headers.pri, "", true)
syncQtResolve(HEADER_FILES, $$_PRO_FILE_PWD_)
syncQtResolve(PRIVATE_HEADER_FILES, $$_PRO_FILE_PWD_)
syncQtResolve(QPA_HEADER_FILES, $$_PRO_FILE_PWD_)
syncQtResolve(GENERATED_HEADER_FILES, $$INC_PATH/include/$$MODULE_INCNAME)
syncQtResolve(INJECTED_HEADER_FILES, $$OUT_PWD)
syncQtResolve(INJECTED_PRIVATE_HEADER_FILES, $$OUT_PWD)
!lib_bundle: \ # Headers are embedded into the bundle, so don't install them separately.
CONFIG += qt_install_headers
@ -114,9 +128,8 @@ exists($$OUT_PWD/qt$${MODULE}-config.h) {
SYNCQT.INJECTIONS += \
$$fwd_rel/qt$${MODULE}-config.h:qt$${MODULE}-config.h \
$$fwd_rel/qt$${MODULE}-config_p.h:$$MODULE_VERSION/$$MODULE_INCNAME/private/qt$${MODULE}-config_p.h
inst_rel = $$relative_path($$OUT_PWD, $$_PRO_FILE_PWD_)
SYNCQT.HEADER_FILES += $$inst_rel/qt$${MODULE}-config.h
SYNCQT.INJECTED_PRIVATE_HEADER_FILES += $$inst_rel/qt$${MODULE}-config_p.h
SYNCQT.INJECTED_HEADER_FILES += $$OUT_PWD/qt$${MODULE}-config.h
SYNCQT.INJECTED_PRIVATE_HEADER_FILES += $$OUT_PWD/qt$${MODULE}-config_p.h
}
for (injection, SYNCQT.INJECTIONS) {

View File

@ -943,7 +943,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
QString fn = files.at(file).toQString();
QString src = fileFixify(fn, FileFixifyAbsolute);
if (!QFile::exists(src))
src = fn;
src = fileFixify(fn, FileFixifyFromOutdir);
else
src = fileFixify(fn);
QString dst = path + Option::dir_sep + fileInfo(fn).fileName();
bundledFiles << dst;
alldeps << dst;

View File

@ -6,7 +6,7 @@
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
"Homepage": "http://www.sqlite.org/",
"Version": "3.22.0",
"Version": "3.23.1",
"License": "Public Domain",
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
}

File diff suppressed because it is too large Load Diff

View File

@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.22.0"
#define SQLITE_VERSION_NUMBER 3022000
#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
#define SQLITE_VERSION "3.23.1"
#define SQLITE_VERSION_NUMBER 3023001
#define SQLITE_SOURCE_ID "2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd148b3b"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -1064,6 +1064,12 @@ struct sqlite3_io_methods {
** so that all subsequent write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
** a file lock using the xLock or xShmLock methods of the VFS to wait
** for up to M milliseconds before failing, where M is the single
** unsigned integer parameter.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@ -1098,6 +1104,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -2054,11 +2061,13 @@ struct sqlite3_mem_methods {
** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to
** override this behaviour. The first parameter passed to this operation
** is an integer - non-zero to disable checkpoints-on-close, or zero (the
** default) to enable them. The second parameter is a pointer to an integer
** is an integer - positive to disable checkpoints-on-close, or zero (the
** default) to enable them, and negative to leave the setting unchanged.
** The second parameter is a pointer to an integer
** into which is written 0 or 1 to indicate whether checkpoints-on-close
** have been disabled - 0 if they are not disabled, 1 if they are.
** </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
@ -2068,13 +2077,20 @@ struct sqlite3_mem_methods {
** slower. But the QPSG has the advantage of more predictable behavior. With
** the QPSG active, SQLite will always use the same query plan in the field as
** was used during testing in the lab.
** The first argument to this setting is an integer which is 0 to disable
** the QPSG, positive to enable QPSG, or negative to leave the setting
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
** following this call.
** </dd>
**
** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
** include output for any operations performed by trigger programs. This
** option is used to set or clear (the default) a flag that governs this
** behavior. The first parameter passed to this operation is an integer -
** non-zero to enable output for trigger programs, or zero to disable it.
** positive to enable output for trigger programs, or zero to disable it,
** or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which is written
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is.
@ -2496,16 +2512,16 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
** These routines understand most of the common K&R formatting options,
** plus some additional non-standard formats, detailed below.
** Note that some of the more obscure formatting options from recent
** C-library standards are omitted from this implementation.
** These routines understand most of the common formatting options from
** the standard library printf()
** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).
** See the [built-in printf()] documentation for details.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
** results into memory obtained from [sqlite3_malloc64()].
** The strings returned by these two routines should be
** released by [sqlite3_free()]. ^Both routines return a
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
@ -2529,71 +2545,7 @@ SQLITE_API void sqlite3_free_table(char **result);
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
** These routines all implement some additional formatting
** options that are useful for constructing SQL statements.
** All of the usual printf() formatting options apply. In addition, there
** is are "%q", "%Q", "%w" and "%z" options.
**
** ^(The %q option works like %s in that it substitutes a nul-terminated
** string from the argument list. But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.)^ By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, assume the string variable zText contains text as follows:
**
** <blockquote><pre>
** char *zText = "It's a happy day!";
** </pre></blockquote>
**
** One can use this text in an SQL statement as follows:
**
** <blockquote><pre>
** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
** sqlite3_exec(db, zSQL, 0, 0, 0);
** sqlite3_free(zSQL);
** </pre></blockquote>
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
** <blockquote><pre>
** INSERT INTO table1 VALUES('It''s a happy day!')
** </pre></blockquote>
**
** This is correct. Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
** <blockquote><pre>
** INSERT INTO table1 VALUES('It's a happy day!');
** </pre></blockquote>
**
** This second example is an SQL syntax error. As a general rule you should
** always use %q instead of %s when inserting text into a string literal.
**
** ^(The %Q option works like %q except it also adds single quotes around
** the outside of the total string. Additionally, if the parameter in the
** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
** single quotes).)^ So, for example, one could say:
**
** <blockquote><pre>
** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
** sqlite3_exec(db, zSQL, 0, 0, 0);
** sqlite3_free(zSQL);
** </pre></blockquote>
**
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
** ^(The "%w" formatting option is like "%q" except that it expects to
** be contained within double-quotes instead of single quotes, and it
** escapes the double-quote character instead of the single-quote
** character.)^ The "%w" formatting option is intended for safely inserting
** table and column names into a constructed SQL statement.
**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
** See also: [built-in printf()], [printf() SQL function]
*/
SQLITE_API char *sqlite3_mprintf(const char*,...);
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
@ -3659,13 +3611,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
** </li>
** </ol>
**
** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
** the extra prepFlags parameter, which is a bit array consisting of zero or
** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The
** sqlite3_prepare_v2() interface works exactly the same as
** sqlite3_prepare_v3() with a zero prepFlags parameter.
** </ol>
*/
SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
@ -7294,6 +7246,15 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
**
** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>
** <dd>This parameter returns the number of dirty cache entries that have
** been written to disk in the middle of a transaction due to the page
** cache overflowing. Transactions are more efficient if they are written
** to disk all at once. When pages spill mid-transaction, that introduces
** additional overhead. This parameter can be used help identify
** inefficiencies that can be resolve by increasing the cache size.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
** <dd>This parameter returns zero for the current value if and only if
** all foreign key constraints (deferred or immediate) have been
@ -7313,7 +7274,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_WRITE 9
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
#define SQLITE_DBSTATUS_CACHE_USED_SHARED 11
#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */
#define SQLITE_DBSTATUS_CACHE_SPILL 12
#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */
/*
@ -8793,6 +8755,128 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
*/
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Serialize a database
**
** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory
** that is a serialization of the S database on [database connection] D.
** If P is not a NULL pointer, then the size of the database in bytes
** is written into *P.
**
** For an ordinary on-disk database file, the serialization is just a
** copy of the disk file. For an in-memory database or a "TEMP" database,
** the serialization is the same sequence of bytes which would be written
** to disk if that database where backed up to disk.
**
** The usual case is that sqlite3_serialize() copies the serialization of
** the database into memory obtained from [sqlite3_malloc64()] and returns
** a pointer to that memory. The caller is responsible for freeing the
** returned value to avoid a memory leak. However, if the F argument
** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations
** are made, and the sqlite3_serialize() function will return a pointer
** to the contiguous memory representation of the database that SQLite
** is currently using for that database, or NULL if the no such contiguous
** memory representation of the database exists. A contiguous memory
** representation of the database will usually only exist if there has
** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
** values of D and S.
** The size of the database is written into *P even if the
** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy
** of the database exists.
**
** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the
** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory
** allocation error occurs.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
*/
SQLITE_API unsigned char *sqlite3_serialize(
sqlite3 *db, /* The database connection */
const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */
sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */
unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */
);
/*
** CAPI3REF: Flags for sqlite3_serialize
**
** Zero or more of the following constants can be OR-ed together for
** the F argument to [sqlite3_serialize(D,S,P,F)].
**
** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return
** a pointer to contiguous in-memory database that it is currently using,
** without making a copy of the database. If SQLite is not currently using
** a contiguous in-memory database, then this option causes
** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be
** using a contiguous in-memory database if it has been initialized by a
** prior call to [sqlite3_deserialize()].
*/
#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */
/*
** CAPI3REF: Deserialize a database
**
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
** [database connection] D to disconnect from database S and then
** reopen S as an in-memory database based on the serialization contained
** in P. The serialized database P is N bytes in size. M is the size of
** the buffer P, which might be larger than N. If M is larger than N, and
** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is
** permitted to add content to the in-memory database as long as the total
** size does not exceed M bytes.
**
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
** invoke sqlite3_free() on the serialization buffer when the database
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
** SQLite will try to increase the buffer size using sqlite3_realloc64()
** if writes on the database cause it to grow larger than M bytes.
**
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
** database is currently in a read transaction or is involved in a backup
** operation.
**
** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the
** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then
** [sqlite3_free()] is invoked on argument P prior to returning.
**
** This interface is only available if SQLite is compiled with the
** [SQLITE_ENABLE_DESERIALIZE] option.
*/
SQLITE_API int sqlite3_deserialize(
sqlite3 *db, /* The database connection */
const char *zSchema, /* Which DB to reopen with the deserialization */
unsigned char *pData, /* The serialized database content */
sqlite3_int64 szDb, /* Number bytes in the deserialization */
sqlite3_int64 szBuf, /* Total size of buffer pData[] */
unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */
);
/*
** CAPI3REF: Flags for sqlite3_deserialize()
**
** The following are allowed values for 6th argument (the F argument) to
** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.
**
** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization
** in the P argument is held in memory obtained from [sqlite3_malloc64()]
** and that SQLite should take ownership of this memory and automatically
** free it when it has finished using it. Without this flag, the caller
** is resposible for freeing any dynamically allocated memory.
**
** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
** grow the size of the database using calls to [sqlite3_realloc64()]. This
** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.
** Without this flag, the deserialized database cannot increase in size beyond
** the number of bytes specified by the M parameter.
**
** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database
** should be treated as read-only.
*/
#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */
#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */
#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */
/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
@ -8940,16 +9024,23 @@ extern "C" {
/*
** CAPI3REF: Session Object Handle
**
** An instance of this object is a [session] that can be used to
** record changes to a database.
*/
typedef struct sqlite3_session sqlite3_session;
/*
** CAPI3REF: Changeset Iterator Handle
**
** An instance of this object acts as a cursor for iterating
** over the elements of a [changeset] or [patchset].
*/
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
/*
** CAPI3REF: Create A New Session Object
** CONSTRUCTOR: sqlite3_session
**
** Create a new session object attached to database handle db. If successful,
** a pointer to the new object is written to *ppSession and SQLITE_OK is
@ -8986,6 +9077,7 @@ SQLITE_API int sqlite3session_create(
/*
** CAPI3REF: Delete A Session Object
** DESTRUCTOR: sqlite3_session
**
** Delete a session object previously allocated using
** [sqlite3session_create()]. Once a session object has been deleted, the
@ -9001,6 +9093,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
/*
** CAPI3REF: Enable Or Disable A Session Object
** METHOD: sqlite3_session
**
** Enable or disable the recording of changes by a session object. When
** enabled, a session object records changes made to the database. When
@ -9020,6 +9113,7 @@ SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
/*
** CAPI3REF: Set Or Clear the Indirect Change Flag
** METHOD: sqlite3_session
**
** Each change recorded by a session object is marked as either direct or
** indirect. A change is marked as indirect if either:
@ -9049,6 +9143,7 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect)
/*
** CAPI3REF: Attach A Table To A Session Object
** METHOD: sqlite3_session
**
** If argument zTab is not NULL, then it is the name of a table to attach
** to the session object passed as the first argument. All subsequent changes
@ -9111,6 +9206,7 @@ SQLITE_API int sqlite3session_attach(
/*
** CAPI3REF: Set a table filter on a Session Object.
** METHOD: sqlite3_session
**
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session object, the filter is called
@ -9129,6 +9225,7 @@ SQLITE_API void sqlite3session_table_filter(
/*
** CAPI3REF: Generate A Changeset From A Session Object
** METHOD: sqlite3_session
**
** Obtain a changeset containing changes to the tables attached to the
** session object passed as the first argument. If successful,
@ -9238,7 +9335,8 @@ SQLITE_API int sqlite3session_changeset(
);
/*
** CAPI3REF: Load The Difference Between Tables Into A Session
** CAPI3REF: Load The Difference Between Tables Into A Session
** METHOD: sqlite3_session
**
** If it is not already attached to the session object passed as the first
** argument, this function attaches table zTbl in the same manner as the
@ -9303,6 +9401,7 @@ SQLITE_API int sqlite3session_diff(
/*
** CAPI3REF: Generate A Patchset From A Session Object
** METHOD: sqlite3_session
**
** The differences between a patchset and a changeset are that:
**
@ -9354,6 +9453,7 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
** CONSTRUCTOR: sqlite3_changeset_iter
**
** Create an iterator used to iterate through the contents of a changeset.
** If successful, *pp is set to point to the iterator handle and SQLITE_OK
@ -9394,6 +9494,7 @@ SQLITE_API int sqlite3changeset_start(
/*
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function may only be used with iterators created by function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
@ -9418,6 +9519,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@ -9452,6 +9554,7 @@ SQLITE_API int sqlite3changeset_op(
/*
** CAPI3REF: Obtain The Primary Key Definition Of A Table
** METHOD: sqlite3_changeset_iter
**
** For each modified table, a changeset includes the following:
**
@ -9483,6 +9586,7 @@ SQLITE_API int sqlite3changeset_pk(
/*
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@ -9513,6 +9617,7 @@ SQLITE_API int sqlite3changeset_old(
/*
** CAPI3REF: Obtain new.* Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** The pIter argument passed to this function may either be an iterator
** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator
@ -9546,6 +9651,7 @@ SQLITE_API int sqlite3changeset_new(
/*
** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function should only be used with iterator objects passed to a
** conflict-handler callback by [sqlite3changeset_apply()] with either
@ -9573,6 +9679,7 @@ SQLITE_API int sqlite3changeset_conflict(
/*
** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations
** METHOD: sqlite3_changeset_iter
**
** This function may only be called with an iterator passed to an
** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case
@ -9589,6 +9696,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
/*
** CAPI3REF: Finalize A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
** This function is used to finalize an iterator allocated with
** [sqlite3changeset_start()].
@ -9605,6 +9713,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
** to that error is returned by this function. Otherwise, SQLITE_OK is
** returned. This is to allow the following pattern (pseudo-code):
**
** <pre>
** sqlite3changeset_start();
** while( SQLITE_ROW==sqlite3changeset_next() ){
** // Do something with change.
@ -9613,6 +9722,7 @@ SQLITE_API int sqlite3changeset_fk_conflicts(
** if( rc!=SQLITE_OK ){
** // An error has occurred
** }
** </pre>
*/
SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
@ -9660,6 +9770,7 @@ SQLITE_API int sqlite3changeset_invert(
** sqlite3_changegroup object. Calling it produces similar results as the
** following code fragment:
**
** <pre>
** sqlite3_changegroup *pGrp;
** rc = sqlite3_changegroup_new(&pGrp);
** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
@ -9670,6 +9781,7 @@ SQLITE_API int sqlite3changeset_invert(
** *ppOut = 0;
** *pnOut = 0;
** }
** </pre>
**
** Refer to the sqlite3_changegroup documentation below for details.
*/
@ -9685,11 +9797,15 @@ SQLITE_API int sqlite3changeset_concat(
/*
** CAPI3REF: Changegroup Handle
**
** A changegroup is an object used to combine two or more
** [changesets] or [patchsets]
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
** CAPI3REF: Create A New Changegroup Object
** CONSTRUCTOR: sqlite3_changegroup
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@ -9727,6 +9843,7 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
** METHOD: sqlite3_changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
@ -9804,6 +9921,7 @@ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pDa
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
** METHOD: sqlite3_changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
@ -9834,25 +9952,25 @@ SQLITE_API int sqlite3changegroup_output(
/*
** CAPI3REF: Delete A Changegroup Object
** DESTRUCTOR: sqlite3_changegroup
*/
SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
/*
** CAPI3REF: Apply A Changeset To A Database
**
** Apply a changeset to a database. This function attempts to update the
** "main" database attached to handle db with the changes found in the
** changeset passed via the second and third arguments.
** Apply a changeset or patchset to a database. These functions attempt to
** update the "main" database attached to handle db with the changes found in
** the changeset passed via the second and third arguments.
**
** The fourth argument (xFilter) passed to this function is the "filter
** The fourth argument (xFilter) passed to these functions is the "filter
** callback". If it is not NULL, then for each table affected by at least one
** change in the changeset, the filter callback is invoked with
** the table name as the second argument, and a copy of the context pointer
** passed as the sixth argument to this function as the first. If the "filter
** callback" returns zero, then no attempt is made to apply any changes to
** the table. Otherwise, if the return value is non-zero or the xFilter
** argument to this function is NULL, all changes related to the table are
** attempted.
** passed as the sixth argument as the first. If the "filter callback"
** returns zero, then no attempt is made to apply any changes to the table.
** Otherwise, if the return value is non-zero or the xFilter argument to
** is NULL, all changes related to the table are attempted.
**
** For each table that is not excluded by the filter callback, this function
** tests that the target database contains a compatible table. A table is
@ -9897,7 +10015,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** <dl>
** <dt>DELETE Changes<dd>
** For each DELETE change, this function checks if the target database
** For each DELETE change, the function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
** stored in all non-primary key columns also match the values stored in
@ -9942,7 +10060,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
** [SQLITE_CHANGESET_REPLACE].
**
** <dt>UPDATE Changes<dd>
** For each UPDATE change, this function checks if the target database
** For each UPDATE change, the function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
** stored in all modified non-primary key columns also match the values
@ -9973,11 +10091,28 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
** This can be used to further customize the applications conflict
** resolution strategy.
**
** All changes made by this function are enclosed in a savepoint transaction.
** All changes made by these functions are enclosed in a savepoint transaction.
** If any other error (aside from a constraint failure when attempting to
** write to the target database) occurs, then the savepoint transaction is
** rolled back, restoring the target database to its original state, and an
** SQLite error code returned.
**
** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
** may set (*ppRebase) to point to a "rebase" that may be used with the
** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
** is set to the size of the buffer in bytes. It is the responsibility of the
** caller to eventually free any such buffer using sqlite3_free(). The buffer
** is only allocated and populated if one or more conflicts were encountered
** while applying the patchset. See comments surrounding the sqlite3_rebaser
** APIs for further details.
**
** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent
** may be modified by passing a combination of
** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.
**
** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>
** and therefore subject to change.
*/
SQLITE_API int sqlite3changeset_apply(
sqlite3 *db, /* Apply change to "main" db of this handle */
@ -9994,6 +10129,41 @@ SQLITE_API int sqlite3changeset_apply(
),
void *pCtx /* First argument passed to xConflict */
);
SQLITE_API int sqlite3changeset_apply_v2(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* Combination of SESSION_APPLY_* flags */
);
/*
** CAPI3REF: Flags for sqlite3changeset_apply_v2
**
** The following flags may passed via the 9th parameter to
** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:
**
** <dl>
** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>
** Usually, the sessions module encloses all operations performed by
** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The
** SAVEPOINT is committed if the changeset or patchset is successfully
** applied, or rolled back if an error occurs. Specifying this flag
** causes the sessions module to omit this savepoint. In this case, if the
** caller has an open transaction or savepoint when apply_v2() is called,
** it may revert the partially applied changeset by rolling it back.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@ -10091,6 +10261,161 @@ SQLITE_API int sqlite3changeset_apply(
#define SQLITE_CHANGESET_REPLACE 1
#define SQLITE_CHANGESET_ABORT 2
/*
** CAPI3REF: Rebasing changesets
** EXPERIMENTAL
**
** Suppose there is a site hosting a database in state S0. And that
** modifications are made that move that database to state S1 and a
** changeset recorded (the "local" changeset). Then, a changeset based
** on S0 is received from another site (the "remote" changeset) and
** applied to the database. The database is then in state
** (S1+"remote"), where the exact state depends on any conflict
** resolution decisions (OMIT or REPLACE) made while applying "remote".
** Rebasing a changeset is to update it to take those conflict
** resolution decisions into account, so that the same conflicts
** do not have to be resolved elsewhere in the network.
**
** For example, if both the local and remote changesets contain an
** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
**
** local: INSERT INTO t1 VALUES(1, 'v1');
** remote: INSERT INTO t1 VALUES(1, 'v2');
**
** and the conflict resolution is REPLACE, then the INSERT change is
** removed from the local changeset (it was overridden). Or, if the
** conflict resolution was "OMIT", then the local changeset is modified
** to instead contain:
**
** UPDATE t1 SET b = 'v2' WHERE a=1;
**
** Changes within the local changeset are rebased as follows:
**
** <dl>
** <dt>Local INSERT<dd>
** This may only conflict with a remote INSERT. If the conflict
** resolution was OMIT, then add an UPDATE change to the rebased
** changeset. Or, if the conflict resolution was REPLACE, add
** nothing to the rebased changeset.
**
** <dt>Local DELETE<dd>
** This may conflict with a remote UPDATE or DELETE. In both cases the
** only possible resolution is OMIT. If the remote operation was a
** DELETE, then add no change to the rebased changeset. If the remote
** operation was an UPDATE, then the old.* fields of change are updated
** to reflect the new.* values in the UPDATE.
**
** <dt>Local UPDATE<dd>
** This may conflict with a remote UPDATE or DELETE. If it conflicts
** with a DELETE, and the conflict resolution was OMIT, then the update
** is changed into an INSERT. Any undefined values in the new.* record
** from the update change are filled in using the old.* values from
** the conflicting DELETE. Or, if the conflict resolution was REPLACE,
** the UPDATE change is simply omitted from the rebased changeset.
**
** If conflict is with a remote UPDATE and the resolution is OMIT, then
** the old.* values are rebased using the new.* values in the remote
** change. Or, if the resolution is REPLACE, then the change is copied
** into the rebased changeset with updates to columns also updated by
** the conflicting remote UPDATE removed. If this means no columns would
** be updated, the change is omitted.
** </dl>
**
** A local change may be rebased against multiple remote changes
** simultaneously. If a single key is modified by multiple remote
** changesets, they are combined as follows before the local changeset
** is rebased:
**
** <ul>
** <li> If there has been one or more REPLACE resolutions on a
** key, it is rebased according to a REPLACE.
**
** <li> If there have been no REPLACE resolutions on a key, then
** the local changeset is rebased according to the most recent
** of the OMIT resolutions.
** </ul>
**
** Note that conflict resolutions from multiple remote changesets are
** combined on a per-field basis, not per-row. This means that in the
** case of multiple remote UPDATE operations, some fields of a single
** local change may be rebased for REPLACE while others are rebased for
** OMIT.
**
** In order to rebase a local changeset, the remote changeset must first
** be applied to the local database using sqlite3changeset_apply_v2() and
** the buffer of rebase information captured. Then:
**
** <ol>
** <li> An sqlite3_rebaser object is created by calling
** sqlite3rebaser_create().
** <li> The new object is configured with the rebase buffer obtained from
** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
** If the local changeset is to be rebased against multiple remote
** changesets, then sqlite3rebaser_configure() should be called
** multiple times, in the same order that the multiple
** sqlite3changeset_apply_v2() calls were made.
** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
** <li> The sqlite3_rebaser object is deleted by calling
** sqlite3rebaser_delete().
** </ol>
*/
typedef struct sqlite3_rebaser sqlite3_rebaser;
/*
** CAPI3REF: Create a changeset rebaser object.
** EXPERIMENTAL
**
** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
** point to the new object and return SQLITE_OK. Otherwise, if an error
** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew)
** to NULL.
*/
SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
/*
** CAPI3REF: Configure a changeset rebaser object.
** EXPERIMENTAL
**
** Configure the changeset rebaser object to rebase changesets according
** to the conflict resolutions described by buffer pRebase (size nRebase
** bytes), which must have been obtained from a previous call to
** sqlite3changeset_apply_v2().
*/
SQLITE_API int sqlite3rebaser_configure(
sqlite3_rebaser*,
int nRebase, const void *pRebase
);
/*
** CAPI3REF: Rebase a changeset
** EXPERIMENTAL
**
** Argument pIn must point to a buffer containing a changeset nIn bytes
** in size. This function allocates and populates a buffer with a copy
** of the changeset rebased rebased according to the configuration of the
** rebaser object passed as the first argument. If successful, (*ppOut)
** is set to point to the new buffer containing the rebased changset and
** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
** responsibility of the caller to eventually free the new buffer using
** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
** are set to zero and an SQLite error code returned.
*/
SQLITE_API int sqlite3rebaser_rebase(
sqlite3_rebaser*,
int nIn, const void *pIn,
int *pnOut, void **ppOut
);
/*
** CAPI3REF: Delete a changeset rebaser object.
** EXPERIMENTAL
**
** Delete the changeset rebaser object and all associated resources. There
** should be one call to this function for each successful invocation
** of sqlite3rebaser_create().
*/
SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p);
/*
** CAPI3REF: Streaming Versions of API functions.
**
@ -10100,6 +10425,7 @@ SQLITE_API int sqlite3changeset_apply(
** <table border=1 style="margin-left:8ex;margin-right:8ex">
** <tr><th>Streaming function<th>Non-streaming equivalent</th>
** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2]
** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert]
** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
@ -10195,6 +10521,23 @@ SQLITE_API int sqlite3changeset_apply_strm(
),
void *pCtx /* First argument passed to xConflict */
);
SQLITE_API int sqlite3changeset_apply_v2_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
);
SQLITE_API int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData),
void *pInA,
@ -10232,6 +10575,13 @@ SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
SQLITE_API int sqlite3rebaser_rebase_strm(
sqlite3_rebaser *pRebaser,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
/*

View File

@ -133,7 +133,7 @@
editable property for (checkable) buttons. Note that QItemDelegate
gets and sets a widget's \c USER property.
\li The presence of the \c CONSTANT attibute indicates that the property
\li The presence of the \c CONSTANT attribute indicates that the property
value is constant. For a given object instance, the READ method of a
constant property must return the same value every time it is called. This
constant value may be different for different instances of the object. A

View File

@ -2295,17 +2295,13 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *
#endif
while (b < boundedEnd) {
int x = (fx >> 16);
#if defined(__SSE2__) || defined(__ARM_NEON__)
int distx8 = (fx & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(s1 + x, s2 + x, distx8, disty8);
#else
uint tl = s1[x];
uint tr = s1[x + 1];
uint bl = s2[x];
uint br = s2[x + 1];
int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
#endif
if (hasFastInterpolate4()) {
int distx8 = (fx & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(s1 + x, s2 + x, distx8, disty8);
} else {
int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx4, disty4);
}
fx += fdx;
++b;
}
@ -2319,14 +2315,13 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_downscale_helper(uint *
uint tr = s1[x2];
uint bl = s2[x1];
uint br = s2[x2];
#if defined(__SSE2__) || defined(__ARM_NEON__)
// The optimized interpolate_4_pixels are faster than interpolate_4_pixels_16.
int distx8 = (fx & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx8, disty8);
#else
int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
#endif
if (hasFastInterpolate4()) {
int distx8 = (fx & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx8, disty8);
} else {
int distx4 = ((fx & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx4, disty4);
}
fx += fdx;
++b;
}
@ -2391,15 +2386,15 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
uint tr = s1[x2];
uint bl = s2[x1];
uint br = s2[x2];
#if defined(__SSE2__) || defined(__ARM_NEON__)
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
#else
int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
#endif
if (hasFastInterpolate4()) {
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
} else {
int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
}
fx += fdx;
fy += fdy;
++b;
@ -2541,19 +2536,15 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
const uint *s1 = (const uint *)image.scanLine(y);
const uint *s2 = (const uint *)image.scanLine(y + 1);
#if defined(__SSE2__) || defined(__ARM_NEON__)
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
#else
uint tl = s1[x];
uint tr = s1[x + 1];
uint bl = s2[x];
uint br = s2[x + 1];
int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
#endif
if (hasFastInterpolate4()) {
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(s1 + x, s2 + x, distx, disty);
} else {
int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(s1[x], s1[x + 1], s2[x], s2[x + 1], distx, disty);
}
fx += fdx;
fy += fdy;
@ -2578,16 +2569,15 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
uint bl = s2[x1];
uint br = s2[x2];
#if defined(__SSE2__) || defined(__ARM_NEON__)
// The optimized interpolate_4_pixels are faster than interpolate_4_pixels_16.
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
#else
int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
#endif
if (hasFastInterpolate4()) {
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
*b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
} else {
int distx = ((fx & 0x0000ffff) + 0x0800) >> 12;
int disty = ((fy & 0x0000ffff) + 0x0800) >> 12;
*b = interpolate_4_pixels_16(tl, tr, bl, br, distx, disty);
}
fx += fdx;
fy += fdy;
@ -2981,7 +2971,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
if (qAbs(data->m22) < qreal(1./8.)) { // scale up more than 8x (on Y)
if (hasFastInterpolate4() || qAbs(data->m22) < qreal(1./8.)) { // scale up more than 8x (on Y)
int disty = (fy & 0x0000ffff) >> 8;
for (int i = 0; i < len; ++i) {
int distx = (fx & 0x0000ffff) >> 8;
@ -3016,7 +3006,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
layout->convertToARGB32PM(buf1, buf1, len * 2, clut, 0);
layout->convertToARGB32PM(buf2, buf2, len * 2, clut, 0);
if (qAbs(data->m11) < qreal(1./8.)|| qAbs(data->m22) < qreal(1./8.)) {
if (hasFastInterpolate4() || qAbs(data->m11) < qreal(1./8.) || qAbs(data->m22) < qreal(1./8.)) {
// If we are zooming more than 8 times, we use 8bit precision for the position.
for (int i = 0; i < len; ++i) {
int distx = (fx & 0x0000ffff) >> 8;

View File

@ -685,6 +685,9 @@ static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint dis
__m128i vb = _mm_loadl_epi64((const __m128i*)b);
return interpolate_4_pixels_sse2(vt, vb, distx, disty);
}
static constexpr inline bool hasFastInterpolate4() { return true; }
#elif defined(__ARM_NEON__)
static Q_ALWAYS_INLINE uint interpolate_4_pixels_neon(uint32x2_t vt32, uint32x2_t vb32, uint distx, uint disty)
{
@ -717,6 +720,9 @@ static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint dis
uint32x2_t vb32 = vld1_u32(b);
return interpolate_4_pixels_neon(vt32, vb32, distx, disty);
}
static constexpr inline bool hasFastInterpolate4() { return true; }
#else
static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
{
@ -731,6 +737,9 @@ static inline uint interpolate_4_pixels(const uint t[], const uint b[], uint dis
{
return interpolate_4_pixels(t[0], t[1], b[0], b[1], distx, disty);
}
static constexpr inline bool hasFastInterpolate4() { return false; }
#endif
#if Q_BYTE_ORDER == Q_BIG_ENDIAN

View File

@ -212,6 +212,9 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan
void QHttp2ProtocolHandler::_q_uploadDataReadyRead()
{
if (!sender()) // QueuedConnection, firing after sender (byte device) was deleted.
return;
auto data = qobject_cast<QNonContiguousByteDevice *>(sender());
Q_ASSERT(data);
const qint32 streamID = data->property("HTTP2StreamID").toInt();
@ -1110,6 +1113,17 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
if (QHttpNetworkReply::isHttpRedirect(statusCode) && redirectUrl.isValid())
httpReply->setRedirectUrl(redirectUrl);
if (QHttpNetworkReply::isHttpRedirect(statusCode)
|| statusCode == 401 || statusCode == 407) {
// These are the status codes that can trigger uploadByteDevice->reset()
// in QHttpNetworkConnectionChannel::handleStatus. Alas, we have no
// single request/reply, we multiplex several requests and thus we never
// simply call 'handleStatus'. If we have byte-device - we try to reset
// it here, we don't (and can't) handle any error during reset operation.
if (stream.data())
stream.data()->reset();
}
if (connectionType == Qt::DirectConnection)
emit httpReply->headerChanged();
else

View File

@ -117,7 +117,7 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
Describes the protocol of the cipher.
\value SslV3 SSLv3. When using the WinRT backend this option will also enable TLSv1.0
\value SslV2 SSLv2
\value SslV2 SSLv2. Note, SSLv2 support was removed in OpenSSL 1.1.
\value TlsV1_0 TLSv1.0
\value TlsV1_0OrLater TLSv1.0 and later versions. This option is not available when using the WinRT backend due to platform limitations.
\value TlsV1 Obsolete, means the same as TlsV1_0
@ -129,8 +129,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl");
\value DtlsV1_2 DTLSv1.2
\value DtlsV1_2OrLater DTLSv1.2 and later versions.
\value UnknownProtocol The cipher's protocol cannot be determined.
\value AnyProtocol The socket understands SSLv2, SSLv3, and TLSv1.0. This
value is used by QSslSocket only.
\value AnyProtocol The socket understands SSLv2, SSLv3, TLSv1.0 and all
supported later versions of TLS. This value is used by QSslSocket only.
\value TlsV1SslV3 On the client side, this will send
a TLS 1.0 Client Hello, enabling TLSv1_0 and SSLv3 connections.
On the server side, this will enable both SSLv3 and TLSv1_0 connections.

View File

@ -100,6 +100,68 @@ init_context:
return;
}
long minVersion = TLS_ANY_VERSION;
long maxVersion = TLS_ANY_VERSION;
switch (sslContext->sslConfiguration.protocol()) {
// The single-protocol versions first:
case QSsl::SslV3:
minVersion = SSL3_VERSION;
maxVersion = SSL3_VERSION;
break;
case QSsl::TlsV1_0:
minVersion = TLS1_VERSION;
maxVersion = TLS1_VERSION;
break;
case QSsl::TlsV1_1:
minVersion = TLS1_1_VERSION;
maxVersion = TLS1_1_VERSION;
break;
case QSsl::TlsV1_2:
minVersion = TLS1_2_VERSION;
maxVersion = TLS1_2_VERSION;
break;
// Ranges:
case QSsl::TlsV1SslV3:
case QSsl::AnyProtocol:
minVersion = SSL3_VERSION;
maxVersion = TLS_MAX_VERSION;
break;
case QSsl::SecureProtocols:
case QSsl::TlsV1_0OrLater:
minVersion = TLS1_VERSION;
maxVersion = TLS_MAX_VERSION;
break;
case QSsl::TlsV1_1OrLater:
minVersion = TLS1_1_VERSION;
maxVersion = TLS_MAX_VERSION;
break;
case QSsl::TlsV1_2OrLater:
minVersion = TLS1_2_VERSION;
maxVersion = TLS_MAX_VERSION;
break;
case QSsl::SslV2:
// This protocol is not supported by OpenSSL 1.1 and we handle
// it as an error (see the code above).
Q_UNREACHABLE();
break;
case QSsl::UnknownProtocol:
break;
}
if (minVersion != TLS_ANY_VERSION
&& !q_SSL_CTX_set_min_proto_version(sslContext->ctx, minVersion)) {
sslContext->errorStr = QSslSocket::tr("Error while setting the minimal protocol version");
sslContext->errorCode = QSslError::UnspecifiedError;
return;
}
if (maxVersion != TLS_ANY_VERSION
&& !q_SSL_CTX_set_max_proto_version(sslContext->ctx, maxVersion)) {
sslContext->errorStr = QSslSocket::tr("Error while setting the maximum protocol version");
sslContext->errorCode = QSslError::UnspecifiedError;
return;
}
// Enable bug workarounds.
long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions);
q_SSL_CTX_set_options(sslContext->ctx, options);

View File

@ -168,4 +168,10 @@ void q_BIO_set_init(BIO *a, int init);
int q_BIO_get_shutdown(BIO *a);
void q_BIO_set_shutdown(BIO *a, int shut);
#define q_SSL_CTX_set_min_proto_version(ctx, version) \
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nullptr)
#define q_SSL_CTX_set_max_proto_version(ctx, version) \
q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, nullptr)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -181,6 +181,10 @@ class QMacStylePrivate : public QCommonStylePrivate
{
Q_DECLARE_PUBLIC(QMacStyle)
public:
enum Direction {
North, South, East, West
};
enum CocoaControlType {
NoControl, // For when there's no such a control in Cocoa
Box, // QGroupBox
@ -188,7 +192,7 @@ public:
Button_Disclosure, // Disclosure triangle, like in QTreeView
Button_PopupButton, // Non-editable QComboBox
Button_PullDown, // QPushButton with menu
Button_PushButton,
Button_PushButton, // Plain QPushButton and QTabBar buttons
Button_RadioButton,
Button_SquareButton, // Oversized QPushButton
Button_WindowClose,
@ -199,6 +203,10 @@ public:
ProgressIndicator_Indeterminate,
Scroller_Horizontal,
Scroller_Vertical,
SegmentedControl_First, // QTabBar buttons focus ring
SegmentedControl_Middle,
SegmentedControl_Last,
SegmentedControl_Single,
Slider_Horizontal,
Slider_Vertical,
SplitView_Horizontal,
@ -207,7 +215,6 @@ public:
TextField
};
struct CocoaControl {
CocoaControl();
CocoaControl(CocoaControlType t, QStyleHelper::WidgetSizePolicy s);
@ -242,49 +249,24 @@ public:
static const int PushButtonContentPadding;
enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen, AquaScrollBar };
static ThemeDrawState getDrawState(QStyle::State flags);
QStyleHelper::WidgetSizePolicy aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
QStyle::ContentsType ct = QStyle::CT_CustomBase,
QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
QStyleHelper::WidgetSizePolicy effectiveAquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
QStyle::ContentsType ct = QStyle::CT_CustomBase,
QSize szHint=QSize(-1, -1), QSize *insz = 0) const;
void getSliderInfo(QStyle::ComplexControl cc, const QStyleOptionSlider *slider,
HIThemeTrackDrawInfo *tdi, const QWidget *needToRemoveMe) const;
inline int animateSpeed(Animates) const { return 33; }
// Utility functions
void drawColorlessButton(const CGRect &macRect, HIThemeButtonDrawInfo *bdi,
const CocoaControl &cw,
QPainter *p, const QStyleOption *opt) const;
static CGRect comboboxInnerBounds(const CGRect &outterBounds, const CocoaControl &cocoaWidget);
QSize pushButtonSizeFromContents(const QStyleOptionButton *btn) const;
CGRect pushButtonContentBounds(const QStyleOptionButton *btn,
const HIThemeButtonDrawInfo *bdi) const;
void initComboboxBdi(const QStyleOptionComboBox *combo, HIThemeButtonDrawInfo *bdi,
CocoaControl *cw,
const QWidget *widget, const ThemeDrawState &tds) const;
static CGRect comboboxInnerBounds(const CGRect &outerBounds, const CocoaControl &cocoaWidget);
static QRect comboboxEditBounds(const QRect &outerBounds, const HIThemeButtonDrawInfo &bdi);
static void drawCombobox(const CGRect &outerBounds, const HIThemeButtonDrawInfo &bdi, const CocoaControl &cw, QPainter *p);
bool contentFitsInPushButton(const QStyleOptionButton *btn, HIThemeButtonDrawInfo *bdi,
ThemeButtonKind buttonKindToCheck) const;
void initHIThemePushButton(const QStyleOptionButton *btn, const QWidget *widget,
const ThemeDrawState tds,
HIThemeButtonDrawInfo *bdi) const;
static QRectF comboboxEditBounds(const QRectF &outterBounds, const CocoaControl &cw);
void setAutoDefaultButton(QObject *button) const;
NSView *cocoaControl(CocoaControl widget) const;
NSCell *cocoaCell(CocoaControl widget) const;
static CocoaControl cocoaControlFromHIThemeButtonKind(ThemeButtonKind kind);
void setupNSGraphicsContext(CGContextRef cg, bool flipped) const;
void restoreNSGraphicsContext(CGContextRef cg) const;
@ -293,7 +275,6 @@ public:
void drawNSViewInRect(CocoaControl widget, NSView *view, const QRectF &rect, QPainter *p, bool isQWidget = true, __attribute__((noescape)) DrawRectBlock drawRectBlock = nil) const;
void resolveCurrentNSView(QWindow *window) const;
void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const;
void drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const;
void drawToolbarButtonArrow(const QStyleOption *opt, QPainter *p) const;
@ -304,6 +285,7 @@ public:
#if QT_CONFIG(tabbar)
void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const;
static Direction tabDirection(QTabBar::Shape shape);
#endif
public:

View File

@ -317,6 +317,9 @@ bool QDockWidgetGroupWindow::event(QEvent *e)
// We might need to show the widget again
destroyOrHideIfEmpty();
break;
case QEvent::Resize:
updateCurrentGapRect();
emit resized();
default:
break;
}
@ -467,6 +470,8 @@ void QDockWidgetGroupWindow::adjustFlags()
}
if (oldFlags != flags) {
if (!windowHandle())
create(); // The desired geometry is forgotten if we call setWindowFlags before having a window
setWindowFlags(flags);
const bool gainedNativeDecos = (oldFlags & Qt::FramelessWindowHint) && !(flags & Qt::FramelessWindowHint);
const bool lostNativeDecos = !(oldFlags & Qt::FramelessWindowHint) && (flags & Qt::FramelessWindowHint);
@ -546,12 +551,18 @@ bool QDockWidgetGroupWindow::hover(QLayoutItem *widgetItem, const QPoint &mouseP
currentGapPos = newGapPos;
newState.insertGap(currentGapPos, widgetItem);
newState.fitItems();
currentGapRect = newState.info(currentGapPos)->itemRect(currentGapPos.last(), true);
*layoutInfo() = std::move(newState);
updateCurrentGapRect();
layoutInfo()->apply(opts & QMainWindow::AnimatedDocks);
return true;
}
void QDockWidgetGroupWindow::updateCurrentGapRect()
{
if (!currentGapPos.isEmpty())
currentGapRect = layoutInfo()->info(currentGapPos)->itemRect(currentGapPos.last(), true);
}
/*
Remove the gap that was created by hover()
*/
@ -1977,6 +1988,8 @@ void QMainWindowLayout::setCurrentHoveredFloat(QDockWidgetGroupWindow *w)
if (currentHoveredFloat) {
disconnect(currentHoveredFloat.data(), &QObject::destroyed,
this, &QMainWindowLayout::updateGapIndicator);
disconnect(currentHoveredFloat.data(), &QDockWidgetGroupWindow::resized,
this, &QMainWindowLayout::updateGapIndicator);
if (currentHoveredFloat)
currentHoveredFloat->restore();
} else if (w) {
@ -1988,6 +2001,8 @@ void QMainWindowLayout::setCurrentHoveredFloat(QDockWidgetGroupWindow *w)
if (w) {
connect(w, &QObject::destroyed,
this, &QMainWindowLayout::updateGapIndicator, Qt::UniqueConnection);
connect(w, &QDockWidgetGroupWindow::resized,
this, &QMainWindowLayout::updateGapIndicator, Qt::UniqueConnection);
}
updateGapIndicator();
@ -2559,6 +2574,7 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)
dropTo->show();
dropTo->d_func()->plug(QRect());
w = floatingTabs;
widget->raise(); // raise, as our newly created drop target is now on top
}
Q_ASSERT(qobject_cast<QDockWidgetGroupWindow *>(w));
auto group = static_cast<QDockWidgetGroupWindow *>(w);

View File

@ -338,12 +338,16 @@ public:
bool hasNativeDecos() const;
bool hover(QLayoutItem *widgetItem, const QPoint &mousePos);
void updateCurrentGapRect();
void restore();
void apply();
QRect currentGapRect;
QList<int> currentGapPos;
signals:
void resized();
protected:
bool event(QEvent *) override;
void paintEvent(QPaintEvent*) override;

View File

@ -768,9 +768,8 @@ void tst_QDBusAbstractAdaptor::scriptableSignalOrNot()
con.connect(con.baseService(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
obj.emitSignal("scriptableSignalVoid", QVariant());
obj.emitSignal("nonScriptableSignalVoid", QVariant());
QTest::qWait(200);
QCOMPARE(spy.count, 1); // only /p1 must have emitted
QTRY_COMPARE(spy.count, 1); // only /p1 must have emitted
QCOMPARE(spy.interface, QString("local.MyObject"));
QCOMPARE(spy.name, QString("scriptableSignalVoid"));
QCOMPARE(spy.path, QString("/p1"));
@ -788,9 +787,8 @@ void tst_QDBusAbstractAdaptor::scriptableSignalOrNot()
con.connect(con.baseService(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
con.connect(con.baseService(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
obj.emitSignal("nonScriptableSignalVoid", QVariant());
QTest::qWait(200);
QCOMPARE(spy.count, 1); // only /p2 must have emitted now
QTRY_COMPARE(spy.count, 1); // only /p2 must have emitted now
QCOMPARE(spy.interface, QString("local.MyObject"));
QCOMPARE(spy.name, QString("nonScriptableSignalVoid"));
QCOMPARE(spy.path, QString("/p2"));
@ -1306,9 +1304,8 @@ void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer()
con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
emitSignalPeer("local.MyObject", "scriptableSignalVoid", QVariant());
emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant());
QTest::qWait(200);
QCOMPARE(spy.count, 1); // only /p1 must have emitted
QTRY_COMPARE(spy.count, 1); // only /p1 must have emitted
QCOMPARE(spy.interface, QString("local.MyObject"));
QCOMPARE(spy.name, QString("scriptableSignalVoid"));
QCOMPARE(spy.path, QString("/p1"));
@ -1327,9 +1324,8 @@ void tst_QDBusAbstractAdaptor::scriptableSignalOrNotPeer()
con.connect(QString(), "/p1", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
con.connect(QString(), "/p2", "local.MyObject", "nonScriptableSignalVoid", &spy, SLOT(slot(QDBusMessage)));
emitSignalPeer("local.MyObject", "nonScriptableSignalVoid", QVariant());
QTest::qWait(200);
QCOMPARE(spy.count, 1); // only /p2 must have emitted now
QTRY_COMPARE(spy.count, 1); // only /p2 must have emitted now
QCOMPARE(spy.interface, QString("local.MyObject"));
QCOMPARE(spy.name, QString("nonScriptableSignalVoid"));
QCOMPARE(spy.path, QString("/p2"));

View File

@ -136,9 +136,7 @@ void tst_QDBusConnection::sendSignalToName()
QVERIFY(con.send(msg));
QTest::qWait(1000);
QCOMPARE(spy.args.count(), 1);
QTRY_COMPARE(spy.args.count(), 1);
QCOMPARE(spy.args.at(0).toString(), QString("ping"));
}
@ -215,8 +213,7 @@ void tst_QDBusConnection::sendAsync()
"/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
QVERIFY(con.callWithCallback(msg, &spy, SLOT(asyncReply(QDBusMessage))));
QTest::qWait(1000);
QTRY_COMPARE(spy.args.count(), 1);
QCOMPARE(spy.args.value(0).typeName(), "QStringList");
QVERIFY(spy.args.at(0).toStringList().contains(con.baseService()));
}
@ -239,9 +236,7 @@ void tst_QDBusConnection::connect()
QVERIFY(con.send(msg));
QTest::qWait(1000);
QCOMPARE(spy.args.count(), 1);
QTRY_COMPARE(spy.args.count(), 1);
QCOMPARE(spy.args.at(0).toString(), QString("ping"));
}
@ -1072,9 +1067,8 @@ void tst_QDBusConnection::connectSignal()
QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
signal.member(), &recv, SLOT(oneSlot(QString))));
QVERIFY(con.send(signal));
QTest::qWait(100);
QTRY_COMPARE(recv.signalsReceived, 1);
QCOMPARE(recv.argumentReceived, signal.arguments().at(0).toString());
QCOMPARE(recv.signalsReceived, 1);
// disconnect and try with a signature
recv.argumentReceived.clear();
@ -1084,9 +1078,8 @@ void tst_QDBusConnection::connectSignal()
QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
signal.member(), "s", &recv, SLOT(oneSlot(QString))));
QVERIFY(con.send(signal));
QTest::qWait(100);
QTRY_COMPARE(recv.signalsReceived, 1);
QCOMPARE(recv.argumentReceived, signal.arguments().at(0).toString());
QCOMPARE(recv.signalsReceived, 1);
// confirm that we are, indeed, a unique connection
recv.argumentReceived.clear();
@ -1094,9 +1087,8 @@ void tst_QDBusConnection::connectSignal()
QVERIFY(!con.connect(con.baseService(), signal.path(), signal.interface(),
signal.member(), "s", &recv, SLOT(oneSlot(QString))));
QVERIFY(con.send(signal));
QTest::qWait(100);
QTRY_COMPARE(recv.signalsReceived, 1);
QCOMPARE(recv.argumentReceived, signal.arguments().at(0).toString());
QCOMPARE(recv.signalsReceived, 1);
}
void tst_QDBusConnection::slotsWithLessParameters()
@ -1114,9 +1106,8 @@ void tst_QDBusConnection::slotsWithLessParameters()
QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
signal.member(), &recv, SLOT(oneSlot())));
QVERIFY(con.send(signal));
QTest::qWait(100);
QTRY_COMPARE(recv.signalsReceived, 1);
QCOMPARE(recv.argumentReceived, QString());
QCOMPARE(recv.signalsReceived, 1);
// disconnect and try with a signature
recv.signalsReceived = 0;
@ -1125,18 +1116,16 @@ void tst_QDBusConnection::slotsWithLessParameters()
QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
signal.member(), "s", &recv, SLOT(oneSlot())));
QVERIFY(con.send(signal));
QTest::qWait(100);
QTRY_COMPARE(recv.signalsReceived, 1);
QCOMPARE(recv.argumentReceived, QString());
QCOMPARE(recv.signalsReceived, 1);
// confirm that we are, indeed, a unique connection
recv.signalsReceived = 0;
QVERIFY(!con.connect(con.baseService(), signal.path(), signal.interface(),
signal.member(), "s", &recv, SLOT(oneSlot())));
QVERIFY(con.send(signal));
QTest::qWait(100);
QTRY_COMPARE(recv.signalsReceived, 1);
QCOMPARE(recv.argumentReceived, QString());
QCOMPARE(recv.signalsReceived, 1);
}
void SignalReceiver::secondCallWithCallback()

View File

@ -414,8 +414,7 @@ void tst_QDBusThreading::registerObjectInOtherThread()
QCOMPARE(functionSpy, Object_method);
QCOMPARE(threadSpy, th);
QTest::qWait(100);
QCOMPARE(signalSpy, 1);
QTRY_COMPARE(signalSpy, 1);
sem2.acquire(); // the object is gone
functionSpy = NoMethod;
@ -462,8 +461,7 @@ void tst_QDBusThreading::registerAdaptorInOtherThread()
QCOMPARE(functionSpy, Adaptor_method);
QCOMPARE(threadSpy, th);
QTest::qWait(100);
QCOMPARE(signalSpy, 1);
QTRY_COMPARE(signalSpy, 1);
functionSpy = NoMethod;
threadSpy = 0;

View File

@ -156,10 +156,7 @@ void tst_QOpenGLWindow::resize()
// Check that a future resize triggers resizeGL.
w.resize(800, 600);
int maxWait = 1000;
while (w.resizeCount == resCount && maxWait-- >= 0)
QTest::qWait(10);
QVERIFY(w.resizeCount > resCount);
QTRY_VERIFY(w.resizeCount > resCount);
}
class PainterWindow : public QOpenGLWindow
@ -239,9 +236,7 @@ void tst_QOpenGLWindow::partial()
for (int i = 0; i < 10; ++i) {
w.paintCount = 0;
w.update();
int maxWait = 1000;
while (w.paintCount == 0 && maxWait-- >= 0)
QTest::qWait(10);
QTRY_VERIFY(w.paintCount > 0);
}
// Now since the painting went to an extra framebuffer, all the rects should

View File

@ -76,11 +76,7 @@ void tst_QRasterWindow::basic()
w.reset();
w.update();
int maxWait = 1000;
while (w.paintCount == 0 && --maxWait > 0)
QTest::qWait(10);
QVERIFY(w.paintCount >= 1);
QTRY_VERIFY(w.paintCount >= 1);
}
#include <tst_qrasterwindow.moc>

View File

@ -123,6 +123,12 @@ void Http2Server::emulateGOAWAY(int timeout)
goawayTimeout = timeout;
}
void Http2Server::redirectOpenStream(quint16 port)
{
redirectWhileReading = true;
targetPort = port;
}
void Http2Server::startServer()
{
#ifdef QT_NO_SSL
@ -775,7 +781,19 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody)
if (emptyBody)
writer.addFlag(FrameFlag::END_STREAM);
HttpHeader header = {{":status", "200"}};
HttpHeader header;
if (redirectWhileReading) {
qDebug("server received HEADERS frame (followed by DATA frames), redirecting ...");
Q_ASSERT(targetPort);
header.push_back({":status", "308"});
const QString url("%1://localhost:%2/");
header.push_back({"location", url.arg(clearTextHTTP2 ? QStringLiteral("http") : QStringLiteral("https"),
QString::number(targetPort)).toLatin1()});
} else {
header.push_back({":status", "200"});
}
if (!emptyBody) {
header.push_back(HPack::HeaderField("content-length",
QString("%1").arg(responseBody.size()).toLatin1()));
@ -871,7 +889,13 @@ void Http2Server::processRequest()
activeRequests[streamID] = decoder.decodedHeader();
if (headersFrame.flags().testFlag(FrameFlag::END_STREAM))
emit receivedRequest(streamID);
// else - we're waiting for incoming DATA frames ...
if (redirectWhileReading) {
sendResponse(streamID, true);
// Don't try to read any DATA frames ...
socket->disconnect();
} // else - we're waiting for incoming DATA frames ...
continuedRequest.clear();
}

View File

@ -74,6 +74,7 @@ public:
void enablePushPromise(bool enabled, const QByteArray &path = QByteArray());
void setResponseBody(const QByteArray &body);
void emulateGOAWAY(int timeout);
void redirectOpenStream(quint16 targetPort);
// Invokables, since we can call them from the main thread,
// but server (can) work on its own thread.
@ -186,6 +187,10 @@ private:
// We need it for PUSH_PROMISE, with the correct port number appended,
// when replying to essentially 1.1 request.
QByteArray authority;
// Redirect, with status code 308, as soon as we've seen headers, while client
// may still be sending DATA frames. See tst_Http2::earlyResponse().
bool redirectWhileReading = false;
quint16 targetPort = 0;
protected slots:
void ignoreErrorSlot();
};

View File

@ -74,6 +74,7 @@ private slots:
void pushPromise();
void goaway_data();
void goaway();
void earlyResponse();
protected slots:
// Slots to listen to our in-process server:
@ -439,6 +440,47 @@ void tst_Http2::goaway()
QVERIFY(!serverGotSettingsACK);
}
void tst_Http2::earlyResponse()
{
// In this test we'd like to verify client side can handle HEADERS frame while
// its stream is in 'open' state. To achieve this, we send a POST request
// with some payload, so that the client is first sending HEADERS and then
// DATA frames without END_STREAM flag set yet (thus the stream is in Stream::open
// state). Upon receiving the client's HEADERS frame our server ('redirector')
// immediately (without trying to read any DATA frames) responds with status
// code 308. The client should properly handle this.
clearHTTP2State();
serverPort = 0;
nRequests = 1;
ServerPtr targetServer(newServer(defaultServerSettings));
QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection);
runEventLoop();
QVERIFY(serverPort != 0);
const quint16 targetPort = serverPort;
serverPort = 0;
ServerPtr redirector(newServer(defaultServerSettings));
redirector->redirectOpenStream(targetPort);
QMetaObject::invokeMethod(redirector.data(), "startServer", Qt::QueuedConnection);
runEventLoop();
QVERIFY(serverPort);
sendRequest(1, QNetworkRequest::NormalPriority, {10000000, Qt::Uninitialized});
runEventLoop();
QVERIFY(nRequests == 0);
QVERIFY(prefaceOK);
QVERIFY(serverGotSettingsACK);
}
void tst_Http2::serverStarted(quint16 port)
{
serverPort = port;
@ -500,6 +542,7 @@ void tst_Http2::sendRequest(int streamNumber,
QNetworkRequest request(url);
request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true));
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, QVariant(true));
request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
request.setPriority(priority);
@ -592,6 +635,10 @@ void tst_Http2::replyFinished()
const QVariant spdyUsed(reply->attribute(QNetworkRequest::SpdyWasUsedAttribute));
QVERIFY(spdyUsed.isValid());
QVERIFY(!spdyUsed.toBool());
const QVariant code(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute));
QVERIFY(code.isValid());
QVERIFY(code.canConvert<int>());
QCOMPARE(code.value<int>(), 200);
}
--nRequests;

View File

@ -1188,13 +1188,7 @@ void tst_QSslSocket::protocolServerSide_data()
#if !defined(OPENSSL_NO_SSL2)
// OpenSSL 1.1 has removed SSL2 support. But there is no OPENSSL_NO_SSL2 macro ...
#define OPENSSL_NO_SSL2
#endif
// A client using our OpenSSL1.1 backend will negotiate up from TLS 1.0 or 1.1
// to TLS 1.2 if the server asks for it, where our older backend fails to compromise.
// So some tests that fail for the old pass with the new.
const bool willUseTLS12 = true;
#else
const bool willUseTLS12 = false;
#endif // OPENSSL_NO_SSL2
#endif // opensslv11
#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT)
@ -1290,7 +1284,7 @@ void tst_QSslSocket::protocolServerSide_data()
QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false;
#endif
QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << willUseTLS12;
QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false;
QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true;
QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true;
@ -1300,8 +1294,8 @@ void tst_QSslSocket::protocolServerSide_data()
#if !defined(OPENSSL_NO_SSL3)
QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false;
#endif
QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << willUseTLS12;
QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << willUseTLS12;
QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false;
QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false;
QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true;
QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true;

View File

@ -923,8 +923,7 @@ void tst_QGL::partialGLWidgetUpdates()
widget.setFixedSize(150, 150);
widget.setAutoFillBackground(autoFillBackground);
widget.show();
QTest::qWait(200);
QVERIFY(QTest::qWaitForWindowExposed(&widget));
if (widget.format().doubleBuffer() != doubleBufferedContext)
QSKIP("Platform does not support requested format");

View File

@ -9,5 +9,3 @@ QT += core-private gui-private
SOURCES += tst_qfiledialog.cpp
DEFINES += SRCDIR=\\\"$$PWD/\\\"
linux*: CONFIG += insignificant_test # Crashes on different Linux distros

View File

@ -2,3 +2,6 @@
opensuse-42.3 ci
[testLineEditValidation]
opensuse-42.3 ci
[comboBox]
# QTBUG-67282
opensuse

View File

@ -1389,13 +1389,12 @@ void tst_QItemDelegate::comboBox()
QTableWidget widget(1, 1);
widget.setItem(0, 0, item1);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
widget.editItem(item1);
QTestEventLoop::instance().enterLoop(1);
QComboBox *boolEditor = widget.viewport()->findChild<QComboBox*>();
QVERIFY(boolEditor);
QComboBox *boolEditor = nullptr;
QTRY_VERIFY( (boolEditor = widget.viewport()->findChild<QComboBox*>()) );
QCOMPARE(boolEditor->currentIndex(), 1); // True is selected initially.
// The data must actually be different in order for the model
// to be updated.

View File

@ -911,7 +911,7 @@ void tst_QWidget_window::setWindowState()
// Minimizing keeps other states
w.showMinimized();
QCOMPARE(w.windowState(), state | Qt::WindowMinimized);
QTest::qWait(100);
QTest::qWait(200);
QCOMPARE(w.windowState(), state | Qt::WindowMinimized);
QCOMPARE(w.windowHandle()->windowStates(), state | Qt::WindowMinimized);
}

View File

@ -128,12 +128,12 @@ void tst_QMacStyle::sizeHints()
QComboBox comboBox1(&w);
comboBox1.setEditable(false);
comboBox1.addItem("Foo");
QCOMPARE(sh(&comboBox1).height(), SIZE(20, 17, 15));
QCOMPARE(sh(&comboBox1).height(), SIZE(26, 17, 15));
QComboBox comboBox2(&w);
comboBox2.setEditable(true);
comboBox2.addItem("Foo");
QCOMPARE(sh(&comboBox2).height(), SIZE(22, 17, 15));
QCOMPARE(sh(&comboBox2).height(), SIZE(26, 17, 15));
// Combos in toolbars use the actual widget rect to
// avoid faulty clipping:
@ -141,7 +141,7 @@ void tst_QMacStyle::sizeHints()
setSize(&tb, size);
QComboBox comboBox3(&tb);
comboBox3.addItem("Foo");
QCOMPARE(sh(&comboBox3).height(), SIZE(26, -1, -1));
QCOMPARE(sh(&comboBox3).height(), SIZE(32, -1, -1));
QSlider slider1(Qt::Horizontal, &w);
QCOMPARE(sh(&slider1).height(), SIZE(15, 12, 10));

View File

@ -127,7 +127,7 @@ QPixmap rasterPixmap(const QImage &image)
QPlatformPixmap *data =
new QRasterPlatformPixmap(QPlatformPixmap::PixmapType);
data->fromImage(image, Qt::AutoColor);
data->fromImage(image, Qt::AutoColor | Qt::NoFormatConversion);
return QPixmap(data);
}
@ -613,9 +613,7 @@ void tst_QPainter::drawPixmapImage_data_helper(bool pixmaps)
QTest::addColumn<int>("type"); // 0 = circle, 1 = diag line, 2 = solid rect, 3 = alpharect
QList<QSize> sizes;
sizes << QSize(1, 1)
<< QSize(10, 10)
<< QSize(100, 100)
sizes << QSize(10, 10)
<< QSize(1000, 1000);
const char *typeNames[] = {
@ -657,7 +655,6 @@ void tst_QPainter::drawPixmapImage_data_helper(bool pixmaps)
QImage::Format_RGB32,
QImage::Format_ARGB32_Premultiplied,
QImage::Format_RGB16,
QImage::Format_ARGB8565_Premultiplied,
QImage::Format_BGR30,
QImage::Format_Invalid
};
@ -682,12 +679,9 @@ void tst_QPainter::drawPixmapImage_data_helper(bool pixmaps)
QImage::Format_ARGB32,
QImage::Format_ARGB32_Premultiplied,
QImage::Format_RGB16,
QImage::Format_ARGB8565_Premultiplied,
QImage::Format_RGB888,
QImage::Format_RGBX8888,
QImage::Format_RGBA8888,
QImage::Format_RGBA8888_Premultiplied,
QImage::Format_A2BGR30_Premultiplied,
QImage::Format_RGB30,
QImage::Format_Grayscale8,
QImage::Format_Invalid