summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/qtmodule-configtests340
-rwxr-xr-xbin/syncqt155
-rwxr-xr-xconfigure10
-rw-r--r--dist/changes-5.0.03
-rw-r--r--doc/src/examples/padnavigator.qdoc2
-rw-r--r--examples/tools/settingseditor/locationdialog.cpp2
-rw-r--r--examples/tutorials/addressbook-fr/README2
-rw-r--r--examples/tutorials/addressbook/README2
-rw-r--r--mkspecs/features/declarative_debug.prf1
-rw-r--r--mkspecs/features/default_pre.prf4
-rw-r--r--mkspecs/features/qt_functions.prf2
-rw-r--r--mkspecs/features/qt_module_config.prf3
-rw-r--r--qmake/project.cpp11
-rw-r--r--qtbase.pro5
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-external.h2
-rw-r--r--src/3rdparty/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp2
-rw-r--r--src/corelib/arch/qatomic_bootstrap.h23
-rw-r--r--src/corelib/global/qglobal.cpp7
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp2
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp210
-rw-r--r--src/corelib/kernel/qmetaobject.cpp25
-rw-r--r--src/corelib/kernel/qmetaobject_p.h3
-rw-r--r--src/corelib/kernel/qobject.cpp32
-rw-r--r--src/corelib/plugin/qlibrary.cpp10
-rw-r--r--src/corelib/plugin/qlibrary.h8
-rw-r--r--src/corelib/plugin/qlibrary_p.h4
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp14
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp8
-rw-r--r--src/corelib/plugin/qsystemlibrary_p.h8
-rw-r--r--src/corelib/thread/qmutex.cpp435
-rw-r--r--src/corelib/thread/qmutex.h121
-rw-r--r--src/corelib/thread/qmutex_linux.cpp138
-rw-r--r--src/corelib/thread/qmutex_mac.cpp96
-rw-r--r--src/corelib/thread/qmutex_p.h70
-rw-r--r--src/corelib/thread/qmutex_unix.cpp116
-rw-r--r--src/corelib/thread/qmutex_win.cpp10
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h12
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp2
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp2
-rw-r--r--src/corelib/thread/thread.pri9
-rw-r--r--src/corelib/tools/qbytearray.cpp21
-rw-r--r--src/corelib/tools/qbytearray.h18
-rw-r--r--src/corelib/tools/qchar.cpp13
-rw-r--r--src/corelib/tools/qfreelist.cpp67
-rw-r--r--src/corelib/tools/qfreelist_p.h294
-rw-r--r--src/corelib/tools/qharfbuzz.cpp2
-rw-r--r--src/corelib/tools/qshareddata.h3
-rw-r--r--src/corelib/tools/qstring.cpp18
-rw-r--r--src/corelib/tools/qstring.h35
-rw-r--r--src/corelib/tools/qstringbuilder.cpp5
-rw-r--r--src/corelib/tools/qstringbuilder.h29
-rw-r--r--src/corelib/tools/tools.pri2
-rw-r--r--src/dbus/qdbus_symbols.cpp9
-rw-r--r--src/dbus/qdbus_symbols_p.h4
-rw-r--r--src/dbus/qdbusmetaobject.cpp12
-rw-r--r--src/gui/image/qbmphandler.cpp64
-rw-r--r--src/gui/image/qtiffhandler.cpp13
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp16
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp7
-rw-r--r--src/gui/painting/qpaintengineex.cpp10
-rw-r--r--src/gui/painting/qpaintengineex_p.h1
-rw-r--r--src/gui/text/qfontengine_p.h3
-rw-r--r--src/gui/text/qrawfont.cpp8
-rw-r--r--src/gui/text/qrawfont.h8
-rw-r--r--src/gui/text/qrawfont_ft.cpp4
-rw-r--r--src/gui/text/qrawfont_p.h2
-rw-r--r--src/gui/text/qrawfont_qpa.cpp2
-rw-r--r--src/gui/text/qtextcontrol.cpp3
-rw-r--r--src/gui/text/qtextengine.cpp2
-rw-r--r--src/gui/util/qvalidator.cpp101
-rw-r--r--src/gui/util/qvalidator.h27
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp10
-rw-r--r--src/opengl/qgl_x11.cpp8
-rw-r--r--src/opengl/qglpixelbuffer_x11.cpp2
-rw-r--r--src/plugins/platforms/xlib/qxlibstatic.cpp6
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp36
-rw-r--r--src/testlib/testlib.pro2
-rw-r--r--src/widgets/platforms/mac/qrawfont_mac.cpp2
-rw-r--r--src/widgets/platforms/win/qrawfont_win.cpp8
-rw-r--r--src/widgets/platforms/x11/qkeymapper_x11.cpp2
-rw-r--r--src/widgets/widgets/qtabwidget.h3
-rw-r--r--src/winmain/winmain.pro2
-rw-r--r--tests/auto/corelib.pro1
-rw-r--r--tests/auto/moc/moc.pro2
-rw-r--r--tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro2
-rw-r--r--tests/auto/qcoreapplication/tst_qcoreapplication.cpp45
-rw-r--r--tests/auto/qdialog/qdialog.pro3
-rw-r--r--tests/auto/qdialog/tst_qdialog.cpp16
-rw-r--r--tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp57
-rw-r--r--tests/auto/qfile/test/test.pro2
-rw-r--r--tests/auto/qfile/tst_qfile.cpp2
-rw-r--r--tests/auto/qfilesystemmodel/qfilesystemmodel.pro2
-rw-r--r--tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp4
-rw-r--r--tests/auto/qfreelist/qfreelist.pro6
-rw-r--r--tests/auto/qfreelist/tst_qfreelist.cpp179
-rw-r--r--tests/auto/qftp/qftp.pro2
-rw-r--r--tests/auto/qftp/tst_qftp.cpp2
-rw-r--r--tests/auto/qglobal/tst_qglobal.cpp2
-rw-r--r--tests/auto/qgraphicstransform/qgraphicstransform.pro2
-rw-r--r--tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp58
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp1
-rw-r--r--tests/auto/qicon/qicon.pro2
-rw-r--r--tests/auto/qicon/tst_qicon.cpp20
-rw-r--r--tests/auto/qimagereader/images/test32bfv4.bmpbin0 -> 232874 bytes
-rw-r--r--tests/auto/qimagereader/images/test32v5.bmpbin0 -> 174858 bytes
-rw-r--r--tests/auto/qimagereader/qimagereader.pro8
-rw-r--r--tests/auto/qimagereader/qimagereader.qrc2
-rw-r--r--tests/auto/qimagereader/tst_qimagereader.cpp311
-rw-r--r--tests/auto/qintvalidator/tst_qintvalidator.cpp33
-rw-r--r--tests/auto/qiodevice/tst_qiodevice.cpp8
-rw-r--r--tests/auto/qlibrary/tst_qlibrary.cpp2
-rw-r--r--tests/auto/qlineedit/tst_qlineedit.cpp87
-rw-r--r--tests/auto/qmessagebox/qmessagebox.pro2
-rw-r--r--tests/auto/qmessagebox/tst_qmessagebox.cpp83
-rw-r--r--tests/auto/qmutex/tst_qmutex.cpp111
-rw-r--r--tests/auto/qnetworkaddressentry/qnetworkaddressentry.pro2
-rw-r--r--tests/auto/qnetworkaddressentry/tst_qnetworkaddressentry.cpp2
-rw-r--r--tests/auto/qprocess/tst_qprocess.cpp6
-rw-r--r--tests/auto/qrawfont/tst_qrawfont.cpp25
-rw-r--r--tests/auto/qregexpvalidator/tst_qregexpvalidator.cpp3
-rw-r--r--tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp23
-rw-r--r--tests/auto/qsslcertificate/tst_qsslcertificate.cpp43
-rw-r--r--tests/auto/qstring/tst_qstring.cpp2
-rw-r--r--tests/auto/qstringbuilder1/stringbuilder.cpp47
-rw-r--r--tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro2
-rw-r--r--tests/auto/qtcpserver/tst_qtcpserver.cpp2
-rw-r--r--tests/auto/qtextedit/tst_qtextedit.cpp27
-rw-r--r--tests/auto/qtextscriptengine/qtextscriptengine.pro2
-rw-r--r--tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp101
-rw-r--r--tests/auto/qwaitcondition/tst_qwaitcondition.cpp8
-rw-r--r--tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp11
-rw-r--r--tools/configure/configureapp.cpp6
133 files changed, 2914 insertions, 1256 deletions
diff --git a/bin/qtmodule-configtests b/bin/qtmodule-configtests
new file mode 100755
index 0000000000..f6cc2052da
--- /dev/null
+++ b/bin/qtmodule-configtests
@@ -0,0 +1,340 @@
+#!/usr/bin/perl
+######################################################################
+#
+# Runs any module configuration tests
+#
+# Called (currently) from syncqt, and expects a few arguments
+#
+# configtests $basedir $out_basedir $qtbasedir $quietmode
+#
+# Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+# Contact: Nokia Corporation (qt-info@nokia.com)
+#
+######################################################################
+
+use strict;
+use warnings;
+
+# use packages -------------------------------------------------------
+use File::Basename;
+use File::Path 'mkpath';
+use File::Spec::Functions;
+use Cwd;
+use Cwd 'abs_path';
+use Config;
+
+# Which file to look for the %configtests variable in
+my $configTestSource = "sync.profile";
+
+if ($#ARGV < 3) {
+ warn "Usage:\n";
+ warn " $0 <module base directory> <module output directory> <QtBase directory> <generator spec>\n";
+ exit 1;
+}
+
+# These might be needed in sync.profile
+our $basedir = $ARGV[0];
+our $out_basedir = $ARGV[1];
+our $qtbasedir = $ARGV[2];
+my $generator = $ARGV[3];
+
+our %configtests;
+
+my $qmakeCachePath = catfile($out_basedir, ".qmake.cache");
+
+my $QMAKE = catfile($qtbasedir, "bin", ($^O =~ /win32/i) ? 'qmake.exe' : 'qmake');
+if (!-x $QMAKE) {
+ # try the qmake from the path (e.g. this is a shadow build)
+ $QMAKE = 'qmake';
+}
+
+# Need to use the right make
+# SYMBIAN_UNIX/MINGW should fall back to the non SYMBIAN ones
+my $MAKE = 'make'; # default, only works on unix
+if ($generator =~ /UNIX|XCODE/i) { # XCODE = make?
+ $MAKE = 'make';
+} elsif ($generator =~ /MINGW/i) {
+ $MAKE = 'mingw32-make';
+} elsif ($generator =~ /MSVC.NET|MSBUILD/i) {
+ $MAKE = 'nmake';
+} else {
+ # Unhandled (at least): BMAKE, GBUILD, SYMBIAN_ABLD, SYMBIAN_SBSV2
+ warn "Unrecognized generator spec ($generator) - assuming '$MAKE'\n";
+}
+
+######################################################################
+# Syntax: fileContents(filename)
+# Params: filename, string, filename of file to return contents
+#
+# Purpose: Get the contents of a file.
+# Returns: String with contents of the file, or empty string if file
+# doens't exist.
+# Warning: Dies if it does exist but script cannot get read access.
+######################################################################
+sub fileContents {
+ my ($filename) = @_;
+ my $filecontents = "";
+ if (-e $filename) {
+ open(I, "< $filename") || die "Could not open $filename for reading, read block?";
+ local $/;
+ binmode I;
+ $filecontents = <I>;
+ close I;
+ }
+ return $filecontents;
+}
+
+######################################################################
+# Syntax: loadConfigTests()
+#
+# Purpose: Loads the config tests from the source basedir into %configtests.
+# Returns: Nothing
+######################################################################
+sub loadConfigTests {
+ my $configprofile = catfile($basedir, $configTestSource);
+ my $result;
+ unless ($result = do $configprofile) {
+ die "configtests couldn't parse $configprofile: $@\n" if $@;
+ # We don't check for non null output, since that is valid
+ }
+}
+
+######################################################################
+# Syntax: hashesAreDifferent
+#
+# Purpose: Compares two hashes. (must have same key=value for everything)
+# Returns: 0 if they are the same, 1 otherwise
+######################################################################
+sub hashesAreDifferent {
+ my %a = %{$_[0]};
+ my %b = %{$_[1]};
+
+ if (keys %a != keys %b) {
+ return 1;
+ }
+
+ my %cmp = map { $_ => 1 } keys %a;
+ for my $key (keys %b) {
+ last unless exists $cmp{$key};
+ last unless $a{$key} eq $b{$key};
+ delete $cmp{$key};
+ }
+ if (%cmp) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+######################################################################
+# Syntax: executeSomething
+# Params: A list of things.
+#
+# Purpose: Executes the first arg, passing the list.
+# stderr is redirected to stdout, and the output is captured.
+# Returns: The output.
+######################################################################
+sub executeSomething {
+ my ($program, @args) = @_;
+
+ my $pid = open(KID_TO_READ, "-|");
+
+ my $output;
+
+ if ($pid) { # parent
+ while (<KID_TO_READ>) {
+ $output = $output . $_;
+ }
+ close(KID_TO_READ) || $! == 0 || warn "\nFailed to execute $program: exited $?";
+ } else {
+ # redirect STDERR to STDOUT
+ open STDERR, ">&STDOUT";
+
+ # Exec something
+ exec ($program, @args) || die "\nCan't exec $program: $!\n";
+ # NOTREACHED
+ }
+
+ return $output;
+}
+
+######################################################################
+# Syntax: executeTest()
+# Params: testName
+#
+# The testName variable controls the actual config test run - the
+# source is assumed to be in $basedir/config.tests/$testName, and
+# when 'qmake; make clean; make' is run, is expected to produce a file
+# $out_basedir/config.tests/$testName/$testName. If this test passes,
+# then 'config_test_$testName = yes' will be written to $out_basedir/.qmake.cache
+#
+# Purpose: Runs a configuration time test.
+# Returns: 0 if the test fails, 1 if it passes, 2 if the test is skipped
+# (e.g. .pro file has requires(x) and x is not satisfied)
+######################################################################
+sub executeTest {
+ my ($testName) = @_;
+
+ my $oldWorkingDir = getcwd();
+ my $ret = 0;
+
+ my @QMAKEARGS = ('CONFIG-=debug_and_release');
+
+ my $testOutDir = catdir($out_basedir, 'config.tests', $testName);
+
+ # Since we might be cross compiling, look for barename (Linux) and .exe (Win32/Symbian)
+ my $testOutFile1 = catfile($testOutDir, "$testName.exe");
+ my $testOutFile2 = catfile($testOutDir, $testName);
+
+ if (abs_path($basedir) eq abs_path($out_basedir)) {
+ chdir $testOutDir or die "\nUnable to change to config test directory ($testOutDir): $!\n";
+ } else { # shadow build
+ if (! -e $testOutDir) {
+ mkpath $testOutDir or die "\nUnable to create shadow build config test directory ($testOutDir): $!\n";
+ }
+ chdir $testOutDir or die "\nUnable to change to config test directory ($testOutDir): $!\n";
+
+ push (@QMAKEARGS, catdir($basedir, 'config.tests', $testName));
+ }
+
+ # First remove existing stuff (XXX this probably needs generator specific code, but hopefully
+ # the target removal below will suffice)
+ if (-e "Makefile") {
+ executeSomething($MAKE, 'distclean');
+ }
+
+ # and any targets that we might find that weren't distcleaned
+ unlink $testOutFile1, $testOutFile2;
+
+ # Run qmake && make
+ executeSomething($QMAKE, @QMAKEARGS);
+ my $makeOutput = executeSomething(($MAKE));
+
+ # If make prints "blah blah blah\nSkipped." we consider this a skipped test
+ if ($makeOutput !~ qr(^Skipped\.$)ms) {
+ # Check the test exists (can't reliably execute, especially for cross compilation)
+ if (-e $testOutFile1 or -e $testOutFile2) {
+ $ret = 1;
+ }
+ } else {
+ $ret = 2;
+ }
+
+ chdir $oldWorkingDir or die "\nUnable to restore working directory: $!\n";
+ return $ret;
+}
+
+# Now run configuration tests
+# %configtests is a map from config test name to a map of parameters
+# e.g:
+#
+# %configtests = (
+# "simple" => {fatal => 1, message => "Missing required 'simple' component\n"},
+# "failed" => {message => "You need to install the FAILED sdk for this to work\n"}
+# );
+#
+# Parameters and their defaults:
+# - fatal [false] - whether failing this test should abort everything
+# - message [""] - A special message to display if this test fails
+#
+loadConfigTests();
+
+# Only do this step for modules that have config tests
+# (qtbase doesn't). We try to preserve existing contents (and furthermore
+# only write to .qmake.cache if the tests change)
+if (abs_path($out_basedir) ne abs_path($qtbasedir)) {
+ # Read any existing content
+ my $existingContents = fileContents($qmakeCachePath);
+ my %oldTestResults;
+ my %newTestResults;
+ my @fatalTestsEncountered;
+
+ # Parse the existing results so we can check if we change them
+ while ($existingContents =~ /^config_test_(.*) = (yes|no)$/gm) {
+ $oldTestResults{$1} = $2;
+ }
+
+ # Get the longest length test name so we can pretty print
+ use List::Util qw(max);
+ my $maxNameLength = max map { length $_ } keys %configtests;
+
+ # Turn off buffering
+ $| = 1;
+
+ # Now run the configuration tests
+ print "Configuration tests:\n";
+
+ while ((my $testName, my $testParameters) = each %configtests) {
+ printf " % *s: ", $maxNameLength, $testName; # right aligned, yes/no lines up
+
+ my $fatalTest = $testParameters->{"fatal"} // 0;
+ my $message = $testParameters->{"message"};
+
+ my $testResult = executeTest($testName);
+ my @testResultStrings = ("no\n","yes\n","skipped\n");
+
+ $newTestResults{$testName} = (($testResult == 1) ? "yes" : "no"); # skipped = no
+
+ if ($testResult == 0) {
+ # Failed test
+ if ($fatalTest) {
+ print "no (fatal)\n";
+ # Report the fatality at the end, too
+ push (@fatalTestsEncountered, $testName);
+ } else {
+ print "no\n";
+ }
+ if (defined($message)) {
+ print $message;
+ print "\n" unless chop $message eq "\n";
+ }
+ } else {
+ # yes or skipped
+ print $testResultStrings[$testResult];
+ }
+ }
+
+ # Check if the test results are different
+ if (hashesAreDifferent(\%oldTestResults, \%newTestResults)) {
+ # Generate the new contents
+ my $newContents = $existingContents;
+
+ # Strip out any existing config test results
+ $newContents =~ s/^config_test_.*$//gms;
+ $newContents =~ s/^# Compile time test results.*$//gms;
+
+ # Add any remaining content and make sure we start on a new line
+ if ($newContents and chop $newContents ne '\n') {
+ $newContents = $newContents . "\n";
+ }
+
+ # Results and header
+ if (%newTestResults) {
+ $newContents = $newContents . '# Compile time test results ('.(localtime).")\n";
+
+ # Results
+ while ((my $testName, my $testResult) = each %newTestResults) {
+ $newContents = $newContents . "config_test_$testName = $testResult\n";
+ }
+ }
+
+ # and open the file
+ open my $cacheFileHandle, ">$qmakeCachePath" or die "Unable to open $qmakeCachePath for writing: $!\n";
+
+ print $cacheFileHandle $newContents;
+
+ close $cacheFileHandle or die "Unable to close $qmakeCachePath: $!\n";
+ }
+
+ # Now see if we have to die
+ if (@fatalTestsEncountered) {
+ if ($#fatalTestsEncountered == 0) {
+ warn "Mandatory configuration test (".$fatalTestsEncountered[0].") failed.\n\n";
+ } else {
+ warn "Mandatory configuration tests (". join (", ", @fatalTestsEncountered) . ") failed.\n\n";
+ }
+ exit -1;
+ }
+}
+
+exit 0;
diff --git a/bin/syncqt b/bin/syncqt
index 776ee9c257..0dcbc4d58e 100755
--- a/bin/syncqt
+++ b/bin/syncqt
@@ -15,6 +15,7 @@ use Cwd;
use Cwd 'abs_path';
use Config;
use strict;
+use English qw(-no_match_vars );
# set output basedir to be where ever syncqt is run from
our $out_basedir = getcwd();
@@ -38,7 +39,7 @@ our (%modules, %moduleheaders, %classnames, %mastercontent, %modulepris);
my $isunix = 0;
my $module = 0;
my $showonly = 0;
-my $quiet = 0;
+my $verbose_level = 1;
my $remove_stale = 1;
my $force_win = 0;
my $force_relative = 0;
@@ -50,6 +51,7 @@ my $module_fwd = "";
my $cache_module_fwd = 0;
my $developer_build = 0;
my $no_module_version_header = 0;
+my $makefile_generator = "";
my @modules_to_sync ;
$force_relative = 1 if ( -d "/System/Library/Frameworks" );
@@ -75,7 +77,9 @@ sub showUsage
print " -showonly Show action but not perform (default: " . ($showonly ? "yes" : "no") . ")\n";
print " -outdir <PATH> Specify output directory for sync (default: $out_basedir)\n";
print " -qtdir <PATH> Set the path to QtBase (detected: " . (defined $qtbasedir ? $qtbasedir : "-none-") . ")\n";
- print " -quiet Only report problems, not activity (default: " . ($quiet ? "yes" : "no") . ")\n";
+ print " -quiet Only report problems, not activity (same as -verbose 0)\n";
+ print " -v, -verbose <level> Sets the verbosity level (max. 4) (default: $verbose_level)\n";
+ print " The short form increases the level by +1\n";
print " -separate-module <NAME>:<PROFILEDIR>:<HEADERDIR>\n";
print " Create headers for <NAME> with original headers in\n";
print " <HEADERDIR> relative to <PROFILEDIR> \n";
@@ -88,6 +92,7 @@ sub showUsage
print " easy development\n";
print " -no-module-version-header\n";
print " Don't create module version header file\n";
+ print " -generator <PATH> Specify the makefile generator setting (e.g. 'UNIX')\n";
print " -help This help\n";
exit 0;
}
@@ -273,6 +278,15 @@ sub classNames {
return @ret;
}
+sub make_path {
+ my ($dir, $lib, $be_verbose) = @_;
+ unless(-e $dir) {
+ mkpath $dir;
+ $dir = "<outbase>" . substr($dir, length($out_basedir)) if ($be_verbose < 3);
+ print "$lib: mkpath $dir\n" if ($be_verbose > 1);
+ }
+}
+
######################################################################
# Syntax: syncHeader(header, iheader, copy, timestamp)
# Params: header, string, filename to create "symlink" for
@@ -284,14 +298,14 @@ sub classNames {
# Returns: 1 if successful, else 0.
######################################################################
sub syncHeader {
- my ($header, $iheader, $copy, $ts) = @_;
+ my ($lib, $header, $iheader, $copy, $ts) = @_;
$iheader =~ s=\\=/=g;
$header =~ s=\\=/=g;
- return copyFile($iheader, $header) if($copy);
+ return copyFile($lib, $iheader, $header) if($copy);
unless(-e $header) {
my $header_dir = dirname($header);
- mkpath $header_dir, !$quiet;
+ make_path($header_dir, $lib, $verbose_level);
#write it
my $iheader_out = fixPaths($iheader, $header_dir);
@@ -412,7 +426,7 @@ sub fileCompare {
######################################################################
sub copyFile
{
- my ($file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_;
+ my ($lib, $file,$ifile, $copy,$knowdiff,$filecontents,$ifilecontents) = @_;
# Bi-directional synchronization
open( I, "< " . $file ) || die "Could not open $file for reading";
local $/;
@@ -434,7 +448,7 @@ sub copyFile
if ( $knowdiff || ($filecontents ne $ifilecontents) ) {
if ( $copy > 0 ) {
my $file_dir = dirname($file);
- mkpath $file_dir, !$quiet unless(-e $file_dir);
+ make_path($file_dir, $lib, $verbose_level);
open(O, "> " . $file) || die "Could not open $file for writing (no write permission?)";
local $/;
binmode O;
@@ -444,7 +458,7 @@ sub copyFile
return 1;
} elsif ( $copy < 0 ) {
my $ifile_dir = dirname($ifile);
- mkpath $ifile_dir, !$quiet unless(-e $ifile_dir);
+ make_path($ifile_dir, $lib, $verbose_level);
open(O, "> " . $ifile) || die "Could not open $ifile for writing (no write permission?)";
local $/;
binmode O;
@@ -468,10 +482,10 @@ sub copyFile
######################################################################
sub symlinkFile
{
- my ($file,$ifile) = @_;
+ my ($lib, $file, $ifile) = @_;
if ($isunix) {
- print "symlink created for $file " unless $quiet;
+ print "$lib: symlink created for $file " if ($verbose_level);
if ( $force_relative && ($ifile =~ /^$quoted_basedir/)) {
my $t = getcwd();
my $c = -1;
@@ -479,12 +493,12 @@ sub symlinkFile
$t =~ s-^$quoted_basedir/--;
$p .= "../" while( ($c = index( $t, "/", $c + 1)) != -1 );
$file =~ s-^$quoted_basedir/-$p-;
- print " ($file)\n" unless $quiet;
+ print " ($file)\n" if($verbose_level);
}
- print "\n" unless $quiet;
+ print "\n" if($verbose_level);
return symlink($file, $ifile);
}
- return copyFile($file, $ifile);
+ return copyFile($lib, $file, $ifile);
}
######################################################################
@@ -534,8 +548,10 @@ sub findFiles {
######################################################################
sub loadSyncProfile {
my ($srcbase, $outbase) = @_;
- print("srcbase = $$srcbase \n");
- print("outbase = $$outbase \n");
+ if ($verbose_level) {
+ print("<srcbase> = $$srcbase \n");
+ print("<outbase> = $$outbase \n");
+ }
my $syncprofile = "$$srcbase/sync.profile";
my $result;
@@ -627,8 +643,14 @@ while ( @ARGV ) {
$var = "showonly";
$val = "yes";
} elsif($arg eq "-quiet") {
- $var = "quiet";
+ $var = "verbose";
+ $val = "0";
+ } elsif($arg eq "-v") {
+ $var = "verbose";
$val = "yes";
+ } elsif($arg eq "-verbose") {
+ $var = "verbose";
+ $val = shift @ARGV;
} elsif($arg eq "-private") {
$var = "create_private_headers";
$val = "yes";
@@ -639,6 +661,9 @@ while ( @ARGV ) {
# skip, it's been dealt with at the top of the file
shift @ARGV;
next;
+ } elsif($arg eq "-generator") {
+ $var = "makefile_generator";
+ $val = shift @ARGV;
} elsif($arg =~/^-/) {
print "Unknown option: $arg\n\n" if(!$var);
showUsage();
@@ -667,11 +692,13 @@ while ( @ARGV ) {
} elsif($showonly) {
$showonly--;
}
- } elsif ($var eq "quiet") {
+ } elsif ($var eq "verbose") {
if($val eq "yes") {
- $quiet++;
- } elsif($quiet) {
- $quiet--;
+ $verbose_level++;
+ } elsif($val eq "no" && $verbose_level) {
+ $verbose_level--;
+ } else {
+ $verbose_level = int($val);
}
} elsif ($var eq "check-includes") {
if($val eq "yes") {
@@ -698,7 +725,7 @@ while ( @ARGV ) {
$force_relative--;
}
} elsif ($var eq "module") {
- print "module :$val:\n" unless $quiet;
+ print "module :$val:\n" if($verbose_level);
die "No such module: $val" unless(defined $modules{$val});
push @modules_to_sync, $val;
} elsif ($var eq "separate-module") {
@@ -720,6 +747,8 @@ while ( @ARGV ) {
$cache_module_fwd = 1;
} elsif ($var eq "developer_build") {
$developer_build = 1;
+ } elsif ($var eq "makefile_generator") {
+ $makefile_generator = $val;
} elsif ($var eq "no_module_version_header") {
$no_module_version_header = 1;
} elsif ($var eq "output") {
@@ -766,9 +795,7 @@ loadSyncProfile(\$basedir, \$out_basedir);
$isunix = checkUnix; #cache checkUnix
# create path
-mkpath "$out_basedir/include", !$quiet;
-mkpath "$out_basedir/include/Qt", !$quiet;
-
+make_path("$out_basedir/include/Qt", "<outdir>", $verbose_level);
foreach my $lib (@modules_to_sync) {
#iteration info
@@ -796,7 +823,7 @@ foreach my $lib (@modules_to_sync) {
chomp $module_patch_version;
}
}
- print "WARNING: Module $lib\'s pri missing QT.<module>.VERSION variable! Private headers not versioned!\n" if (!$module_version);
+ print "$lib: WARNING: Module\'s pri missing QT.<module>.VERSION variable! Private headers not versioned!\n" if (!$module_version);
my $pathtoheaders = "";
$pathtoheaders = $moduleheaders{$lib} if ($moduleheaders{$lib});
@@ -870,6 +897,7 @@ foreach my $lib (@modules_to_sync) {
my $modulepri = $modulepris{$lib};
if (-e $modulepri) {
my $modulepriname = basename($modulepri);
+ # FIXME: this creates a file in the source location for shadow-builds
my $moduleversionheader = "$modules{$lib}/" . lc($lib) . "version.h";
my $modulehexstring = sprintf("0x%02X%02X%02X", int($module_major_version), int($module_minor_version), int($module_patch_version));
open MODULE_VERSION_HEADER_FILE, ">$moduleversionheader";
@@ -882,8 +910,11 @@ foreach my $lib (@modules_to_sync) {
print MODULE_VERSION_HEADER_FILE "#define " .uc($lib) . "_VERSION $modulehexstring\n", ;
print MODULE_VERSION_HEADER_FILE "\n";
print MODULE_VERSION_HEADER_FILE "#endif // QT_". uc($lib) . "_VERSION_H\n";
+ close MODULE_VERSION_HEADER_FILE;
+ $moduleversionheader = "<srcbase>" . substr($moduleversionheader, length($basedir)) if ($verbose_level < 2);
+ print "$lib: created version header $moduleversionheader\n" if($verbose_level);
} elsif ($modulepri) {
- print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating module version header for $lib.\n";
+ print "$lib: WARNING: Module\'s pri file '$modulepri' not found.\n$lib: Skipped creating module version header.\n";
}
}
@@ -913,6 +944,7 @@ foreach my $lib (@modules_to_sync) {
push @headers, "*".$if;
}
}
+ my $header_dirname = "";
foreach my $header (@headers) {
my $shadow = ($header =~ s/^\*//);
$header = 0 if($header =~ /^ui_.*.h/);
@@ -979,11 +1011,11 @@ foreach my $lib (@modules_to_sync) {
# class =~ s,::,/,g;
# }
$class_lib_map_contents .= "QT_CLASS_LIB($full_class, $lib, $header_base)\n";
- $header_copies++ if(syncHeader("$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts));
+ $header_copies++ if(syncHeader($lib, "$out_basedir/include/$lib/$class", "$out_basedir/include/$lib/$header", 0, $ts));
# KDE-Compat headers for Phonon
if ($lib eq "phonon") {
- $header_copies++ if (syncHeader("$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0, $ts));
+ $header_copies++ if (syncHeader($lib, "$out_basedir/include/phonon_compat/Phonon/$class", "$out_basedir/include/$lib/$header", 0, $ts));
}
}
} elsif ($create_private_headers) {
@@ -994,7 +1026,7 @@ foreach my $lib (@modules_to_sync) {
}
}
foreach(@headers) { #sync them
- $header_copies++ if(syncHeader($_, $iheader, $copy_headers && !$shadow, $ts));
+ $header_copies++ if(syncHeader($lib, $_, $iheader, $copy_headers && !$shadow, $ts));
}
if($public_header) {
@@ -1023,9 +1055,29 @@ foreach my $lib (@modules_to_sync) {
$pri_install_pfiles.= "$pri_install_iheader ";;
}
}
- print "header created for $iheader ($header_copies)\n" if($header_copies > 0 && !$quiet);
+
+ if ($verbose_level && $header_copies) {
+ my $new_header_dirname = dirname($iheader);
+ $new_header_dirname = "<srcbase>" . substr($new_header_dirname, length($basedir)) if ($new_header_dirname && $verbose_level < 2);
+ my $header_base = basename($iheader);
+ if ($verbose_level < 3) {
+ my $line_prefix = ",";
+ if ($new_header_dirname ne $header_dirname) {
+ $line_prefix = "$lib: created fwd-include header(s) for $new_header_dirname/ {";
+ $line_prefix = " }\n".$line_prefix if ($header_dirname);
+ $header_dirname = $new_header_dirname;
+ } else {
+ $line_prefix = ",";
+ }
+ print "$line_prefix $header_base ($header_copies)";
+ } else { # $verbose_level >= 3
+ $iheader = "<srcbase>" . substr($iheader, length($basedir)) if ($verbose_level == 3);
+ print "$lib: created $header_copies fwd-include headers for $iheader\n";
+ }
+ }
}
}
+ print " }\n" if ($header_dirname && $verbose_level > 0 && $verbose_level < 3);
}
}
@@ -1051,11 +1103,11 @@ foreach my $lib (@modules_to_sync) {
}
if($master_include && $master_contents) {
my $master_dir = dirname($master_include);
- mkpath $master_dir, !$quiet;
- print "header (master) created for $lib\n" unless $quiet;
+ make_path($master_dir, $lib, $verbose_level);
open MASTERINCLUDE, ">$master_include";
print MASTERINCLUDE $master_contents;
close MASTERINCLUDE;
+ print "$lib: created header (master) file\n" if($verbose_level);
}
}
@@ -1076,11 +1128,11 @@ foreach my $lib (@modules_to_sync) {
}
if($headers_pri_file && $master_contents) {
my $headers_pri_dir = dirname($headers_pri_file);
- mkpath $headers_pri_dir, !$quiet;
- print "headers.pri file created for $lib\n" unless $quiet;
+ make_path($headers_pri_dir, $lib, $verbose_level);
open HEADERS_PRI_FILE, ">$headers_pri_file";
print HEADERS_PRI_FILE $headers_pri_contents;
close HEADERS_PRI_FILE;
+ print "$lib: created headers.pri file\n" if($verbose_level);
}
# create forwarding module pri in qtbase/mkspecs/modules
@@ -1088,7 +1140,7 @@ foreach my $lib (@modules_to_sync) {
my $modulepri = $modulepris{$lib};
if (-e $modulepri) {
my $modulepriname = basename($modulepri);
- mkpath($module_fwd);
+ make_path($module_fwd, $lib, $verbose_level);
my $moduleprifwd = "$module_fwd/$modulepriname";
my $mod_base = $developer_build ? $basedir : $out_basedir;
my $mod_component_base = $developer_build ? $qtbasedir : $out_basedir;
@@ -1114,7 +1166,7 @@ foreach my $lib (@modules_to_sync) {
}
}
} elsif ($modulepri) {
- print "WARNING: Module $lib\'s pri file '$modulepri' not found.\nSkipped creating forwarding pri for $lib.\n";
+ print "$lib: WARNING: Module\'s pri file '$modulepri' not found.\n$lib: Skipped creating forwarding pri.\n";
}
}
}
@@ -1132,7 +1184,7 @@ unless($showonly || !$create_uic_class_map) {
}
if($class_lib_map) {
my $class_lib_map_dir = dirname($class_lib_map);
- mkpath $class_lib_map_dir, !$quiet;
+ make_path($class_lib_map_dir, "<outdir>", $verbose_level);
open CLASS_LIB_MAP, ">$class_lib_map";
print CLASS_LIB_MAP $class_lib_map_contents;
close CLASS_LIB_MAP;
@@ -1216,7 +1268,7 @@ if($check_includes) {
if($include) {
for my $trylib (keys(%modules)) {
if(-e "$out_basedir/include/$trylib/$include") {
- print "WARNING: $iheader includes $include when it should include $trylib/$include\n";
+ print "$lib: WARNING: $iheader includes $include when it should include $trylib/$include\n";
}
}
}
@@ -1234,27 +1286,27 @@ if($check_includes) {
}
if ($header_skip_qt_begin_header_test == 0) {
if ($qt_begin_header_found == 0) {
- print "WARNING: $iheader does not include QT_BEGIN_HEADER\n";
+ print "$lib: WARNING: $iheader does not include QT_BEGIN_HEADER\n";
}
if ($qt_begin_header_found && $qt_end_header_found == 0) {
- print "WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n";
+ print "$lib: WARNING: $iheader has QT_BEGIN_HEADER but no QT_END_HEADER\n";
}
}
if ($header_skip_qt_begin_namespace_test == 0) {
if ($qt_begin_namespace_found == 0) {
- print "WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n";
+ print "$lib: WARNING: $iheader does not include QT_BEGIN_NAMESPACE\n";
}
if ($qt_begin_namespace_found && $qt_end_namespace_found == 0) {
- print "WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n";
+ print "$lib: WARNING: $iheader has QT_BEGIN_NAMESPACE but no QT_END_NAMESPACE\n";
}
}
if ($header_skip_qt_module_test == 0) {
if ($qt_module_found == 0) {
- print "WARNING: $iheader does not include QT_MODULE\n";
+ print "$lib: WARNING: $iheader does not include QT_MODULE\n";
}
}
close(F);
@@ -1266,4 +1318,21 @@ if($check_includes) {
}
}
+# Do configure tests now (pass some things along)
+# fatal tests have a non zero return
+# If the generator is not set (e.g. someone invoking syncqt as part of configure etc, then don't run tests either)
+unless ($showonly || $makefile_generator eq '') {
+ my $configtests = dirname($0)."/qtmodule-configtests";
+ if (! -f $configtests) {
+ $configtests = $qtbasedir."/bin/qtmodule-configtests";
+ }
+ if (! -f $configtests) {
+ warn "Unable to locate qtmodule-configtests script - config tests disabled.\n";
+ } else {
+ if (system($EXECUTABLE_NAME, $configtests, $basedir, $out_basedir, $qtbasedir, $makefile_generator)) {
+ die "$configtests exited with status $?";
+ }
+ }
+}
+
exit 0;
diff --git a/configure b/configure
index a3349d468c..be744d3990 100755
--- a/configure
+++ b/configure
@@ -2577,7 +2577,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then
chmod 755 "$outpath/bin/syncqt"
fi
- for i in elf2e32_qtwrapper createpackage patch_capabilities; do
+ for i in elf2e32_qtwrapper createpackage patch_capabilities qtmodule-configtests; do
rm -f "$outpath/bin/$i"
if [ -x "$relpath/bin/$i" ]; then
mkdir -p "$outpath/bin"
@@ -2970,7 +2970,7 @@ if [ '!' -f "${XQMAKESPEC}/qplatformdefs.h" ]; then
echo
echo " $XQMAKESPEC/qplatformdefs.h"
echo
- echo " Please contact qt-bugs@trolltech.com."
+ echo " Please contact qt-info@nokia.com."
echo
exit 2
fi
@@ -6911,7 +6911,7 @@ fi
# For "-carbon" builds: 32 bit x86/ppc.
# For builds on snow leopard : compiler default (64-bit).
# For builds on leopard : compiler default (32-bit).
-if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_ARCHS" = "" ]; then
+if [ "$CFG_ARCH" = "macosx" ] && [ "$CFG_MAC_ARCHS" = "" ]; then
source "$mactests/defaultarch.test" "$TEST_COMPILER" "$OPT_VERBOSE" "$mactests"
if [ "$CFG_MAC_CARBON" = "yes" ]; then
@@ -7150,7 +7150,7 @@ fi
[ "$CFG_AVX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx"
[ "$CFG_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt"
[ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon"
-[ "$PLATFORM_MAC" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG $CFG_MAC_ARCHS"
+[ "$CFG_ARCH" = "macosx" ] && QMAKE_CONFIG="$QMAKE_CONFIG $CFG_MAC_ARCHS"
if [ "$CFG_CLOCK_GETTIME" = "yes" ]; then
QT_CONFIG="$QT_CONFIG clock-gettime"
fi
@@ -8617,7 +8617,7 @@ else
echo "Building for: $XPLATFORM"
fi
-if [ "$PLATFORM_MAC" = "yes" ]; then
+if [ ! -z "$CFG_MAC_ARCHS" ]; then
echo "Architecture: $CFG_ARCH ($CFG_MAC_ARCHS )"
else
echo "Architecture: $CFG_ARCH"
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index 344edb6517..523d649573 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -17,6 +17,9 @@ information about a particular change.
- Unite clipping support has been removed from QPainter. The alternative is
to unite QRegion's and using the result on QPainter.
+- QLibrary::resolve() now returns a function pointer instead of a void
+ pointer.
+
****************************************************************************
* General *
****************************************************************************
diff --git a/doc/src/examples/padnavigator.qdoc b/doc/src/examples/padnavigator.qdoc
index 0942c82215..591d3d0e63 100644
--- a/doc/src/examples/padnavigator.qdoc
+++ b/doc/src/examples/padnavigator.qdoc
@@ -316,7 +316,7 @@
Now we construct the \c FlippablePad item, passing its column-row count to
its constructor.
- The pad is constrolled by three transformations, and we create one
+ The pad is controlled by three transformations, and we create one
QGraphicsRotation object for each of these.
\list
diff --git a/examples/tools/settingseditor/locationdialog.cpp b/examples/tools/settingseditor/locationdialog.cpp
index de7e5bcada..dcf190363a 100644
--- a/examples/tools/settingseditor/locationdialog.cpp
+++ b/examples/tools/settingseditor/locationdialog.cpp
@@ -54,7 +54,7 @@ LocationDialog::LocationDialog(QWidget *parent)
scopeComboBox->addItem(tr("System"));
organizationComboBox = new QComboBox;
- organizationComboBox->addItem(tr("Trolltech"));
+ organizationComboBox->addItem(tr("Qt"));
organizationComboBox->setEditable(true);
applicationComboBox = new QComboBox;
diff --git a/examples/tutorials/addressbook-fr/README b/examples/tutorials/addressbook-fr/README
index 359859390e..5f82d3ce38 100644
--- a/examples/tutorials/addressbook-fr/README
+++ b/examples/tutorials/addressbook-fr/README
@@ -39,4 +39,4 @@ qmake -spec macx-xcode
Then open the generated Xcode project in Xcode and build it.
-Feel free to send comments about the tutorial to qt-bugs@trolltech.com.
+Feel free to send comments about the tutorial to qt-info@nokia.com.
diff --git a/examples/tutorials/addressbook/README b/examples/tutorials/addressbook/README
index 20ae7f3ada..5f364d909c 100644
--- a/examples/tutorials/addressbook/README
+++ b/examples/tutorials/addressbook/README
@@ -39,4 +39,4 @@ qmake -spec macx-xcode
Then open the generated Xcode project in Xcode and build it.
-Feel free to send comments about the tutorial to qt-bugs@trolltech.com.
+Feel free to send comments about the tutorial to qt-info@nokia.com.
diff --git a/mkspecs/features/declarative_debug.prf b/mkspecs/features/declarative_debug.prf
new file mode 100644
index 0000000000..b0248f0ac3
--- /dev/null
+++ b/mkspecs/features/declarative_debug.prf
@@ -0,0 +1 @@
+contains(QT, declarative):DEFINES += QT_DECLARATIVE_DEBUG
diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf
index ebb94e272e..35a4d3f4a4 100644
--- a/mkspecs/features/default_pre.prf
+++ b/mkspecs/features/default_pre.prf
@@ -2,7 +2,7 @@ load(exclusive_builds)
### Qt 5: remove "uic" and "resources" - or add "qt"
CONFIG = lex yacc warn_on debug uic resources $$CONFIG
-exists($$_PRO_FILE_PWD_/sync.profile) {
+!build_pass:exists($$_PRO_FILE_PWD_/sync.profile) {
PRO_BASENAME = $$basename(_PRO_FILE_)
# Try to detect proper QTDIR path. We require QTDIR, as syncqt uses that to create qt_module.pri
@@ -31,7 +31,7 @@ exists($$_PRO_FILE_PWD_/sync.profile) {
qtPrepareTool(QMAKE_SYNCQT, syncqt)
- MSG = $$quote($$QMAKE_SYNCQT $$QTFWD -outdir $$OUT_PWD $$_PRO_FILE_PWD_)
+ MSG = $$quote($$QMAKE_SYNCQT $$QTFWD -generator $$MAKEFILE_GENERATOR -outdir $$OUT_PWD $$_PRO_FILE_PWD_)
!silent:message($$MSG)
system($$MSG) {
# success! Nothing to do
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 86d80cb239..13dadeb1e9 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -140,7 +140,7 @@ defineTest(qtAddModule) {
}
isEmpty(LINKAGE) {
# Make sure we can link to uninstalled libraries
- !isEqual(MODULE_LIBS, $[QT_INSTALL_LIBS]) {
+ !isEqual(MODULE_LIBS, $$[QT_INSTALL_LIBS]) {
QMAKE_LIBDIR *= $$MODULE_LIBS
unix:!mac:QMAKE_LFLAGS *= "-Wl,-rpath-link,$$MODULE_LIBS"
}
diff --git a/mkspecs/features/qt_module_config.prf b/mkspecs/features/qt_module_config.prf
index 8f225fe6ed..7b5b5ad304 100644
--- a/mkspecs/features/qt_module_config.prf
+++ b/mkspecs/features/qt_module_config.prf
@@ -186,6 +186,9 @@ DEFINES *= QT_USE_QSTRINGBUILDER
TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end
+qtPrepareTool(QMAKE_MOC, moc)
+qtPrepareTool(QMAKE_UIC, uic)
+qtPrepareTool(QMAKE_RCC, rcc)
qtPrepareTool(QMAKE_LUPDATE, lupdate)
qtPrepareTool(QMAKE_LRELEASE, lrelease)
diff --git a/qmake/project.cpp b/qmake/project.cpp
index cb4117bef4..bbfd9005c6 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -1382,16 +1382,15 @@ QMakeProject::read(uchar cmd)
read(Option::mkfile::cachefile, base_vars);
}
}
-
- if(cmd & ReadFeatures) {
- debug_msg(1, "Processing default_pre: %s", vars["CONFIG"].join("::").toLatin1().constData());
- if(doProjectInclude("default_pre", IncludeFlagFeature, base_vars) == IncludeNoExist)
- doProjectInclude("default", IncludeFlagFeature, base_vars);
- }
}
vars = base_vars; // start with the base
+ if(cmd & ReadFeatures) {
+ debug_msg(1, "Processing default_pre: %s", vars["CONFIG"].join("::").toLatin1().constData());
+ doProjectInclude("default_pre", IncludeFlagFeature, vars);
+ }
+
//get a default
if(pfile != "-" && vars["TARGET"].isEmpty())
vars["TARGET"].append(QFileInfo(pfile).baseName());
diff --git a/qtbase.pro b/qtbase.pro
index ecbb183471..c28bc9382b 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -135,6 +135,11 @@ syncqt.files=$$QT_BUILD_TREE/bin/syncqt
win32:syncqt.files=$$QT_BUILD_TREE/bin/syncqt.bat
INSTALLS += syncqt
+#qtmodule-configtests
+configtests.path=$$[QT_INSTALL_BINS]
+configtests.files=$$QT_BUILD_TREE/bin/qtmodule-configtests
+INSTALLS += configtests
+
#mkspecs
mkspecs.path=$$[QT_INSTALL_DATA]/mkspecs
mkspecs.files=$$QT_BUILD_TREE/mkspecs/qconfig.pri $$files($$QT_SOURCE_TREE/mkspecs/*)
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-external.h b/src/3rdparty/harfbuzz/src/harfbuzz-external.h
index 5fff35fe50..1f7ae1c902 100644
--- a/src/3rdparty/harfbuzz/src/harfbuzz-external.h
+++ b/src/3rdparty/harfbuzz/src/harfbuzz-external.h
@@ -144,7 +144,7 @@ HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch);
int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch);
HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch);
-void *HB_Library_Resolve(const char *library, int version, const char *symbol);
+void (*HB_Library_Resolve(const char *library, int version, const char *symbol))();
HB_END_HEADER
diff --git a/src/3rdparty/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp b/src/3rdparty/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp
index f0048b75ef..2c261639ad 100644
--- a/src/3rdparty/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp
+++ b/src/3rdparty/harfbuzz/tests/linebreaking/harfbuzz-qt.cpp
@@ -79,7 +79,7 @@ void HB_GetGraphemeAndLineBreakClass(HB_UChar32 ch, HB_GraphemeClass *grapheme,
*lineBreak = (HB_LineBreakClass) prop->line_break_class;
}
-void *HB_Library_Resolve(const char *library, int version, const char *symbol)
+void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
{
return QLibrary::resolve(library, version, symbol);
}
diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h
index ecce758e71..74dc6cfbb2 100644
--- a/src/corelib/arch/qatomic_bootstrap.h
+++ b/src/corelib/arch/qatomic_bootstrap.h
@@ -75,13 +75,34 @@ inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
return testAndSetOrdered(expectedValue, newValue);
}
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
{
int returnValue = _q_value;
_q_value += valueToAdd;
return returnValue;
}
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+
template <typename T>
Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
{
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index a59cbf9382..452679c7d7 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -718,6 +718,13 @@ QT_BEGIN_NAMESPACE
\sa QtMsgHandler, qInstallMsgHandler()
*/
+/*! \typedef QFunctionPointer
+ \relates <QtGlobal>
+
+ This is a typedef for \c{void (*)()}, a pointer to a function that takes
+ no arguments and returns void.
+*/
+
/*! \macro qint64 Q_INT64_C(literal)
\relates <QtGlobal>
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index e4084ed91f..2f6f33efca 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -281,7 +281,7 @@ namespace QT_NAMESPACE {}
# define Q_OS_VXWORKS
#elif defined(__MAKEDEPEND__)
#else
-# error "Qt has not been ported to this OS - talk to qt-bugs@trolltech.com"
+# error "Qt has not been ported to this OS - talk to qt-info@nokia.com"
#endif
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINCE)
@@ -794,7 +794,7 @@ namespace QT_NAMESPACE {}
# define Q_CC_NOKIAX86
#else
-# error "Qt has not been tested with this compiler - talk to qt-bugs@trolltech.com"
+# error "Qt has not been tested with this compiler - talk to qt-info@nokia.com"
#endif
@@ -1807,6 +1807,8 @@ Q_CORE_EXPORT void qt_message_output(QtMsgType, const char *buf);
typedef void (*QtMsgHandler)(QtMsgType, const char *);
Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
+typedef void (*QFunctionPointer)();
+
#if !defined(Q_UNIMPLEMENTED)
# define Q_UNIMPLEMENTED() qWarning("%s:%d: %s: Unimplemented code.", __FILE__, __LINE__, Q_FUNC_INFO)
#endif
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 5c5223eb1c..ef302243da 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -131,7 +131,7 @@
# define __NR_inotify_rm_watch 286
# define __NR_inotify_init1 328
#else
-# error "This architecture is not supported. Please talk to qt-bugs@trolltech.com"
+# error "This architecture is not supported. Please talk to qt-info@nokia.com"
#endif
#if !defined(IN_CLOEXEC) && defined(O_CLOEXEC) && defined(__NR_inotify_init1)
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 1b0707605c..10de2caf62 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -45,109 +45,10 @@
#include "qthread.h"
#include <private/qthread_p.h>
#include <private/qcoreapplication_p.h>
+#include <private/qfreelist_p.h>
QT_BEGIN_NAMESPACE
-// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
-static const int TimerIdMask = 0x00ffffff;
-static const int TimerSerialMask = ~TimerIdMask & ~0x80000000;
-static const int TimerSerialCounter = TimerIdMask + 1;
-static const int MaxTimerId = TimerIdMask;
-
-static int FirstBucket[] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
-};
-
-enum {
- FirstBucketOffset = 0,
- SecondBucketOffset = sizeof(FirstBucket) / sizeof(FirstBucket[0]),
- ThirdBucketOffset = 0x100,
- FourthBucketOffset = 0x1000,
- FifthBucketOffset = 0x10000,
- SixthBucketOffset = 0x100000
-};
-
-enum {
- FirstBucketSize = SecondBucketOffset,
- SecondBucketSize = ThirdBucketOffset - SecondBucketOffset,
- ThirdBucketSize = FourthBucketOffset - ThirdBucketOffset,
- FourthBucketSize = FifthBucketOffset - FourthBucketOffset,
- FifthBucketSize = SixthBucketOffset - FifthBucketOffset,
- SixthBucketSize = MaxTimerId - SixthBucketOffset
-};
-
-static const int BucketSize[] = {
- FirstBucketSize, SecondBucketSize, ThirdBucketSize,
- FourthBucketSize, FifthBucketSize, SixthBucketSize
-};
-enum { NumberOfBuckets = sizeof(BucketSize) / sizeof(BucketSize[0]) };
-
-static const int BucketOffset[] = {
- FirstBucketOffset, SecondBucketOffset, ThirdBucketOffset,
- FourthBucketOffset, FifthBucketOffset, SixthBucketOffset
-};
-
-static QBasicAtomicPointer<int> timerIds[] =
- { Q_BASIC_ATOMIC_INITIALIZER(FirstBucket),
- Q_BASIC_ATOMIC_INITIALIZER(0),
- Q_BASIC_ATOMIC_INITIALIZER(0),
- Q_BASIC_ATOMIC_INITIALIZER(0),
- Q_BASIC_ATOMIC_INITIALIZER(0),
- Q_BASIC_ATOMIC_INITIALIZER(0) };
-
-static void timerIdsDestructorFunction()
-{
- // start at one, the first bucket is pre-allocated
- for (int i = 1; i < NumberOfBuckets; ++i)
- delete [] static_cast<int *>(timerIds[i]);
-}
-Q_DESTRUCTOR_FUNCTION(timerIdsDestructorFunction)
-
-static QBasicAtomicInt nextFreeTimerId = Q_BASIC_ATOMIC_INITIALIZER(1);
-
-// avoid the ABA-problem by using 7 of the top 8 bits of the timerId as a serial number
-static inline int prepareNewValueWithSerialNumber(int oldId, int newId)
-{
- return (newId & TimerIdMask) | ((oldId + TimerSerialCounter) & TimerSerialMask);
-}
-
-namespace {
- template<bool> struct QStaticAssertType;
- template<> struct QStaticAssertType<true> { enum { Value = 1 }; };
-}
-#define q_static_assert(expr) (void)QStaticAssertType<expr>::Value
-
-static inline int bucketOffset(int timerId)
-{
- q_static_assert(sizeof BucketSize == sizeof BucketOffset);
- q_static_assert(sizeof(timerIds) / sizeof(timerIds[0]) == NumberOfBuckets);
-
- for (int i = 0; i < NumberOfBuckets; ++i) {
- if (timerId < BucketSize[i])
- return i;
- timerId -= BucketSize[i];
- }
- qFatal("QAbstractEventDispatcher: INTERNAL ERROR, timer ID %d is too large", timerId);
- return -1;
-}
-
-static inline int bucketIndex(int bucket, int timerId)
-{
- return timerId - BucketOffset[bucket];
-}
-
-static inline int *allocateBucket(int bucket)
-{
- // allocate a new bucket
- const int size = BucketSize[bucket];
- const int offset = BucketOffset[bucket];
- int *b = new int[size];
- for (int i = 0; i != size; ++i)
- b[i] = offset + i + 1;
- return b;
-}
-
void QAbstractEventDispatcherPrivate::init()
{
Q_Q(QAbstractEventDispatcher);
@@ -158,79 +59,54 @@ void QAbstractEventDispatcherPrivate::init()
}
}
-// Timer IDs are implemented using a free-list;
-// there's a vector initialized with:
-// X[i] = i + 1
-// and nextFreeTimerId starts with 1.
-//
-// Allocating a timer ID involves taking the ID from
-// X[nextFreeTimerId]
-// updating nextFreeTimerId to this value and returning the old value
-//
-// When the timer ID is allocated, its cell in the vector is unused (it's a
-// free list). As an added protection, we use the cell to store an invalid
-// (negative) value that we can later check for integrity.
-//
-// (continues below).
+// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
+struct QtTimerIdFreeListConstants : public QFreeListDefaultConstants
+{
+ enum
+ {
+ InitialNextValue = 1,
+ BlockCount = 6,
+ };
+
+ static const int Sizes[BlockCount];
+};
+
+enum {
+ Offset0 = 0x00000000,
+ Offset1 = 0x00000040,
+ Offset2 = 0x00000100,
+ Offset3 = 0x00001000,
+ Offset4 = 0x00010000,
+ Offset5 = 0x00100000,
+
+ Size0 = Offset1 - Offset0,
+ Size1 = Offset2 - Offset1,
+ Size2 = Offset3 - Offset2,
+ Size3 = Offset4 - Offset3,
+ Size4 = Offset5 - Offset4,
+ Size5 = QtTimerIdFreeListConstants::MaxIndex - Offset5
+};
+
+const int QtTimerIdFreeListConstants::Sizes[QtTimerIdFreeListConstants::BlockCount] = {
+ Size0,
+ Size1,
+ Size2,
+ Size3,
+ Size4,
+ Size5
+};
+
+typedef QFreeList<void, QtTimerIdFreeListConstants> QtTimerIdFreeList;
+Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList)
+
int QAbstractEventDispatcherPrivate::allocateTimerId()
{
- int timerId, newTimerId;
- int at, *b;
- do {
- timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics
-
- // which bucket are we looking in?
- int which = timerId & TimerIdMask;
- int bucket = bucketOffset(which);
- at = bucketIndex(bucket, which);
- b = timerIds[bucket];
-
- if (!b) {
- // allocate a new bucket
- b = allocateBucket(bucket);
- if (!timerIds[bucket].testAndSetRelease(0, b)) {
- // another thread won the race to allocate the bucket
- delete [] b;
- b = timerIds[bucket];
- }
- }
-
- newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]);
- } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId));
-
- b[at] = -timerId;
-
- return timerId;
+ return timerIdFreeList()->next();
}
-// Releasing a timer ID requires putting the current ID back in the vector;
-// we do it by setting:
-// X[timerId] = nextFreeTimerId;
-// then we update nextFreeTimerId to the timer we've just released
-//
-// The extra code in allocateTimerId and releaseTimerId are ABA prevention
-// and bucket memory. The buckets are simply to make sure we allocate only
-// the necessary number of timers. See above.
-//
-// ABA prevention simply adds a value to 7 of the top 8 bits when resetting
-// nextFreeTimerId.
void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
{
- int which = timerId & TimerIdMask;
- int bucket = bucketOffset(which);
- int at = bucketIndex(bucket, which);
- int *b = timerIds[bucket];
-
- Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId",
- "Internal error: timer ID not found");
-
- int freeId, newTimerId;
- do {
- freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics
- b[at] = freeId & TimerIdMask;
-
- newTimerId = prepareNewValueWithSerialNumber(freeId, timerId);
- } while (!nextFreeTimerId.testAndSetRelease(freeId, newTimerId));
+ timerIdFreeList()->release(timerId);
}
/*!
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index c8ac15c1fa..b6de002cf4 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -859,20 +859,31 @@ QMetaProperty QMetaObject::property(int index) const
if (flags & EnumOrFlag) {
result.menum = enumerator(indexOfEnumerator(type));
if (!result.menum.isValid()) {
- QByteArray enum_name = type;
- QByteArray scope_name = d.stringdata;
- int s = enum_name.lastIndexOf("::");
- if (s > 0) {
- scope_name = enum_name.left(s);
- enum_name = enum_name.mid(s + 2);
+ const char *enum_name = type;
+ const char *scope_name = d.stringdata;
+ char *scope_buffer = 0;
+
+ const char *colon = strrchr(enum_name, ':');
+ // ':' will always appear in pairs
+ Q_ASSERT(colon <= enum_name || *(colon-1) == ':');
+ if (colon > enum_name) {
+ int len = colon-enum_name-1;
+ scope_buffer = (char *)qMalloc(len+1);
+ qMemCopy(scope_buffer, enum_name, len);
+ scope_buffer[len] = '\0';
+ scope_name = scope_buffer;
+ enum_name = colon+1;
}
+
const QMetaObject *scope = 0;
- if (scope_name == "Qt")
+ if (qstrcmp(scope_name, "Qt") == 0)
scope = &QObject::staticQtMetaObject;
else
scope = QMetaObject_findMetaObject(this, scope_name);
if (scope)
result.menum = scope->enumerator(scope->indexOfEnumerator(enum_name));
+ if (scope_buffer)
+ qFree(scope_buffer);
}
}
}
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 63605ecadb..5da936aab0 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -101,7 +101,8 @@ enum MethodFlags {
};
enum MetaObjectFlags {
- DynamicMetaObject = 0x01
+ DynamicMetaObject = 0x01,
+ RequiresVariantMetaObject = 0x02
};
class QMutex;
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index a282ae007c..7652ec4871 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -60,7 +60,6 @@
#include <qsharedpointer.h>
#include <private/qorderedmutexlocker_p.h>
-#include <private/qmutexpool_p.h>
#include <new>
@@ -95,35 +94,22 @@ static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
return types;
}
-static QBasicAtomicPointer<QMutexPool> signalSlotMutexes = Q_BASIC_ATOMIC_INITIALIZER(0);
-static QBasicAtomicInt objectCount = Q_BASIC_ATOMIC_INITIALIZER(0);
+static QBasicMutex _q_ObjectMutexPool[131];
/** \internal
* mutex to be locked when accessing the connectionlists or the senders list
*/
static inline QMutex *signalSlotLock(const QObject *o)
{
- if (!signalSlotMutexes) {
- QMutexPool *mp = new QMutexPool;
- if (!signalSlotMutexes.testAndSetOrdered(0, mp)) {
- delete mp;
- }
- }
- return signalSlotMutexes->get(o);
+ return static_cast<QMutex *>(&_q_ObjectMutexPool[
+ uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]);
}
extern "C" Q_CORE_EXPORT void qt_addObject(QObject *)
-{
- objectCount.ref();
-}
+{}
extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
-{
- if(!objectCount.deref()) {
- QMutexPool *old = signalSlotMutexes.fetchAndStoreAcquire(0);
- delete old;
- }
-}
+{}
struct QConnectionSenderSwitcher {
QObject *receiver;
@@ -879,7 +865,7 @@ QObject::~QObject()
if (c->next) c->next->prev = c->prev;
}
if (needToUnlock)
- m->unlockInline();
+ m->unlock();
connectionList.first = c->nextConnectionList;
delete c;
@@ -903,7 +889,7 @@ QObject::~QObject()
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
//the node has maybe been removed while the mutex was unlocked in relock?
if (!node || node->sender != sender) {
- m->unlockInline();
+ m->unlock();
continue;
}
node->receiver = 0;
@@ -913,7 +899,7 @@ QObject::~QObject()
node = node->next;
if (needToUnlock)
- m->unlockInline();
+ m->unlock();
}
}
@@ -3077,7 +3063,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
}
if (needToUnlock)
- receiverMutex->unlockInline();
+ receiverMutex->unlock();
c->receiver = 0;
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 314ccd7861..45515f32e1 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -447,7 +447,7 @@ QLibraryPrivate::~QLibraryPrivate()
}
}
-void *QLibraryPrivate::resolve(const char *symbol)
+QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
{
if (!pHnd)
return 0;
@@ -1129,7 +1129,7 @@ void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &ver
Note: In Symbian resolving with symbol names works only if the loaded
library was built as STDDLL. Otherwise, the ordinals must be used.
*/
-void *QLibrary::resolve(const char *symbol)
+QFunctionPointer QLibrary::resolve(const char *symbol)
{
if (!isLoaded() && !load())
return 0;
@@ -1152,7 +1152,7 @@ void *QLibrary::resolve(const char *symbol)
\sa resolve()
*/
-void *QLibrary::resolve(const QString &fileName, const char *symbol)
+QFunctionPointer QLibrary::resolve(const QString &fileName, const char *symbol)
{
QLibrary library(fileName);
return library.resolve(symbol);
@@ -1175,7 +1175,7 @@ void *QLibrary::resolve(const QString &fileName, const char *symbol)
\sa resolve()
*/
-void *QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
+QFunctionPointer QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
{
QLibrary library(fileName, verNum);
return library.resolve(symbol);
@@ -1199,7 +1199,7 @@ void *QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
\sa resolve()
*/
-void *QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol)
+QFunctionPointer QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol)
{
QLibrary library(fileName, version);
return library.resolve(symbol);
diff --git a/src/corelib/plugin/qlibrary.h b/src/corelib/plugin/qlibrary.h
index 0154e949b3..e3f557dd7d 100644
--- a/src/corelib/plugin/qlibrary.h
+++ b/src/corelib/plugin/qlibrary.h
@@ -79,10 +79,10 @@ public:
explicit QLibrary(const QString& fileName, const QString &version, QObject *parent = 0);
~QLibrary();
- void *resolve(const char *symbol);
- static void *resolve(const QString &fileName, const char *symbol);
- static void *resolve(const QString &fileName, int verNum, const char *symbol);
- static void *resolve(const QString &fileName, const QString &version, const char *symbol);
+ QFunctionPointer resolve(const char *symbol);
+ static QFunctionPointer resolve(const QString &fileName, const char *symbol);
+ static QFunctionPointer resolve(const QString &fileName, int verNum, const char *symbol);
+ static QFunctionPointer resolve(const QString &fileName, const QString &version, const char *symbol);
bool load();
bool unload();
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index 4f66bc26a0..c6804955d9 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -87,7 +87,7 @@ public:
bool loadPlugin(); // loads and resolves instance
bool unload();
void release();
- void *resolve(const char *);
+ QFunctionPointer resolve(const char *);
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString());
@@ -108,7 +108,7 @@ private:
bool load_sys();
bool unload_sys();
- void *resolve_sys(const char *);
+ QFunctionPointer resolve_sys(const char *);
QAtomicInt libraryRefCount;
QAtomicInt libraryUnloadCount;
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 0a7e841519..d3b08e1acf 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -267,29 +267,29 @@ bool QLibraryPrivate::unload_sys()
}
#ifdef Q_OS_MAC
-Q_CORE_EXPORT void *qt_mac_resolve_sys(void *handle, const char *symbol)
+Q_CORE_EXPORT QFunctionPointer qt_mac_resolve_sys(void *handle, const char *symbol)
{
- return dlsym(handle, symbol);
+ return QFunctionPointer(dlsym(handle, symbol));
}
#endif
-void* QLibraryPrivate::resolve_sys(const char* symbol)
+QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
{
#if defined(QT_AOUT_UNDERSCORE)
// older a.out systems add an underscore in front of symbols
char* undrscr_symbol = new char[strlen(symbol)+2];
undrscr_symbol[0] = '_';
strcpy(undrscr_symbol+1, symbol);
- void* address = dlsym(pHnd, undrscr_symbol);
+ QFunctionPointer address = QFunctionPointer(dlsym(pHnd, undrscr_symbol));
delete [] undrscr_symbol;
#elif defined(QT_HPUX_LD)
- void* address = 0;
+ QFunctionPointer address = 0;
if (shl_findsym((shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address) < 0)
address = 0;
#elif defined (QT_NO_DYNAMIC_LIBRARY)
- void *address = 0;
+ QFunctionPointer address = 0;
#else
- void* address = dlsym(pHnd, symbol);
+ QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol));
#endif
if (!address) {
errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg(
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 667d9cca45..4eeb2fc441 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -113,12 +113,12 @@ bool QLibraryPrivate::unload_sys()
return true;
}
-void* QLibraryPrivate::resolve_sys(const char* symbol)
+QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
{
#ifdef Q_OS_WINCE
- void* address = (void*)GetProcAddress(pHnd, (const wchar_t*)QString::fromLatin1(symbol).utf16());
+ FARPROC address = GetProcAddress(pHnd, (const wchar_t*)QString::fromLatin1(symbol).utf16());
#else
- void* address = (void*)GetProcAddress(pHnd, symbol);
+ FARPROC address = GetProcAddress(pHnd, symbol);
#endif
if (!address) {
errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg(
@@ -126,6 +126,6 @@ void* QLibraryPrivate::resolve_sys(const char* symbol)
} else {
errorString.clear();
}
- return address;
+ return QFunctionPointer(address);
}
QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qsystemlibrary_p.h b/src/corelib/plugin/qsystemlibrary_p.h
index f20d0b6b9d..3298f05b8f 100644
--- a/src/corelib/plugin/qsystemlibrary_p.h
+++ b/src/corelib/plugin/qsystemlibrary_p.h
@@ -78,20 +78,20 @@ public:
return (m_handle != 0);
}
- void *resolve(const char *symbol)
+ QFunctionPointer resolve(const char *symbol)
{
if (!m_didLoad)
load();
if (!m_handle)
return 0;
#ifdef Q_OS_WINCE
- return (void*)GetProcAddress(m_handle, (const wchar_t*)QString::fromLatin1(symbol).utf16());
+ return QFunctionPointer(GetProcAddress(m_handle, (const wchar_t*)QString::fromLatin1(symbol).utf16()));
#else
- return (void*)GetProcAddress(m_handle, symbol);
+ return QFunctionPointer(GetProcAddress(m_handle, symbol));
#endif
}
- static void *resolve(const QString &libraryName, const char *symbol)
+ static QFunctionPointer resolve(const QString &libraryName, const char *symbol)
{
return QSystemLibrary(libraryName).resolve(symbol);
}
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 3e3bf8ff13..c90b44be6c 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -49,9 +49,26 @@
#include "qthread.h"
#include "qmutex_p.h"
+#ifndef Q_OS_LINUX
+#include "private/qfreelist_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
/*!
+ \class QBasicMutex
+ \brief QMutex POD
+ \internal
+
+ \ingroup thread
+
+ - Can be used as global static object.
+ - Always non-recursive
+ - Do not use tryLock with timeout > 0, else you can have a leak (see the ~QMutex destructor)
+*/
+
+
+/*!
\class QMutex
\brief The QMutex class provides access serialization between threads.
@@ -122,8 +139,12 @@ QT_BEGIN_NAMESPACE
\sa lock(), unlock()
*/
QMutex::QMutex(RecursionMode mode)
- : d(new QMutexPrivate(mode))
-{ }
+{
+ if (mode == Recursive)
+ d = new QRecursiveMutexPrivate;
+ else
+ d = 0;
+}
/*!
Destroys the mutex.
@@ -131,9 +152,18 @@ QMutex::QMutex(RecursionMode mode)
\warning Destroying a locked mutex may result in undefined behavior.
*/
QMutex::~QMutex()
-{ delete static_cast<QMutexPrivate *>(d); }
+{
+ if (isRecursive())
+ delete static_cast<QRecursiveMutexPrivate *>(d._q_value);
+ else if (d) {
+#ifndef Q_OS_LINUX
+ if (d->possiblyUnlocked && tryLock()) { unlock(); return; }
+#endif
+ qWarning("QMutex: destroying locked mutex");
+ }
+}
-/*!
+/*! \fn void QMutex::lock()
Locks the mutex. If another thread has locked the mutex then this
call will block until that thread has unlocked it.
@@ -145,40 +175,8 @@ QMutex::~QMutex()
\sa unlock()
*/
-void QMutex::lock()
-{
- QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
- Qt::HANDLE self;
-
- if (d->recursive) {
- self = QThread::currentThreadId();
- if (d->owner == self) {
- ++d->count;
- Q_ASSERT_X(d->count != 0, "QMutex::lock", "Overflow in recursion counter");
- return;
- }
- bool isLocked = d->contenders.testAndSetAcquire(0, 1);
- if (!isLocked) {
- // didn't get the lock, wait for it
- isLocked = d->wait();
- Q_ASSERT_X(isLocked, "QMutex::lock",
- "Internal error, infinite wait has timed out.");
- }
-
- d->owner = self;
- ++d->count;
- Q_ASSERT_X(d->count != 0, "QMutex::lock", "Overflow in recursion counter");
- return;
- }
-
- bool isLocked = d->contenders.testAndSetAcquire(0, 1);
- if (!isLocked) {
- lockInternal();
- }
-}
-
-/*!
+/*!\fn bool QMutex::trylock()
Attempts to lock the mutex. If the lock was obtained, this function
returns true. If another thread has locked the mutex, this
function returns false immediately.
@@ -195,36 +193,9 @@ void QMutex::lock()
\sa lock(), unlock()
*/
-bool QMutex::tryLock()
-{
- QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
- Qt::HANDLE self;
- if (d->recursive) {
- self = QThread::currentThreadId();
- if (d->owner == self) {
- ++d->count;
- Q_ASSERT_X(d->count != 0, "QMutex::tryLock", "Overflow in recursion counter");
- return true;
- }
-
- bool isLocked = d->contenders.testAndSetAcquire(0, 1);
- if (!isLocked) {
- // some other thread has the mutex locked, or we tried to
- // recursively lock an non-recursive mutex
- return isLocked;
- }
-
- d->owner = self;
- ++d->count;
- Q_ASSERT_X(d->count != 0, "QMutex::tryLock", "Overflow in recursion counter");
- return isLocked;
- }
-
- return d->contenders.testAndSetAcquire(0, 1);
-}
-
-/*! \overload
+/*! \fn bool QMutex::tryLock(int timeout)
+ \overload
Attempts to lock the mutex. This function returns true if the lock
was obtained; otherwise it returns false. If another thread has
@@ -247,81 +218,30 @@ bool QMutex::tryLock()
\sa lock(), unlock()
*/
-bool QMutex::tryLock(int timeout)
-{
- QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
- Qt::HANDLE self;
- if (d->recursive) {
- self = QThread::currentThreadId();
- if (d->owner == self) {
- ++d->count;
- Q_ASSERT_X(d->count != 0, "QMutex::tryLock", "Overflow in recursion counter");
- return true;
- }
- bool isLocked = d->contenders.testAndSetAcquire(0, 1);
- if (!isLocked) {
- // didn't get the lock, wait for it
- isLocked = d->wait(timeout);
- if (!isLocked)
- return false;
- }
-
- d->owner = self;
- ++d->count;
- Q_ASSERT_X(d->count != 0, "QMutex::tryLock", "Overflow in recursion counter");
- return true;
- }
-
- return (d->contenders.testAndSetAcquire(0, 1)
- // didn't get the lock, wait for it
- || d->wait(timeout));
-}
-
-
-/*!
+/*! \fn void QMutex::unlock()
Unlocks the mutex. Attempting to unlock a mutex in a different
thread to the one that locked it results in an error. Unlocking a
mutex that is not locked results in undefined behavior.
\sa lock()
*/
-void QMutex::unlock()
-{
- QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
- if (d->recursive) {
- if (!--d->count) {
- d->owner = 0;
- if (!d->contenders.testAndSetRelease(1, 0))
- d->wakeUp();
- }
- } else {
- if (!d->contenders.testAndSetRelease(1, 0))
- d->wakeUp();
- }
-}
/*!
- \fn bool QMutex::locked()
-
- Returns true if the mutex is locked by another thread; otherwise
- returns false.
-
- It is generally a bad idea to use this function, because code
- that uses it has a race condition. Use tryLock() and unlock()
- instead.
-
- \oldcode
- bool isLocked = mutex.locked();
- \newcode
- bool isLocked = true;
- if (mutex.tryLock()) {
- mutex.unlock();
- isLocked = false;
- }
- \endcode
+ \fn void QMutex::isRecursive()
+ \since 5.0
+
+ Returns true if the mutex is recursive
+
*/
+bool QBasicMutex::isRecursive() {
+ QMutexPrivate *d = this->d;
+ if (quintptr(d) <= 0x3)
+ return false;
+ return d->recursive;
+}
+
/*!
\class QMutexLocker
@@ -418,96 +338,217 @@ void QMutex::unlock()
\sa unlock()
*/
+#ifndef Q_OS_LINUX //linux implementation is in qmutex_linux.cpp
/*!
- \fn QMutex::QMutex(bool recursive)
-
- Use the constructor that takes a RecursionMode parameter instead.
-*/
-
-/*!
- \internal helper for lockInline()
+ \internal helper for lock()
*/
-void QMutex::lockInternal()
+bool QBasicMutex::lockInternal(int timeout)
{
- QMutexPrivate *d = static_cast<QMutexPrivate *>(this->d);
-
- if (QThread::idealThreadCount() == 1) {
- // don't spin on single cpu machines
- bool isLocked = d->wait();
- Q_ASSERT_X(isLocked, "QMutex::lock",
- "Internal error, infinite wait has timed out.");
- Q_UNUSED(isLocked);
- return;
- }
+ while (!fastTryLock()) {
+ QMutexPrivate *d = this->d;
+ if (!d) // if d is 0, the mutex is unlocked
+ continue;
- QElapsedTimer elapsedTimer;
- elapsedTimer.start();
- do {
- qint64 spinTime = elapsedTimer.nsecsElapsed();
- if (spinTime > d->maximumSpinTime) {
- // didn't get the lock, wait for it, since we're not going to gain anything by spinning more
- elapsedTimer.start();
- bool isLocked = d->wait();
- Q_ASSERT_X(isLocked, "QMutex::lock",
- "Internal error, infinite wait has timed out.");
- Q_UNUSED(isLocked);
-
- qint64 maximumSpinTime = d->maximumSpinTime;
- qint64 averageWaitTime = d->averageWaitTime;
- qint64 actualWaitTime = elapsedTimer.nsecsElapsed();
- if (actualWaitTime < (QMutexPrivate::MaximumSpinTimeThreshold * 3 / 2)) {
- // measure the wait times
- averageWaitTime = d->averageWaitTime = qMin((averageWaitTime + actualWaitTime) / 2, qint64(QMutexPrivate::MaximumSpinTimeThreshold));
+ if (d == dummyLocked()) {
+ if (timeout == 0)
+ return false;
+ QMutexPrivate *newD = QMutexPrivate::allocate();
+ if (!this->d.testAndSetOrdered(d, newD)) {
+ //Either the mutex is already unlocked, or another thread already set it.
+ newD->deref();
+ continue;
}
+ d = newD;
+ //the d->refCount is already 1 the deref will occurs when we unlock
+ } else if (d->recursive) {
+ return static_cast<QRecursiveMutexPrivate *>(d)->lock(timeout);
+ }
+
+ if (timeout == 0 && !d->possiblyUnlocked)
+ return false;
- // adjust the spin count when spinning does not benefit contention performance
- if ((spinTime + actualWaitTime) - qint64(QMutexPrivate::MaximumSpinTimeThreshold) >= qint64(QMutexPrivate::MaximumSpinTimeThreshold)) {
- // long waits, stop spinning
- d->maximumSpinTime = 0;
- } else {
- // allow spinning if wait times decrease, but never spin more than the average wait time (otherwise we may perform worse)
- d->maximumSpinTime = qBound(qint64(averageWaitTime * 3 / 2), maximumSpinTime / 2, qint64(QMutexPrivate::MaximumSpinTimeThreshold));
+ if (!d->ref())
+ continue; //that QMutexPrivate was already released
+
+ if (d != this->d) {
+ //Either the mutex is already unlocked, or relocked with another mutex
+ d->deref();
+ continue;
+ }
+
+ int old_waiters;
+ do {
+ old_waiters = d->waiters;
+ if (old_waiters == -QMutexPrivate::BigNumber) {
+ // we are unlocking, and the thread that unlocks is about to change d to 0
+ // we try to aquire the mutex by changing to dummyLocked()
+ if (this->d.testAndSetAcquire(d, dummyLocked())) {
+ // Mutex aquired
+ Q_ASSERT(d->waiters == -QMutexPrivate::BigNumber || d->waiters == 0);
+ d->waiters = 0;
+ d->deref();
+ return true;
+ } else {
+ Q_ASSERT(d != this->d); //else testAndSetAcquire should have succeeded
+ // Mutex is likely to bo 0, we should continue the outer-loop,
+ // set old_waiters to the magic value of BigNumber
+ old_waiters = QMutexPrivate::BigNumber;
+ break;
+ }
+ }
+ } while (!d->waiters.testAndSetRelaxed(old_waiters, old_waiters + 1));
+
+ if (d != this->d) {
+ // Mutex was unlocked.
+ if (old_waiters != QMutexPrivate::BigNumber) {
+ //we did not break the previous loop
+ Q_ASSERT(d->waiters >= 1);
+ d->waiters.deref();
}
- return;
+ d->deref();
+ continue;
+ }
+
+ if (d->wait(timeout)) {
+ if (d->possiblyUnlocked && d->possiblyUnlocked.testAndSetRelaxed(true, false))
+ d->deref();
+ d->derefWaiters(1);
+ //we got the lock. (do not deref)
+ Q_ASSERT(d == this->d);
+ return true;
+ } else {
+ Q_ASSERT(timeout >= 0);
+ //timeout
+ d->derefWaiters(1);
+ //There may be a race in which the mutex is unlocked right after we timed out,
+ // and before we deref the waiters, so maybe the mutex is actually unlocked.
+ if (!d->possiblyUnlocked.testAndSetRelaxed(false, true))
+ d->deref();
+ return false;
}
- // be a good citizen... yielding lets something else run if there is something to run, but may also relieve memory pressure if not
- QThread::yieldCurrentThread();
- } while (d->contenders != 0 || !d->contenders.testAndSetAcquire(0, 1));
-
- // spinning is working, do not change the spin time (unless we are using much less time than allowed to spin)
- qint64 maximumSpinTime = d->maximumSpinTime;
- qint64 spinTime = elapsedTimer.nsecsElapsed();
- if (spinTime < maximumSpinTime / 2) {
- // we are using much less time than we need, adjust the limit
- d->maximumSpinTime = qBound(qint64(d->averageWaitTime * 3 / 2), maximumSpinTime / 2, qint64(QMutexPrivate::MaximumSpinTimeThreshold));
}
+ Q_ASSERT(this->d);
+ return true;
}
/*!
\internal
*/
-void QMutex::unlockInternal()
+void QBasicMutex::unlockInternal()
{
- static_cast<QMutexPrivate *>(d)->wakeUp();
+ QMutexPrivate *d = this->d;
+ Q_ASSERT(d); //we must be locked
+ Q_ASSERT(d != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
+
+ if (d->recursive) {
+ static_cast<QRecursiveMutexPrivate *>(d)->unlock();
+ return;
+ }
+
+ if (d->waiters.fetchAndAddRelease(-QMutexPrivate::BigNumber) == 0) {
+ //there is no one waiting on this mutex anymore, set the mutex as unlocked (d = 0)
+ if (this->d.testAndSetRelease(d, 0)) {
+ if (d->possiblyUnlocked && d->possiblyUnlocked.testAndSetRelaxed(true, false))
+ d->deref();
+ }
+ d->derefWaiters(0);
+ } else {
+ d->derefWaiters(0);
+ //there are thread waiting, transfer the lock.
+ d->wakeUp();
+ }
+ d->deref();
}
-/*!
- \fn QMutex::lockInline()
- \internal
- inline version of QMutex::lock()
-*/
+//The freelist managment
+namespace {
+struct FreeListConstants : QFreeListDefaultConstants {
+ enum { BlockCount = 4, MaxIndex=0xffff };
+ static const int Sizes[BlockCount];
+};
+const int FreeListConstants::Sizes[FreeListConstants::BlockCount] = {
+ 16,
+ 128,
+ 1024,
+ FreeListConstants::MaxIndex - (16-128-1024)
+};
+
+typedef QFreeList<QMutexPrivate, FreeListConstants> FreeList;
+Q_GLOBAL_STATIC(FreeList, freelist);
+}
+
+QMutexPrivate *QMutexPrivate::allocate()
+{
+ int i = freelist()->next();
+ QMutexPrivate *d = &(*freelist())[i];
+ d->id = i;
+ Q_ASSERT(d->refCount == 0);
+ Q_ASSERT(!d->recursive);
+ Q_ASSERT(!d->possiblyUnlocked);
+ Q_ASSERT(d->waiters == 0);
+ d->refCount = 1;
+ return d;
+}
+
+void QMutexPrivate::release()
+{
+ Q_ASSERT(!recursive);
+ Q_ASSERT(refCount == 0);
+ Q_ASSERT(!possiblyUnlocked);
+ Q_ASSERT(waiters == 0);
+ freelist()->release(id);
+}
+
+// atomically substract "value" to the waiters, and remove the QMutexPrivate::BigNumber flag
+void QMutexPrivate::derefWaiters(int value)
+{
+ int old_waiters;
+ int new_waiters;
+ do {
+ old_waiters = waiters;
+ new_waiters = old_waiters;
+ if (new_waiters < 0) {
+ new_waiters += QMutexPrivate::BigNumber;
+ }
+ new_waiters -= value;
+ } while (!waiters.testAndSetRelaxed(old_waiters, new_waiters));
+}
+#endif
/*!
- \fn QMutex::unlockInline()
\internal
- inline version of QMutex::unlock()
-*/
+ */
+bool QRecursiveMutexPrivate::lock(int timeout) {
+ Qt::HANDLE self = QThread::currentThreadId();
+ if (owner == self) {
+ ++count;
+ Q_ASSERT_X(count != 0, "QMutex::lock", "Overflow in recursion counter");
+ return true;
+ }
+ bool success = true;
+ if (timeout == -1) {
+ mutex.lock();
+ } else {
+ success = mutex.tryLock(timeout);
+ }
+
+ if (success)
+ owner = self;
+ return success;
+}
/*!
- \fn QMutex::tryLockInline()
\internal
- inline version of QMutex::tryLock()
-*/
+ */
+void QRecursiveMutexPrivate::unlock()
+{
+ if (count > 0) {
+ count--;
+ } else {
+ owner = 0;
+ mutex.unlock();
+ }
+}
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index cc667560db..a49b981d01 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -52,47 +52,64 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Core)
-#ifndef QT_NO_THREAD
+#if !defined(QT_NO_THREAD) && !defined(qdoc)
-class QAtomicInt;
-class QMutexData;
+class QMutexPrivate;
-class Q_CORE_EXPORT QMutex
+class Q_CORE_EXPORT QBasicMutex
{
- friend class QWaitCondition;
- friend class QWaitConditionPrivate;
-
public:
- enum RecursionMode { NonRecursive, Recursive };
+ inline void lock() {
+ if (!fastTryLock())
+ lockInternal();
+ }
- explicit QMutex(RecursionMode mode = NonRecursive);
- ~QMutex();
+ inline void unlock() {
+ Q_ASSERT(d); //mutex must be locked
+ if (!d.testAndSetRelease(dummyLocked(), 0))
+ unlockInternal();
+ }
+
+ bool tryLock(int timeout = 0) {
+ return fastTryLock() || lockInternal(timeout);
+ }
- void lock(); //### Qt5: make inline;
- inline void lockInline();
- bool tryLock(); //### Qt5: make inline;
- bool tryLock(int timeout);
- inline bool tryLockInline();
- void unlock(); //### Qt5: make inline;
- inline void unlockInline();
+ bool isRecursive();
private:
- void lockInternal();
+ inline bool fastTryLock() {
+ return d.testAndSetAcquire(0, dummyLocked());
+ }
+ bool lockInternal(int timeout = -1);
void unlockInternal();
- Q_DISABLE_COPY(QMutex)
- QMutexData *d;
+ QBasicAtomicPointer<QMutexPrivate> d;
+ static inline QMutexPrivate *dummyLocked() {
+ return reinterpret_cast<QMutexPrivate *>(quintptr(1));
+ }
+
+ friend class QMutex;
+ friend class QMutexPrivate;
+};
+
+class Q_CORE_EXPORT QMutex : public QBasicMutex {
+public:
+ enum RecursionMode { NonRecursive, Recursive };
+ explicit QMutex(RecursionMode mode = NonRecursive);
+ ~QMutex();
+private:
+ Q_DISABLE_COPY(QMutex)
};
class Q_CORE_EXPORT QMutexLocker
{
public:
- inline explicit QMutexLocker(QMutex *m)
+ inline explicit QMutexLocker(QBasicMutex *m)
{
Q_ASSERT_X((reinterpret_cast<quintptr>(m) & quintptr(1u)) == quintptr(0),
"QMutexLocker", "QMutex pointer is misaligned");
if (m) {
- m->lockInline();
+ m->lock();
val = reinterpret_cast<quintptr>(m) | quintptr(1u);
} else {
val = 0;
@@ -104,7 +121,7 @@ public:
{
if ((val & quintptr(1u)) == quintptr(1u)) {
val &= ~quintptr(1u);
- mutex()->unlockInline();
+ mutex()->unlock();
}
}
@@ -112,7 +129,7 @@ public:
{
if (val) {
if ((val & quintptr(1u)) == quintptr(0u)) {
- mutex()->lockInline();
+ mutex()->lock();
val |= quintptr(1u);
}
}
@@ -138,54 +155,9 @@ private:
quintptr val;
};
-class QMutexData
-{
- public:
- QAtomicInt contenders;
- const uint recursive : 1;
- uint reserved : 31;
- protected:
- QMutexData(QMutex::RecursionMode mode);
- ~QMutexData();
-};
-
-#ifdef QT_NO_DEBUG
-inline void QMutex::unlockInline()
-{
- if (d->recursive) {
- unlock();
- } else if (!d->contenders.testAndSetRelease(1, 0)) {
- unlockInternal();
- }
-}
-
-inline bool QMutex::tryLockInline()
-{
- if (d->recursive) {
- return tryLock();
- } else {
- return d->contenders.testAndSetAcquire(0, 1);
- }
-}
-
-inline void QMutex::lockInline()
-{
- if (d->recursive) {
- lock();
- } else if(!tryLockInline()) {
- lockInternal();
- }
-}
-#else // QT_NO_DEBUG
-//in debug we do not use inline calls in order to allow debugging tools
-// to hook the mutex locking functions.
-inline void QMutex::unlockInline() { unlock(); }
-inline bool QMutex::tryLockInline() { return tryLock(); }
-inline void QMutex::lockInline() { lock(); }
-#endif // QT_NO_DEBUG
-#else // QT_NO_THREAD
+#else // QT_NO_THREAD or qdoc
class Q_CORE_EXPORT QMutex
@@ -194,14 +166,11 @@ public:
enum RecursionMode { NonRecursive, Recursive };
inline explicit QMutex(RecursionMode mode = NonRecursive) { Q_UNUSED(mode); }
- inline ~QMutex() {}
static inline void lock() {}
- static inline void lockInline() {}
static inline bool tryLock(int timeout = 0) { Q_UNUSED(timeout); return true; }
- static inline bool tryLockInline() { return true; }
static inline void unlock() {}
- static inline void unlockInline() {}
+ static inline bool isRecursive() { return true; }
private:
Q_DISABLE_COPY(QMutex)
@@ -221,7 +190,9 @@ private:
Q_DISABLE_COPY(QMutexLocker)
};
-#endif // QT_NO_THREAD
+typedef QMutex QBasicMutex;
+
+#endif // QT_NO_THREAD or qdoc
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp
new file mode 100644
index 0000000000..17015b8f84
--- /dev/null
+++ b/src/corelib/thread/qmutex_linux.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qmutex.h"
+
+#ifndef QT_NO_THREAD
+#include "qatomic.h"
+#include "qmutex_p.h"
+# include "qelapsedtimer.h"
+
+#include <linux/futex.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <errno.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline int _q_futex(QMutexPrivate *volatile *addr, int op, int val, const struct timespec *timeout)
+{
+ volatile int *int_addr = reinterpret_cast<volatile int *>(addr);
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN && QT_POINTER_SIZE == 8
+ int_addr++; //We want a pointer to the 32 least significant bit of QMutex::d
+#endif
+ int *addr2 = 0;
+ int val2 = 0;
+ return syscall(SYS_futex, int_addr, op, val, timeout, addr2, val2);
+}
+
+static inline QMutexPrivate *dummyFutexValue()
+{
+ return reinterpret_cast<QMutexPrivate *>(quintptr(3));
+}
+
+
+QMutexPrivate::~QMutexPrivate() {}
+QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
+ : recursive(mode == QMutex::Recursive) {}
+
+bool QBasicMutex::lockInternal(int timeout)
+{
+ QElapsedTimer elapsedTimer;
+ if (timeout >= 1)
+ elapsedTimer.start();
+
+ while (!fastTryLock()) {
+ QMutexPrivate *d = this->d;
+ if (!d) // if d is 0, the mutex is unlocked
+ continue;
+
+ if (quintptr(d) <= 0x3) { //d == dummyLocked() || d == dummyFutexValue()
+ if (timeout == 0)
+ return false;
+ while (this->d.fetchAndStoreAcquire(dummyFutexValue()) != 0) {
+ struct timespec ts, *pts = 0;
+ if (timeout >= 1) {
+ // recalculate the timeout
+ qint64 xtimeout = timeout * 1000 * 1000;
+ xtimeout -= elapsedTimer.nsecsElapsed();
+ if (xtimeout <= 0) {
+ // timer expired after we returned
+ return false;
+ }
+ ts.tv_sec = xtimeout / Q_INT64_C(1000) / 1000 / 1000;
+ ts.tv_nsec = xtimeout % (Q_INT64_C(1000) * 1000 * 1000);
+ pts = &ts;
+ }
+ int r = _q_futex(&this->d._q_value, FUTEX_WAIT, quintptr(dummyFutexValue()), pts);
+ if (r != 0 && errno == ETIMEDOUT)
+ return false;
+ }
+ return true;
+ }
+ Q_ASSERT(d->recursive);
+ return static_cast<QRecursiveMutexPrivate *>(d)->lock(timeout);
+ }
+ Q_ASSERT(this->d);
+ return true;
+}
+
+void QBasicMutex::unlockInternal()
+{
+ QMutexPrivate *d = this->d;
+ Q_ASSERT(d); //we must be locked
+ Q_ASSERT(d != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed
+
+ if (d == dummyFutexValue()) {
+ this->d.fetchAndStoreRelease(0);
+ _q_futex(&this->d._q_value, FUTEX_WAKE, 1, 0);
+ return;
+ }
+
+ Q_ASSERT(d->recursive);
+ static_cast<QRecursiveMutexPrivate *>(d)->unlock();
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_THREAD
diff --git a/src/corelib/thread/qmutex_mac.cpp b/src/corelib/thread/qmutex_mac.cpp
new file mode 100644
index 0000000000..f63feebca4
--- /dev/null
+++ b/src/corelib/thread/qmutex_mac.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qmutex.h"
+
+#if !defined(QT_NO_THREAD)
+
+#include "qmutex_p.h"
+
+#include <mach/mach.h>
+#include <mach/task.h>
+
+#include <errno.h>
+
+QT_BEGIN_NAMESPACE
+
+QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
+ : recursive(mode == QMutex::Recursive)
+{
+ kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0);
+ if (r != KERN_SUCCESS)
+ qWarning("QMutex: failed to create semaphore, error %d", r);
+}
+
+QMutexPrivate::~QMutexPrivate()
+{
+ kern_return_t r = semaphore_destroy(mach_task_self(), mach_semaphore);
+ if (r != KERN_SUCCESS)
+ qWarning("QMutex: failed to destroy semaphore, error %d", r);
+}
+
+bool QMutexPrivate::wait(int timeout)
+{
+ kern_return_t r;
+ if (timeout < 0) {
+ do {
+ r = semaphore_wait(mach_semaphore);
+ } while (r == KERN_ABORTED);
+ Q_ASSERT(r == KERN_SUCCESS);
+ } else {
+ mach_timespec_t ts;
+ ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
+ ts.tv_sec = (timeout / 1000);
+ r = semaphore_timedwait(mach_semaphore, ts);
+ }
+ return (r == KERN_SUCCESS);
+}
+
+void QMutexPrivate::wakeUp()
+{
+ semaphore_signal(mach_semaphore);
+}
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_THREAD
diff --git a/src/corelib/thread/qmutex_p.h b/src/corelib/thread/qmutex_p.h
index a9923c47a4..00f071ebef 100644
--- a/src/corelib/thread/qmutex_p.h
+++ b/src/corelib/thread/qmutex_p.h
@@ -57,50 +57,80 @@
#include <QtCore/qglobal.h>
#include <QtCore/qnamespace.h>
#include <QtCore/qmutex.h>
+#include <QtCore/qatomic.h>
#if defined(Q_OS_MAC)
# include <mach/semaphore.h>
#endif
-#if defined(Q_OS_SYMBIAN)
-# include <e32std.h>
-#endif
-
QT_BEGIN_NAMESPACE
-class QMutexPrivate : public QMutexData {
+class QMutexPrivate {
public:
- QMutexPrivate(QMutex::RecursionMode mode);
~QMutexPrivate();
+ QMutexPrivate(QMutex::RecursionMode mode = QMutex::NonRecursive);
bool wait(int timeout = -1);
void wakeUp();
- // 1ms = 1000000ns
- enum { MaximumSpinTimeThreshold = 1000000 };
- volatile qint64 maximumSpinTime;
- volatile qint64 averageWaitTime;
- Qt::HANDLE owner;
- uint count;
+#if !defined(Q_OS_LINUX)
+ // Conrol the lifetime of the privates
+ QAtomicInt refCount;
+ int id;
+
+ bool ref() {
+ Q_ASSERT(refCount >= 0);
+ int c;
+ do {
+ c = refCount;
+ if (c == 0)
+ return false;
+ } while (!refCount.testAndSetRelaxed(c, c + 1));
+ Q_ASSERT(refCount >= 0);
+ return true;
+ }
+ void deref() {
+ Q_ASSERT(refCount >=0);
+ if (!refCount.deref())
+ release();
+ Q_ASSERT(refCount >=0);
+ }
+ void release();
+ static QMutexPrivate *allocate();
+
+ QAtomicInt waiters; //number of thread waiting
+ QAtomicInt possiblyUnlocked; //bool saying that a timed wait timed out
+ enum { BigNumber = 0x100000 }; //Must be bigger than the possible number of waiters (number of threads)
+ void derefWaiters(int value);
+#endif
+
+ // handle recursive mutex
+ bool recursive;
+ //platform specific stuff
#if defined(Q_OS_MAC)
semaphore_t mach_semaphore;
-#elif defined(Q_OS_UNIX) && !defined(Q_OS_LINUX) && !defined(Q_OS_SYMBIAN)
- volatile bool wakeup;
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_LINUX)
+ bool wakeup;
pthread_mutex_t mutex;
pthread_cond_t cond;
#elif defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
HANDLE event;
-#elif defined(Q_OS_SYMBIAN)
- RSemaphore lock;
#endif
};
-inline QMutexData::QMutexData(QMutex::RecursionMode mode)
- : recursive(mode == QMutex::Recursive)
-{}
+class QRecursiveMutexPrivate : public QMutexPrivate
+{
+public:
+ QRecursiveMutexPrivate()
+ : QMutexPrivate(QMutex::Recursive), owner(0), count(0) {}
+ Qt::HANDLE owner;
+ uint count;
+ QMutex mutex;
-inline QMutexData::~QMutexData() {}
+ bool lock(int timeout);
+ void unlock();
+};
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index e692e19525..0bccad589d 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -46,142 +46,35 @@
#ifndef QT_NO_THREAD
#include "qatomic.h"
#include "qmutex_p.h"
-
#include <errno.h>
#if defined(Q_OS_VXWORKS) && defined(wakeup)
#undef wakeup
#endif
-#if defined(Q_OS_MAC)
-# include <mach/mach.h>
-# include <mach/task.h>
-#elif defined(Q_OS_LINUX)
-# include <linux/futex.h>
-# include <sys/syscall.h>
-# include <unistd.h>
-# include <QtCore/qelapsedtimer.h>
-#endif
-
QT_BEGIN_NAMESPACE
-#if !defined(Q_OS_MAC) && !defined(Q_OS_LINUX)
static void report_error(int code, const char *where, const char *what)
{
if (code != 0)
qWarning("%s: %s failure: %s", where, what, qPrintable(qt_error_string(code)));
}
-#endif
-
QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
- : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), averageWaitTime(0), owner(0), count(0)
+ : recursive(mode == QMutex::Recursive), wakeup(false)
{
-#if defined(Q_OS_MAC)
- kern_return_t r = semaphore_create(mach_task_self(), &mach_semaphore, SYNC_POLICY_FIFO, 0);
- if (r != KERN_SUCCESS)
- qWarning("QMutex: failed to create semaphore, error %d", r);
-#elif !defined(Q_OS_LINUX)
- wakeup = false;
report_error(pthread_mutex_init(&mutex, NULL), "QMutex", "mutex init");
report_error(pthread_cond_init(&cond, NULL), "QMutex", "cv init");
-#endif
}
QMutexPrivate::~QMutexPrivate()
{
-#if defined(Q_OS_MAC)
- kern_return_t r = semaphore_destroy(mach_task_self(), mach_semaphore);
- if (r != KERN_SUCCESS)
- qWarning("QMutex: failed to destroy semaphore, error %d", r);
-#elif !defined(Q_OS_LINUX)
report_error(pthread_cond_destroy(&cond), "QMutex", "cv destroy");
report_error(pthread_mutex_destroy(&mutex), "QMutex", "mutex destroy");
-#endif
}
-#if defined(Q_OS_MAC)
-
bool QMutexPrivate::wait(int timeout)
{
- if (contenders.fetchAndAddAcquire(1) == 0) {
- // lock acquired without waiting
- return true;
- }
- kern_return_t r;
- if (timeout < 0) {
- do {
- r = semaphore_wait(mach_semaphore);
- } while (r == KERN_ABORTED);
- if (r != KERN_SUCCESS)
- qWarning("QMutex: infinite wait failed, error %d", r);
- } else {
- mach_timespec_t ts;
- ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
- ts.tv_sec = (timeout / 1000);
- r = semaphore_timedwait(mach_semaphore, ts);
- }
- contenders.deref();
- return r == KERN_SUCCESS;
-}
-
-void QMutexPrivate::wakeUp()
-{
- semaphore_signal(mach_semaphore);
-}
-
-#elif defined(Q_OS_LINUX)
-
-static inline int _q_futex(volatile int *addr, int op, int val, const struct timespec *timeout, int *addr2, int val2)
-{
- return syscall(SYS_futex, addr, op, val, timeout, addr2, val2);
-}
-
-bool QMutexPrivate::wait(int timeout)
-{
- struct timespec ts, *pts = 0;
- QElapsedTimer timer;
- if (timeout >= 0) {
- ts.tv_nsec = ((timeout % 1000) * 1000) * 1000;
- ts.tv_sec = (timeout / 1000);
- pts = &ts;
- timer.start();
- }
- while (contenders.fetchAndStoreAcquire(2) > 0) {
- int r = _q_futex(&contenders._q_value, FUTEX_WAIT, 2, pts, 0, 0);
- if (r != 0 && errno == ETIMEDOUT)
- return false;
-
- if (pts) {
- // recalculate the timeout
- qint64 xtimeout = timeout * 1000 * 1000;
- xtimeout -= timer.nsecsElapsed();
- if (xtimeout < 0) {
- // timer expired after we returned
- return false;
- }
-
- ts.tv_sec = timeout / Q_INT64_C(1000) / 1000 / 1000;
- ts.tv_nsec = timeout % (Q_INT64_C(1000) * 1000 * 1000);
- }
- }
- return true;
-}
-
-void QMutexPrivate::wakeUp()
-{
- (void) contenders.fetchAndStoreRelease(0);
- (void) _q_futex(&contenders._q_value, FUTEX_WAKE, 1, 0, 0, 0);
-}
-
-#else // !Q_OS_MAC && !Q_OS_LINUX
-
-bool QMutexPrivate::wait(int timeout)
-{
- if (contenders.fetchAndAddAcquire(1) == 0) {
- // lock acquired without waiting
- return true;
- }
report_error(pthread_mutex_lock(&mutex), "QMutex::lock", "mutex lock");
int errorCode = 0;
while (!wakeup) {
@@ -190,12 +83,10 @@ bool QMutexPrivate::wait(int timeout)
} else {
struct timeval tv;
gettimeofday(&tv, 0);
-
timespec ti;
ti.tv_nsec = (tv.tv_usec + (timeout % 1000) * 1000) * 1000;
ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000);
ti.tv_nsec %= 1000000000;
-
errorCode = pthread_cond_timedwait(&cond, &mutex, &ti);
}
if (errorCode) {
@@ -207,10 +98,10 @@ bool QMutexPrivate::wait(int timeout)
report_error(errorCode, "QMutex::lock()", "cv wait");
}
}
+ bool ret = wakeup;
wakeup = false;
report_error(pthread_mutex_unlock(&mutex), "QMutex::lock", "mutex unlock");
- contenders.deref();
- return errorCode == 0;
+ return ret;
}
void QMutexPrivate::wakeUp()
@@ -221,7 +112,6 @@ void QMutexPrivate::wakeUp()
report_error(pthread_mutex_unlock(&mutex), "QMutex::unlock", "mutex unlock");
}
-#endif // !Q_OS_MAC && !Q_OS_LINUX
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index 53ad8cfe89..f6670f6d1e 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
QMutexPrivate::QMutexPrivate(QMutex::RecursionMode mode)
- : QMutexData(mode), maximumSpinTime(MaximumSpinTimeThreshold), averageWaitTime(0), owner(0), count(0)
+ : recursive(mode)
{
event = CreateEvent(0, FALSE, FALSE, 0);
if (!event)
@@ -60,13 +60,7 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
- if (contenders.fetchAndAddAcquire(1) == 0) {
- // lock acquired without waiting
- return true;
- }
- bool returnValue = (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
- contenders.deref();
- return returnValue;
+ return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
}
void QMutexPrivate::wakeUp()
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index 8f01c1c056..e65a601369 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -79,8 +79,8 @@ public:
void relock()
{
if (!locked) {
- if (mtx1) mtx1->lockInline();
- if (mtx2) mtx2->lockInline();
+ if (mtx1) mtx1->lock();
+ if (mtx2) mtx2->lock();
locked = true;
}
}
@@ -88,8 +88,8 @@ public:
void unlock()
{
if (locked) {
- if (mtx1) mtx1->unlockInline();
- if (mtx2) mtx2->unlockInline();
+ if (mtx1) mtx1->unlock();
+ if (mtx2) mtx2->unlock();
locked = false;
}
}
@@ -100,10 +100,10 @@ public:
if (mtx1 == mtx2)
return false;
if (mtx1 < mtx2) {
- mtx2->lockInline();
+ mtx2->lock();
return true;
}
- if (!mtx2->tryLockInline()) {
+ if (!mtx2->tryLock()) {
mtx1->unlock();
mtx2->lock();
mtx1->lock();
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index b946a9de24..dd85bf4023 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -146,7 +146,7 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
if (! mutex)
return false;
- if (mutex->d->recursive) {
+ if (mutex->isRecursive()) {
qWarning("QWaitCondition: cannot wait on recursive mutexes");
return false;
}
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index 8a8db97342..bf1ec5e5ba 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -164,7 +164,7 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
if (!mutex)
return false;
- if (mutex->d->recursive) {
+ if (mutex->isRecursive()) {
qWarning("QWaitCondition::wait: Cannot wait on recursive mutexes");
return false;
}
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index 592ab1644b..309bf30d25 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -24,8 +24,7 @@ SOURCES += thread/qatomic.cpp \
thread/qthread.cpp \
thread/qthreadstorage.cpp
-unix:!symbian:SOURCES += thread/qmutex_unix.cpp \
- thread/qthread_unix.cpp \
+unix:!symbian:SOURCES += thread/qthread_unix.cpp \
thread/qwaitcondition_unix.cpp
symbian:SOURCES += thread/qmutex_symbian.cpp \
@@ -39,3 +38,9 @@ win32:SOURCES += thread/qmutex_win.cpp \
integrity:SOURCES += thread/qmutex_unix.cpp \
thread/qthread_unix.cpp \
thread/qwaitcondition_unix.cpp
+
+unix: {
+ macx-* { SOURCES += thread/qmutex_mac.cpp }
+ else:linux-* { SOURCES += thread/qmutex_linux.cpp }
+ else { SOURCES += thread/qmutex_unix.cpp }
+}
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 9f21b72bfd..11ebd8a103 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -904,7 +904,7 @@ QByteArray &QByteArray::operator=(const char *str)
x = const_cast<Data *>(&shared_empty.ba);
} else {
int len = qstrlen(str);
- if (d->ref != 1 || len > d->alloc || (len < d->size && len < d->alloc >> 1))
+ if (d->ref != 1 || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1))
realloc(len);
x = d;
memcpy(x->data(), str, len + 1); // include null terminator
@@ -1432,9 +1432,10 @@ void QByteArray::resize(int size)
x->data()[size] = '\0';
d = x;
} else {
- if (d->ref != 1 || size > d->alloc || (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
+ if (d->ref != 1 || size > int(d->alloc)
+ || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
realloc(qAllocMore(size, sizeof(Data)));
- if (d->alloc >= size) {
+ if (int(d->alloc) >= size) {
d->size = size;
d->data()[size] = '\0';
}
@@ -1563,7 +1564,7 @@ QByteArray &QByteArray::prepend(const char *str)
QByteArray &QByteArray::prepend(const char *str, int len)
{
if (str) {
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
memmove(d->data()+len, d->data(), d->size);
memcpy(d->data(), str, len);
@@ -1581,7 +1582,7 @@ QByteArray &QByteArray::prepend(const char *str, int len)
QByteArray &QByteArray::prepend(char ch)
{
- if (d->ref != 1 || d->size + 1 > d->alloc)
+ if (d->ref != 1 || d->size + 1 > int(d->alloc))
realloc(qAllocMore(d->size + 1, sizeof(Data)));
memmove(d->data()+1, d->data(), d->size);
d->data()[0] = ch;
@@ -1619,7 +1620,7 @@ QByteArray &QByteArray::append(const QByteArray &ba)
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
*this = ba;
} else if (ba.d != &shared_null.ba) {
- if (d->ref != 1 || d->size + ba.d->size > d->alloc)
+ if (d->ref != 1 || d->size + ba.d->size > int(d->alloc))
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
d->size += ba.d->size;
@@ -1653,7 +1654,7 @@ QByteArray& QByteArray::append(const char *str)
{
if (str) {
int len = qstrlen(str);
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
memcpy(d->data() + d->size, str, len + 1); // include null terminator
d->size += len;
@@ -1678,7 +1679,7 @@ QByteArray &QByteArray::append(const char *str, int len)
if (len < 0)
len = qstrlen(str);
if (str && len) {
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
memcpy(d->data() + d->size, str, len); // include null terminator
d->size += len;
@@ -1695,7 +1696,7 @@ QByteArray &QByteArray::append(const char *str, int len)
QByteArray& QByteArray::append(char ch)
{
- if (d->ref != 1 || d->size + 1 > d->alloc)
+ if (d->ref != 1 || d->size + 1 > int(d->alloc))
realloc(qAllocMore(d->size + 1, sizeof(Data)));
d->data()[d->size++] = ch;
d->data()[d->size] = '\0';
@@ -2204,7 +2205,7 @@ QByteArray QByteArray::repeated(int times) const
QByteArray result;
result.reserve(resultSize);
- if (result.d->alloc != resultSize)
+ if (int(result.d->alloc) != resultSize)
return QByteArray(); // not enough memory
memcpy(result.d->data(), d->data(), d->size);
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index dbac302d05..b70dba4d55 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -133,10 +133,10 @@ struct QByteArrayData
inline const char *data() const { return d + sizeof(qptrdiff) + offset; }
};
-template<int n> struct QConstByteArrayData
+template<int N> struct QConstByteArrayData
{
const QByteArrayData ba;
- const char data[n];
+ const char data[N + 1];
};
template<int N> struct QConstByteArrayDataPtr
@@ -146,10 +146,10 @@ template<int N> struct QConstByteArrayDataPtr
#if defined(Q_COMPILER_LAMBDA)
-# define QByteArrayLiteral(str) ([]() { \
- enum { Size = sizeof(str) }; \
+# define QByteArrayLiteral(str) ([]() -> QConstByteArrayDataPtr<sizeof(str) - 1> { \
+ enum { Size = sizeof(str) - 1 }; \
static const QConstByteArrayData<Size> qbytearray_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, str }; \
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
return holder; }())
@@ -160,9 +160,9 @@ template<int N> struct QConstByteArrayDataPtr
# define QByteArrayLiteral(str) \
__extension__ ({ \
- enum { Size = sizeof(str) }; \
+ enum { Size = sizeof(str) - 1 }; \
static const QConstByteArrayData<Size> qbytearray_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, str }; \
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
holder; })
#endif
@@ -439,10 +439,10 @@ inline int QByteArray::capacity() const
{ return d->alloc; }
inline void QByteArray::reserve(int asize)
-{ if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true; }
+{ if (d->ref != 1 || asize > int(d->alloc)) realloc(asize); d->capacityReserved = true; }
inline void QByteArray::squeeze()
-{ if (d->size < d->alloc) realloc(d->size); d->capacityReserved = false; }
+{ if (d->size < int(d->alloc)) realloc(d->size); d->capacityReserved = false; }
class Q_CORE_EXPORT QByteRef {
QByteArray &a;
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 00261daa95..736bc63b11 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -317,8 +317,6 @@ QT_BEGIN_NAMESPACE
\value Vertical
\value Wide
- \omitvalue Single
-
\sa decomposition()
*/
@@ -382,12 +380,6 @@ QT_BEGIN_NAMESPACE
\value ByteOrderSwapped
\value ParagraphSeparator
\value LineSeparator
-
- \omitvalue null
- \omitvalue replacement
- \omitvalue byteOrderMark
- \omitvalue byteOrderSwapped
- \omitvalue nbsp
*/
/*!
@@ -957,7 +949,7 @@ QString QChar::decomposition(uint ucs4)
/*!
Returns the tag defining the composition of the character. Returns
- QChar::Single if no decomposition exists.
+ QChar::NoDecomposition if no decomposition exists.
*/
QChar::Decomposition QChar::decompositionTag() const
{
@@ -967,7 +959,7 @@ QChar::Decomposition QChar::decompositionTag() const
/*!
\overload
Returns the tag defining the composition of the UCS-4-encoded character
- specified by \a ucs4. Returns QChar::Single if no decomposition exists.
+ specified by \a ucs4. Returns QChar::NoDecomposition if no decomposition exists.
*/
QChar::Decomposition QChar::decompositionTag(uint ucs4)
{
@@ -1232,7 +1224,6 @@ ushort QChar::toCaseFolded(ushort ucs2)
return ucs2 + qGetProp(ucs2)->caseFoldDiff;
}
-
/*!
\fn char QChar::toLatin1() const
diff --git a/src/corelib/tools/qfreelist.cpp b/src/corelib/tools/qfreelist.cpp
new file mode 100644
index 0000000000..bbbdb25e49
--- /dev/null
+++ b/src/corelib/tools/qfreelist.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qfreelist_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// default sizes and offsets (no need to define these when customizing)
+enum {
+ Offset0 = 0x00000000,
+ Offset1 = 0x00008000,
+ Offset2 = 0x00080000,
+ Offset3 = 0x00800000,
+
+ Size0 = Offset1 - Offset0,
+ Size1 = Offset2 - Offset1,
+ Size2 = Offset3 - Offset2,
+ Size3 = QFreeListDefaultConstants::MaxIndex - Offset3
+};
+
+const int QFreeListDefaultConstants::Sizes[QFreeListDefaultConstants::BlockCount] = {
+ Size0,
+ Size1,
+ Size2,
+ Size3
+};
+
+QT_END_NAMESPACE
+
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
new file mode 100644
index 0000000000..74ba3b587e
--- /dev/null
+++ b/src/corelib/tools/qfreelist_p.h
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFREELIST_P_H
+#define QFREELIST_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qatomic.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+/*! \internal
+
+ Element in a QFreeList. ConstReferenceType and ReferenceType are used as
+ the return values for QFreeList::at() and QFreeList::operator[](). Contains
+ the real data storage (_t) and the id of the next free element (next).
+
+ Note: the t() functions should be used to access the data, not _t.
+*/
+template <typename T>
+struct QFreeListElement
+{
+ typedef const T &ConstReferenceType;
+ typedef T &ReferenceType;
+
+ T _t;
+ int next;
+
+ inline ConstReferenceType t() const { return _t; }
+ inline ReferenceType t() { return _t; }
+};
+
+/*! \internal
+
+ Element in a QFreeList without a paylout. ConstReferenceType and
+ ReferenceType are void, the t() functions return void and are empty.
+*/
+template <>
+struct QFreeListElement<void>
+{
+ typedef void ConstReferenceType;
+ typedef void ReferenceType;
+
+ int next;
+
+ inline void t() const { }
+ inline void t() { }
+};
+
+/*! \internal
+
+ Defines default constants used by QFreeList:
+
+ - The initial value returned by QFreeList::next() is zero.
+
+ - QFreeList allows for up to 16777216 elements in QFreeList and uses the top
+ 8 bits to store a serial counter for ABA protection.
+
+ - QFreeList will make a maximum of 4 allocations (blocks), with each
+ successive block larger than the previous.
+
+ - Sizes static int[] array to define the size of each block.
+
+ It is possible to define your own constants struct/class and give this to
+ QFreeList to customize/tune the behavior.
+*/
+struct Q_AUTOTEST_EXPORT QFreeListDefaultConstants
+{
+ // used by QFreeList, make sure to define all of when customizing
+ enum {
+ InitialNextValue = 0,
+ IndexMask = 0x00ffffff,
+ SerialMask = ~IndexMask & ~0x80000000,
+ SerialCounter = IndexMask + 1,
+ MaxIndex = IndexMask,
+ BlockCount = 4,
+ };
+
+ static const int Sizes[BlockCount];
+};
+
+/*! \internal
+
+ This is a generic implementation of a lock-free free list. Use next() to
+ get the next free entry in the list, and release(id) when done with the id.
+
+ This version is templated and allows having a payload of type T which can
+ be accessed using the id returned by next(). The payload is allocated and
+ deallocated automatically by the free list, but *NOT* when calling
+ next()/release(). Initialization should be done by code needing it after
+ next() returns. Likewise, cleanup() should happen before calling release().
+ It is possible to have use 'void' as the payload type, in which case the
+ free list only contains indexes to the next free entry.
+
+ The ConstantsType type defaults to QFreeListDefaultConstants above. You can
+ define your custom ConstantsType, see above for details on what needs to be
+ available.
+*/
+template <typename T, typename ConstantsType = QFreeListDefaultConstants>
+class QFreeList
+{
+ typedef T ValueType;
+ typedef QFreeListElement<T> ElementType;
+ typedef typename ElementType::ConstReferenceType ConstReferenceType;
+ typedef typename ElementType::ReferenceType ReferenceType;
+
+ // return which block the index \a x falls in, and modify \a x to be the index into that block
+ static inline int blockfor(int &x)
+ {
+ for (int i = 0; i < ConstantsType::BlockCount; ++i) {
+ int size = ConstantsType::Sizes[i];
+ if (x < size)
+ return i;
+ x -= size;
+ }
+ Q_ASSERT(false);
+ return -1;
+ }
+
+ // allocate a block of the given \a size, initialized starting with the given \a offset
+ static inline ElementType *allocate(int offset, int size)
+ {
+ // qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset);
+ ElementType *v = new ElementType[size];
+ for (int i = 0; i < size; ++i)
+ v[i].next = offset + i + 1;
+ return v;
+ }
+
+ // take the current serial number from \a o, increment it, and store it in \a n
+ static inline int incrementserial(int o, int n)
+ {
+ return (n & ConstantsType::IndexMask) | ((o + ConstantsType::SerialCounter) & ConstantsType::SerialMask);
+ }
+
+ // the blocks
+ QAtomicPointer<ElementType> _v[ConstantsType::BlockCount];
+ // the next free id
+ QAtomicInt _next;
+
+ // QFreeList is not copyable
+ Q_DISABLE_COPY(QFreeList)
+
+public:
+ inline QFreeList();
+ inline ~QFreeList();
+
+ // returns the payload for the given index \a x
+ inline ConstReferenceType at(int x) const;
+ inline ReferenceType operator[](int x);
+
+ /*
+ Return the next free id. Use this id to access the payload (see above).
+ Call release(id) when done using the id.
+ */
+ inline int next();
+ inline void release(int id);
+};
+
+template <typename T, typename ConstantsType>
+inline QFreeList<T, ConstantsType>::QFreeList()
+ : _next(ConstantsType::InitialNextValue)
+{ }
+
+template <typename T, typename ConstantsType>
+inline QFreeList<T, ConstantsType>::~QFreeList()
+{
+ for (int i = 0; i < ConstantsType::BlockCount; ++i)
+ delete [] static_cast<ElementType *>(_v[i]);
+}
+
+template <typename T, typename ConstantsType>
+inline typename QFreeList<T, ConstantsType>::ConstReferenceType QFreeList<T, ConstantsType>::at(int x) const
+{
+ const int block = blockfor(x);
+ return _v[block][x].t();
+}
+
+template <typename T, typename ConstantsType>
+inline typename QFreeList<T, ConstantsType>::ReferenceType QFreeList<T, ConstantsType>::operator[](int x)
+{
+ const int block = blockfor(x);
+ return _v[block][x].t();
+}
+
+template <typename T, typename ConstantsType>
+inline int QFreeList<T, ConstantsType>::next()
+{
+ int id, newid, at;
+ ElementType *v;
+ do {
+ id = _next; // .loadAqcuire();
+
+ at = id & ConstantsType::IndexMask;
+ const int block = blockfor(at);
+ v = _v[block];
+
+ if (!v) {
+ v = allocate((id & ConstantsType::IndexMask) - at, ConstantsType::Sizes[block]);
+ if (!_v[block].testAndSetRelease(0, v)) {
+ // race with another thread lost
+ delete [] v;
+ v = _v[block];
+ Q_ASSERT(v != 0);
+ }
+ }
+
+ newid = v[at].next | (id & ~ConstantsType::IndexMask);
+ } while (!_next.testAndSetRelease(id, newid));
+ // qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
+ // id & ConstantsType::IndexMask,
+ // newid & ConstantsType::IndexMask,
+ // (newid & ~ConstantsType::IndexMask) >> 24);
+ return id & ConstantsType::IndexMask;
+}
+
+template <typename T, typename ConstantsType>
+inline void QFreeList<T, ConstantsType>::release(int id)
+{
+ int at = id & ConstantsType::IndexMask;
+ const int block = blockfor(at);
+ ElementType *v = _v[block];
+
+ int x, newid;
+ do {
+ x = _next; // .loadAcquire();
+ v[at].next = x & ConstantsType::IndexMask;
+
+ newid = incrementserial(x, id);
+ } while (!_next.testAndSetRelease(x, newid));
+ // qDebug("QFreeList::release(%d): _next now %d (was %d), serial %d",
+ // id & ConstantsType::IndexMask,
+ // newid & ConstantsType::IndexMask,
+ // x & ConstantsType::IndexMask,
+ // (newid & ~ConstantsType::IndexMask) >> 24);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QFREELIST_P_H
diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp
index 68f780d9fd..324cd481ed 100644
--- a/src/corelib/tools/qharfbuzz.cpp
+++ b/src/corelib/tools/qharfbuzz.cpp
@@ -102,7 +102,7 @@ HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
return QChar::mirroredChar(ch);
}
-void *HB_Library_Resolve(const char *library, int version, const char *symbol)
+void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
{
#ifdef QT_NO_LIBRARY
return 0;
diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h
index 9b404bdf0c..811b186e8b 100644
--- a/src/corelib/tools/qshareddata.h
+++ b/src/corelib/tools/qshareddata.h
@@ -279,6 +279,9 @@ namespace std {
QT_BEGIN_NAMESPACE
#endif
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedDataPointer<T>, Q_MOVABLE_TYPE);
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QExplicitlySharedDataPointer<T>, Q_MOVABLE_TYPE);
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 9e238193a3..9ce5eead8c 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -1267,10 +1267,10 @@ void QString::resize(int size)
QString::free(d);
d = x;
} else {
- if (d->ref != 1 || size > d->alloc ||
- (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
+ if (d->ref != 1 || size > int(d->alloc) ||
+ (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
realloc(grow(size));
- if (d->alloc >= size) {
+ if (int(d->alloc) >= size) {
d->size = size;
d->data()[size] = '\0';
}
@@ -1560,7 +1560,7 @@ QString &QString::append(const QString &str)
if (d == &shared_null.str) {
operator=(str);
} else {
- if (d->ref != 1 || d->size + str.d->size > d->alloc)
+ if (d->ref != 1 || d->size + str.d->size > int(d->alloc))
realloc(grow(d->size + str.d->size));
memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
d->size += str.d->size;
@@ -1580,7 +1580,7 @@ QString &QString::append(const QLatin1String &str)
const uchar *s = (const uchar *)str.latin1();
if (s) {
int len = qstrlen((char *)s);
- if (d->ref != 1 || d->size + len > d->alloc)
+ if (d->ref != 1 || d->size + len > int(d->alloc))
realloc(grow(d->size + len));
ushort *i = d->data() + d->size;
while ((*i++ = *s++))
@@ -1623,7 +1623,7 @@ QString &QString::append(const QLatin1String &str)
*/
QString &QString::append(QChar ch)
{
- if (d->ref != 1 || d->size + 1 > d->alloc)
+ if (d->ref != 1 || d->size + 1 > int(d->alloc))
realloc(grow(d->size + 1));
d->data()[d->size++] = ch.unicode();
d->data()[d->size] = '\0';
@@ -3550,8 +3550,8 @@ static QByteArray toLatin1_helper(const QChar *data, int length)
const __m128i questionMark = _mm_set1_epi16('?');
// SSE has no compare instruction for unsigned comparison.
// The variables must be shiffted + 0x8000 to be compared
- const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
- const __m128i thresholdMask = _mm_set1_epi16(0xff + 0x8000);
+ const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
+ const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
for (int i = 0; i < chunkCount; ++i) {
__m128i chunk1 = _mm_loadu_si128((__m128i*)src); // load
src += 8;
@@ -6152,7 +6152,7 @@ QString QString::repeated(int times) const
QString result;
result.reserve(resultSize);
- if (result.d->alloc != resultSize)
+ if (int(result.d->alloc) != resultSize)
return QString(); // not enough memory
memcpy(result.d->data(), d->data(), d->size * sizeof(ushort));
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index af3e3f3ff9..209994de16 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -97,36 +97,43 @@ template<int N> struct QConstStringDataPtr
};
#if defined(Q_COMPILER_UNICODE_STRINGS)
-template<int n> struct QConstStringData
+template<int N> struct QConstStringData
{
const QStringData str;
- const char16_t data[n];
+ const char16_t data[N + 1];
};
-#define QT_QSTRING_UNICODE_MARKER u""
+
+#define QT_UNICODE_LITERAL_II(str) u"" str
#elif defined(Q_OS_WIN) || (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) || defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536)
// wchar_t is 2 bytes
-template<int n> struct QConstStringData
+template<int N> struct QConstStringData
{
const QStringData str;
- const wchar_t data[n];
+ const wchar_t data[N + 1];
};
-#define QT_QSTRING_UNICODE_MARKER L""
+
+#if defined(Q_CC_MSVC)
+# define QT_UNICODE_LITERAL_II(str) L##str
+#else
+# define QT_UNICODE_LITERAL_II(str) L"" str
+#endif
#else
-template<int n> struct QConstStringData
+template<int N> struct QConstStringData
{
const QStringData str;
- const ushort data[n];
+ const ushort data[N + 1];
};
#endif
-#if defined(QT_QSTRING_UNICODE_MARKER)
+#if defined(QT_UNICODE_LITERAL_II)
+# define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str)
# if defined(Q_COMPILER_LAMBDA)
-# define QStringLiteral(str) ([]() { \
- enum { Size = sizeof(QT_QSTRING_UNICODE_MARKER str)/2 }; \
+# define QStringLiteral(str) ([]() -> QConstStringDataPtr<sizeof(QT_UNICODE_LITERAL(str))/2 - 1> { \
+ enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
static const QConstStringData<Size> qstring_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, QT_QSTRING_UNICODE_MARKER str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, QT_UNICODE_LITERAL(str) }; \
QConstStringDataPtr<Size> holder = { &qstring_literal }; \
return holder; }())
@@ -137,9 +144,9 @@ template<int n> struct QConstStringData
# define QStringLiteral(str) \
__extension__ ({ \
- enum { Size = sizeof(QT_QSTRING_UNICODE_MARKER str)/2 }; \
+ enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \
static const QConstStringData<Size> qstring_literal = \
- { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, QT_QSTRING_UNICODE_MARKER str }; \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size, 0, 0, { 0 } }, QT_UNICODE_LITERAL(str) }; \
QConstStringDataPtr<Size> holder = { &qstring_literal }; \
holder; })
# endif
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 4c6848498b..7c1bde4ac7 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -108,13 +108,12 @@ QT_BEGIN_NAMESPACE
*/
/*! \internal
- Note: The len contains the ending \0
*/
void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out)
{
#ifndef QT_NO_TEXTCODEC
if (QString::codecForCStrings && len) {
- QString tmp = QString::fromAscii(a, len > 0 ? len - 1 : -1);
+ QString tmp = QString::fromAscii(a, len > 0 ? len : -1);
memcpy(out, reinterpret_cast<const char *>(tmp.constData()), sizeof(QChar) * tmp.size());
out += tmp.length();
return;
@@ -126,7 +125,7 @@ void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out
while (*a)
*out++ = QLatin1Char(*a++);
} else {
- for (int i = 0; i < len - 1; ++i)
+ for (int i = 0; i < len; ++i)
*out++ = QLatin1Char(a[i]);
}
}
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 6d998b62aa..30b81c42f4 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -294,7 +294,7 @@ template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
#ifndef QT_NO_CAST_FROM_ASCII
static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
{
- QAbstractConcatenable::convertFromAscii(a, N, out);
+ QAbstractConcatenable::convertFromAscii(a, N - 1, out);
}
#endif
static inline void appendTo(const char a[N], char *&out)
@@ -313,7 +313,7 @@ template <int N> struct QConcatenable<const char[N]> : private QAbstractConcaten
#ifndef QT_NO_CAST_FROM_ASCII
static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out)
{
- QAbstractConcatenable::convertFromAscii(a, N, out);
+ QAbstractConcatenable::convertFromAscii(a, N - 1, out);
}
#endif
static inline void appendTo(const char a[N], char *&out)
@@ -349,10 +349,9 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
enum { ExactSize = false };
static int size(const QByteArray &ba) { return ba.size(); }
#ifndef QT_NO_CAST_FROM_ASCII
- static inline void appendTo(const QByteArray &ba, QChar *&out)
+ static inline QT_ASCII_CAST_WARN void appendTo(const QByteArray &ba, QChar *&out)
{
- // adding 1 because convertFromAscii expects the size including the null-termination
- QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size() + 1, out);
+ QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size(), out);
}
#endif
static inline void appendTo(const QByteArray &ba, char *&out)
@@ -364,6 +363,26 @@ template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
}
};
+template <int N> struct QConcatenable<QConstByteArrayDataPtr<N> > : private QAbstractConcatenable
+{
+ typedef QConstByteArrayDataPtr<N> type;
+ typedef QByteArray ConvertTo;
+ enum { ExactSize = false };
+ static int size(const type &) { return N; }
+#ifndef QT_NO_CAST_FROM_ASCII
+ static inline QT_ASCII_CAST_WARN void appendTo(const type &a, QChar *&out)
+ {
+ QAbstractConcatenable::convertFromAscii(a.ptr->data, N, out);
+ }
+#endif
+ static inline void appendTo(const type &ba, char *&out)
+ {
+ const char *a = ba.ptr->data;
+ while (*a)
+ *out++ = *a++;
+ }
+};
+
namespace QtStringBuilder {
template <typename A, typename B> struct ConvertToTypeHelper
{ typedef A ConvertTo; };
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index f5b38eb1c0..13b597d513 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -13,6 +13,7 @@ HEADERS += \
tools/qdatetime.h \
tools/qdatetime_p.h \
tools/qeasingcurve.h \
+ tools/qfreelist_p.h \
tools/qhash.h \
tools/qline.h \
tools/qlinkedlist.h \
@@ -61,6 +62,7 @@ SOURCES += \
tools/qdatetime.cpp \
tools/qeasingcurve.cpp \
tools/qelapsedtimer.cpp \
+ tools/qfreelist.cpp \
tools/qhash.cpp \
tools/qline.cpp \
tools/qlinkedlist.cpp \
diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp
index fed18350bb..8e74b8b922 100644
--- a/src/dbus/qdbus_symbols.cpp
+++ b/src/dbus/qdbus_symbols.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
-void *qdbus_resolve_me(const char *name);
+void (*qdbus_resolve_me(const char *name))();
#if !defined QT_LINKED_LIBDBUS
@@ -95,20 +95,19 @@ bool qdbus_loadLibDBus()
return false;
}
-void *qdbus_resolve_conditionally(const char *name)
+void (*qdbus_resolve_conditionally(const char *name))()
{
if (qdbus_loadLibDBus())
return qdbus_libdbus->resolve(name);
return 0;
}
-void *qdbus_resolve_me(const char *name)
+void (*qdbus_resolve_me(const char *name))()
{
- void *ptr = 0;
if (!qdbus_loadLibDBus())
qFatal("Cannot find libdbus-1 in your system to resolve symbol '%s'.", name);
- ptr = qdbus_libdbus->resolve(name);
+ QFunctionPointer ptr = qdbus_libdbus->resolve(name);
if (!ptr)
qFatal("Cannot resolve '%s' in your libdbus-1.", name);
diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h
index a59c08a8ab..8178e2ecf3 100644
--- a/src/dbus/qdbus_symbols_p.h
+++ b/src/dbus/qdbus_symbols_p.h
@@ -63,8 +63,8 @@ QT_BEGIN_NAMESPACE
#if !defined QT_LINKED_LIBDBUS
-void *qdbus_resolve_conditionally(const char *name); // doesn't print a warning
-void *qdbus_resolve_me(const char *name); // prints a warning
+void (*qdbus_resolve_conditionally(const char *name))(); // doesn't print a warning
+void (*qdbus_resolve_me(const char *name))(); // prints a warning
bool qdbus_loadLibDBus();
# define DEFINEFUNC(ret, func, args, argcall, funcret) \
diff --git a/src/dbus/qdbusmetaobject.cpp b/src/dbus/qdbusmetaobject.cpp
index d12642d632..8daf2300b7 100644
--- a/src/dbus/qdbusmetaobject.cpp
+++ b/src/dbus/qdbusmetaobject.cpp
@@ -125,6 +125,11 @@ private:
MethodScriptable = 0x40
};
+ enum MetaObjectFlags {
+ DynamicMetaObject = 0x01,
+ RequiresVariantMetaObject = 0x02
+ };
+
QMap<QByteArray, Method> methods;
QMap<QByteArray, Property> properties;
@@ -152,6 +157,8 @@ struct QDBusMetaObjectPrivate
int methodCount, methodData;
int propertyCount, propertyData;
int enumeratorCount, enumeratorData;
+ int constructorCount, constructorData; // since revision 2
+ int flags; // since revision 3
// this is specific for QDBusMetaObject:
int propertyDBusData;
@@ -416,7 +423,7 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
idata.resize(sizeof(QDBusMetaObjectPrivate) / sizeof(int));
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(idata.data());
- header->revision = 1;
+ header->revision = 3;
header->className = 0;
header->classInfoCount = 0;
header->classInfoData = 0;
@@ -426,6 +433,9 @@ void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
header->propertyData = header->methodData + header->methodCount * 5;
header->enumeratorCount = 0;
header->enumeratorData = 0;
+ header->constructorCount = 0;
+ header->constructorData = 0;
+ header->flags = RequiresVariantMetaObject;
header->propertyDBusData = header->propertyData + header->propertyCount * 3;
header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty;
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index 7848bc96f3..d854b1765b 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -97,8 +97,10 @@ static QDataStream &operator<<(QDataStream &s, const BMP_FILEHDR &bf)
const int BMP_OLD = 12; // old Windows/OS2 BMP size
-const int BMP_WIN = 40; // new Windows BMP size
+const int BMP_WIN = 40; // Windows BMP v3 size
const int BMP_OS2 = 64; // new OS/2 BMP size
+const int BMP_WIN4 = 108; // Windows BMP v4 size
+const int BMP_WIN5 = 124; // Windows BMP v5 size
const int BMP_RGB = 0; // no compression
const int BMP_RLE8 = 1; // run-length encoded, 8 bits
@@ -109,7 +111,7 @@ const int BMP_BITFIELDS = 3; // RGB values encoded in dat
static QDataStream &operator>>(QDataStream &s, BMP_INFOHDR &bi)
{
s >> bi.biSize;
- if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2) {
+ if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2 || bi.biSize == BMP_WIN4 || bi.biSize == BMP_WIN5) {
s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
s >> bi.biCompression >> bi.biSizeImage;
s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
@@ -255,7 +257,57 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
image.setDotsPerMeterY(bi.biYPelsPerMeter);
if (!d->isSequential())
- d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap
+ d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+
+ if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) {
+ Q_ASSERT(ncols == 0);
+
+ if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
+ return false;
+ if (d->read((char *)&green_mask, sizeof(green_mask)) != sizeof(green_mask))
+ return false;
+ if (d->read((char *)&blue_mask, sizeof(blue_mask)) != sizeof(blue_mask))
+ return false;
+
+ // Read BMP v4+ header
+ if (bi.biSize >= BMP_WIN4) {
+ int alpha_mask = 0;
+ int CSType = 0;
+ int gamma_red = 0;
+ int gamma_green = 0;
+ int gamma_blue = 0;
+ int endpoints[9];
+
+ if (d->read((char *)&alpha_mask, sizeof(alpha_mask)) != sizeof(alpha_mask))
+ return false;
+ if (d->read((char *)&CSType, sizeof(CSType)) != sizeof(CSType))
+ return false;
+ if (d->read((char *)&endpoints, sizeof(endpoints)) != sizeof(endpoints))
+ return false;
+ if (d->read((char *)&gamma_red, sizeof(gamma_red)) != sizeof(gamma_red))
+ return false;
+ if (d->read((char *)&gamma_green, sizeof(gamma_green)) != sizeof(gamma_green))
+ return false;
+ if (d->read((char *)&gamma_blue, sizeof(gamma_blue)) != sizeof(gamma_blue))
+ return false;
+
+ if (bi.biSize == BMP_WIN5) {
+ qint32 intent = 0;
+ qint32 profileData = 0;
+ qint32 profileSize = 0;
+ qint32 reserved = 0;
+
+ if (d->read((char *)&intent, sizeof(intent)) != sizeof(intent))
+ return false;
+ if (d->read((char *)&profileData, sizeof(profileData)) != sizeof(profileData))
+ return false;
+ if (d->read((char *)&profileSize, sizeof(profileSize)) != sizeof(profileSize))
+ return false;
+ if (d->read((char *)&reserved, sizeof(reserved)) != sizeof(reserved) || reserved != 0)
+ return false;
+ }
+ }
+ }
if (ncols > 0) { // read color table
uchar rgb[4];
@@ -268,12 +320,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
return false;
}
} else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {
- if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
- return false;
- if (d->read((char *)&green_mask, sizeof(green_mask)) != sizeof(green_mask))
- return false;
- if (d->read((char *)&blue_mask, sizeof(blue_mask)) != sizeof(blue_mask))
- return false;
red_shift = calc_shift(red_mask);
red_scale = 256 / ((red_mask >> red_shift) + 1);
green_shift = calc_shift(green_mask);
diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp
index c753b83294..4dc9775d46 100644
--- a/src/gui/image/qtiffhandler.cpp
+++ b/src/gui/image/qtiffhandler.cpp
@@ -236,14 +236,14 @@ bool QTiffHandler::read(QImage *image)
}
} else {
// create the color table
- uint16 *redTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16)));
- uint16 *greenTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16)));
- uint16 *blueTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16)));
- if (!redTable || !greenTable || !blueTable) {
+ uint16 *redTable = 0;
+ uint16 *greenTable = 0;
+ uint16 *blueTable = 0;
+ if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) {
TIFFClose(tiff);
return false;
}
- if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) {
+ if (!redTable || !greenTable || !blueTable) {
TIFFClose(tiff);
return false;
}
@@ -500,6 +500,9 @@ bool QTiffHandler::write(const QImage &image)
uint16 *greenTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16)));
uint16 *blueTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16)));
if (!redTable || !greenTable || !blueTable) {
+ qFree(redTable);
+ qFree(greenTable);
+ qFree(blueTable);
TIFFClose(tiff);
return false;
}
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 837bd519b8..cef92af66b 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -55,6 +55,20 @@ QT_BEGIN_NAMESPACE
\since 4.6
\ingroup painting-3D
+ The QMatrix4x4 class in general is treated as a row-major matrix, in that the
+ constructors and operator() functions take data in row-major format, as is
+ familiar in C-style usage.
+
+ Internally the data is stored as column-major format, so as to be optimal for
+ passing to OpenGL functions, which expect column-major data.
+
+ When using these functions be aware that they return data in \bold{column-major}
+ format:
+ \list
+ \o data()
+ \o constData()
+ \endlist
+
\sa QVector3D, QGenericMatrix
*/
@@ -1725,6 +1739,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
\fn const qreal *QMatrix4x4::data() const
Returns a constant pointer to the raw data of this matrix.
+ This raw data is stored in column-major format.
\sa constData()
*/
@@ -1733,6 +1748,7 @@ QRectF QMatrix4x4::mapRect(const QRectF& rect) const
\fn const qreal *QMatrix4x4::constData() const
Returns a constant pointer to the raw data of this matrix.
+ This raw data is stored in column-major format.
\sa data()
*/
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 908fdf1183..566b4d5f61 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3005,7 +3005,7 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
ensureState();
QFontEngine *fontEngine = textItem->fontEngine();
- if (!supportsTransformations(fontEngine)) {
+ if (shouldDrawCachedGlyphs(fontEngine->fontDef.pixelSize, state()->matrix)) {
drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
fontEngine);
} else {
@@ -3355,10 +3355,7 @@ bool QRasterPaintEngine::supportsTransformations(qreal pixelSize, const QTransfo
#endif
return true;
- if (pixelSize * pixelSize * qAbs(m.determinant()) >= 64 * 64)
- return true;
-
- return false;
+ return !shouldDrawCachedGlyphs(pixelSize, m);
}
/*!
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 9427dd5105..5ef6900cc8 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -53,6 +53,10 @@
QT_BEGIN_NAMESPACE
+#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
+# define QT_MAX_CACHED_GLYPH_SIZE 64
+#endif
+
/*******************************************************************************
*
* class QVectorPath
@@ -1096,4 +1100,10 @@ bool QPaintEngineEx::supportsTransformations(qreal pixelSize, const QTransform &
return false;
}
+bool QPaintEngineEx::shouldDrawCachedGlyphs(qreal pixelSize, const QTransform &m) const
+{
+ return (pixelSize * pixelSize * qAbs(m.determinant())) <
+ QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h
index 604a43133f..d9ab506c94 100644
--- a/src/gui/painting/qpaintengineex_p.h
+++ b/src/gui/painting/qpaintengineex_p.h
@@ -228,6 +228,7 @@ public:
};
virtual uint flags() const {return 0;}
virtual bool supportsTransformations(qreal pixelSize, const QTransform &m) const;
+ virtual bool shouldDrawCachedGlyphs(qreal pixelSize, const QTransform &m) const;
protected:
QPaintEngineEx(QPaintEngineExPrivate &data);
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index 6ae410cada..c53e841cf4 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -155,6 +155,7 @@ public:
struct FaceId {
FaceId() : index(0), encoding(0) {}
QByteArray filename;
+ QByteArray uuid;
int index;
int encoding;
};
@@ -303,7 +304,7 @@ inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId
inline uint qHash(const QFontEngine::FaceId &f)
{
- return qHash((f.index << 16) + f.encoding) + qHash(f.filename);
+ return qHash((f.index << 16) + f.encoding) + qHash(f.filename + f.uuid);
}
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 4c65ad5de0..26b6a8aad7 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -139,7 +139,7 @@ QRawFont::QRawFont()
\note The referenced file must contain a TrueType or OpenType font.
*/
QRawFont::QRawFont(const QString &fileName,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference)
: d(new QRawFontPrivate)
{
@@ -154,7 +154,7 @@ QRawFont::QRawFont(const QString &fileName,
\note The data must contain a TrueType or OpenType font.
*/
QRawFont::QRawFont(const QByteArray &fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference)
: d(new QRawFontPrivate)
{
@@ -204,7 +204,7 @@ bool QRawFont::isValid() const
\sa loadFromData()
*/
void QRawFont::loadFromFile(const QString &fileName,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
QFile file(fileName);
@@ -222,7 +222,7 @@ void QRawFont::loadFromFile(const QString &fileName,
\sa loadFromFile()
*/
void QRawFont::loadFromData(const QByteArray &fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
detach();
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index e94bd99b8c..f7d7494f0b 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -70,10 +70,10 @@ public:
QRawFont();
QRawFont(const QString &fileName,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
QRawFont(const QByteArray &fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
QRawFont(const QRawFont &other);
~QRawFont();
@@ -117,11 +117,11 @@ public:
qreal unitsPerEm() const;
void loadFromFile(const QString &fileName,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference);
void loadFromData(const QByteArray &fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference);
bool supportsCharacter(quint32 ucs4) const;
diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp
index db60459176..1666df3fdf 100644
--- a/src/gui/text/qrawfont_ft.cpp
+++ b/src/gui/text/qrawfont_ft.cpp
@@ -45,6 +45,7 @@
#include "qrawfont_p.h"
#include "qfontengine_ft_p.h"
+#include "quuid.h"
#if defined(Q_WS_X11) && !defined(QT_NO_FONTCONFIG)
# include "qfontengine_x11_p.h"
@@ -87,6 +88,7 @@ public:
FaceId faceId;
faceId.filename = "";
faceId.index = 0;
+ faceId.uuid = QUuid::createUuid().toByteArray();
return init(faceId, true, Format_None, fontData);
}
@@ -98,7 +100,7 @@ void QRawFontPrivate::platformCleanUp()
// Font engine handles all resources
}
-void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_ASSERT(fontEngine == 0);
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
index 56ea6a031d..4a4ed56223 100644
--- a/src/gui/text/qrawfont_p.h
+++ b/src/gui/text/qrawfont_p.h
@@ -99,7 +99,7 @@ public:
void cleanUp();
void platformCleanUp();
void platformLoadFromData(const QByteArray &fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference);
static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); }
diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp
index b80b64cbaf..47815baf06 100644
--- a/src/gui/text/qrawfont_qpa.cpp
+++ b/src/gui/text/qrawfont_qpa.cpp
@@ -53,7 +53,7 @@ void QRawFontPrivate::platformCleanUp()
{
}
-void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize,
+void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
Q_ASSERT(fontEngine == 0);
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 3d7e597f23..689fd4379b 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -1817,6 +1817,7 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
bool isGettingInput = !e->commitString().isEmpty()
|| e->preeditString() != cursor.block().layout()->preeditAreaText()
|| e->replacementLength() > 0;
+ bool forceSelectionChanged = false;
cursor.beginEditBlock();
if (isGettingInput) {
@@ -1840,6 +1841,7 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
cursor.setPosition(blockStart + a.length, QTextCursor::KeepAnchor);
q->ensureCursorVisible();
repaintOldAndNewSelection(oldCursor);
+ forceSelectionChanged = true;
}
}
@@ -1874,6 +1876,7 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
cursor_d->setX();
if (oldPreeditCursor != preeditCursor)
emit q->microFocusChanged();
+ selectionChanged(forceSelectionChanged);
}
QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 5cc3d73fb9..0d3aa0b585 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -1632,7 +1632,7 @@ bool QTextEngine::isRightToLeft() const
int QTextEngine::findItem(int strPos) const
{
itemize();
- int left = 0;
+ int left = 1;
int right = layoutData->items.size()-1;
while(left <= right) {
int middle = ((right-left)/2)+left;
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index b32bea8b7a..43251a8829 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -131,6 +131,69 @@ QT_BEGIN_NAMESPACE
\omitvalue Valid
*/
+
+/*!
+ \fn void QIntValidator::topChanged(int top)
+
+ This signal is emitted after the top property changed.
+
+ \sa QIntValidator::top(), QIntValidator::setTop(), QIntValidator::bottom(), QIntValidator::setBottom()
+ \internal
+*/
+
+/*!
+ \fn void QIntValidator::bottomChanged(int bottom)
+
+ This signal is emitted after the bottom property changed.
+
+ \sa QIntValidator::top(), QIntValidator::setTop(), QIntValidator::bottom(), QIntValidator::setBottom()
+ \internal
+*/
+
+/*!
+ \fn void QDoubleValidator::topChanged(int top)
+
+ This signal is emitted after the top property changed.
+
+ \sa QDoubleValidator::top(), QDoubleValidator::setTop(), QDoubleValidator::bottom(), QDoubleValidator::setBottom()
+ \internal
+*/
+
+/*!
+ \fn void QDoubleValidator::bottomChanged(int bottom)
+
+ This signal is emitted after the bottom property changed.
+
+ \sa QDoubleValidator::top(), QDoubleValidator::setTop(), QDoubleValidator::bottom(), QDoubleValidator::setBottom()
+ \internal
+*/
+
+/*!
+ \fn void QDoubleValidator::decimalsChanged(int decimals)
+
+ This signal is emitted after the decimals property changed.
+
+ \internal
+*/
+
+/*!
+ \fn void QDoubleValidator::notationChanged(QDoubleValidator::Notation notation)
+
+ This signal is emitted after the notation property changed.
+
+ QDoubleValidator::Notation is not a registered metatype, so for queued connections,
+ you will have to register it with Q_DECLARE_METATYPE() and qRegisterMetaType().
+
+ \internal
+*/
+
+/*!
+ \fn void QRegExpValidator::regExpChanged(const QRegExp &regExp)
+
+ This signal is emitted after the regExp property changed.
+ \internal
+*/
+
class QValidatorPrivate : public QObjectPrivate{
Q_DECLARE_PUBLIC(QValidator)
public:
@@ -436,8 +499,15 @@ void QIntValidator::fixup(QString &input) const
void QIntValidator::setRange(int bottom, int top)
{
- b = bottom;
- t = top;
+ if (b != bottom) {
+ b = bottom;
+ emit bottomChanged(b);
+ }
+
+ if (t != top) {
+ t = top;
+ emit topChanged(t);
+ }
}
@@ -710,9 +780,20 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
void QDoubleValidator::setRange(double minimum, double maximum, int decimals)
{
- b = minimum;
- t = maximum;
- dec = decimals;
+ if (b != minimum) {
+ b = minimum;
+ emit bottomChanged(b);
+ }
+
+ if (t != maximum) {
+ t = maximum;
+ emit topChanged(t);
+ }
+
+ if (dec != decimals) {
+ dec = decimals;
+ emit decimalsChanged(dec);
+ }
}
/*!
@@ -771,7 +852,10 @@ void QDoubleValidator::setDecimals(int decimals)
void QDoubleValidator::setNotation(Notation newNotation)
{
Q_D(QDoubleValidator);
- d->notation = newNotation;
+ if (d->notation != newNotation) {
+ d->notation = newNotation;
+ emit notationChanged(d->notation);
+ }
}
QDoubleValidator::Notation QDoubleValidator::notation() const
@@ -915,7 +999,10 @@ QValidator::State QRegExpValidator::validate(QString &input, int& pos) const
void QRegExpValidator::setRegExp(const QRegExp& rx)
{
- r = rx;
+ if (r != rx) {
+ r = rx;
+ emit regExpChanged(r);
+ }
}
#endif
diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h
index 70f656e6a8..cb0436cc3e 100644
--- a/src/gui/util/qvalidator.h
+++ b/src/gui/util/qvalidator.h
@@ -96,8 +96,8 @@ private:
class Q_GUI_EXPORT QIntValidator : public QValidator
{
Q_OBJECT
- Q_PROPERTY(int bottom READ bottom WRITE setBottom)
- Q_PROPERTY(int top READ top WRITE setTop)
+ Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomChanged)
+ Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged)
public:
explicit QIntValidator(QObject * parent = 0);
@@ -113,7 +113,9 @@ public:
int bottom() const { return b; }
int top() const { return t; }
-
+Q_SIGNALS:
+ void bottomChanged(int bottom);
+ void topChanged(int top);
#ifdef QT3_SUPPORT
public:
QT3_SUPPORT_CONSTRUCTOR QIntValidator(QObject * parent, const char *name);
@@ -134,11 +136,11 @@ class QDoubleValidatorPrivate;
class Q_GUI_EXPORT QDoubleValidator : public QValidator
{
Q_OBJECT
- Q_PROPERTY(double bottom READ bottom WRITE setBottom)
- Q_PROPERTY(double top READ top WRITE setTop)
- Q_PROPERTY(int decimals READ decimals WRITE setDecimals)
+ Q_PROPERTY(double bottom READ bottom WRITE setBottom NOTIFY bottomChanged)
+ Q_PROPERTY(double top READ top WRITE setTop NOTIFY topChanged)
+ Q_PROPERTY(int decimals READ decimals WRITE setDecimals NOTIFY decimalsChanged)
Q_ENUMS(Notation)
- Q_PROPERTY(Notation notation READ notation WRITE setNotation)
+ Q_PROPERTY(Notation notation READ notation WRITE setNotation NOTIFY notationChanged)
public:
explicit QDoubleValidator(QObject * parent = 0);
@@ -149,7 +151,6 @@ public:
StandardNotation,
ScientificNotation
};
-
QValidator::State validate(QString &, int &) const;
virtual void setRange(double bottom, double top, int decimals = 0);
@@ -163,6 +164,12 @@ public:
int decimals() const { return dec; }
Notation notation() const;
+Q_SIGNALS:
+ void bottomChanged(double bottom);
+ void topChanged(double top);
+ void decimalsChanged(int decimals);
+ void notationChanged(QDoubleValidator::Notation notation);
+
#ifdef QT3_SUPPORT
public:
QT3_SUPPORT_CONSTRUCTOR QDoubleValidator(QObject * parent, const char *name);
@@ -182,7 +189,7 @@ private:
class Q_GUI_EXPORT QRegExpValidator : public QValidator
{
Q_OBJECT
- Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp)
+ Q_PROPERTY(QRegExp regExp READ regExp WRITE setRegExp NOTIFY regExpChanged)
public:
explicit QRegExpValidator(QObject *parent = 0);
@@ -194,6 +201,8 @@ public:
void setRegExp(const QRegExp& rx);
const QRegExp& regExp() const { return r; } // ### make inline for 5.0
+Q_SIGNALS:
+ void regExpChanged(const QRegExp& regExp);
#ifdef QT3_SUPPORT
public:
QT3_SUPPORT_CONSTRUCTOR QRegExpValidator(QObject *parent, const char *name);
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index ab103ba836..58b9002222 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -97,10 +97,6 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled;
extern bool qt_applefontsmoothing_enabled;
#endif
-#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
-# define QT_MAX_CACHED_GLYPH_SIZE 64
-#endif
-
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
////////////////////////////////// Private Methods //////////////////////////////////////////
@@ -1441,8 +1437,7 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
// don't try to cache huge fonts or vastly transformed fonts
QFontEngine *fontEngine = textItem->fontEngine();
const qreal pixelSize = fontEngine->fontDef.pixelSize;
- if (pixelSize * pixelSize * qAbs(det) < QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE ||
- det < 0.25f || det > 4.f) {
+ if (shouldDrawCachedGlyphs(pixelSize, s->matrix) || det < 0.25f || det > 4.f) {
QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0
? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat)
: d->glyphCacheType;
@@ -1500,8 +1495,7 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem
// don't try to cache huge fonts or vastly transformed fonts
const qreal pixelSize = ti.fontEngine->fontDef.pixelSize;
- if (pixelSize * pixelSize * qAbs(det) >= QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE ||
- det < 0.25f || det > 4.f)
+ if (shouldDrawCachedGlyphs(pixelSize, s->matrix) || det < 0.25f || det > 4.f)
drawCached = false;
QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index 1fd9e373ed..c35488da02 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -347,13 +347,13 @@ static void find_trans_colors()
QGLFormat UNIX/GLX-specific code
*****************************************************************************/
-void* qglx_getProcAddress(const char* procName)
+void (*qglx_getProcAddress(const char* procName))()
{
// On systems where the GL driver is pluggable (like Mesa), we have to use
// the glXGetProcAddressARB extension to resolve other function pointers as
// the symbols wont be in the GL library, but rather in a plugin loaded by
// the GL library.
- typedef void* (*qt_glXGetProcAddressARB)(const char *);
+ typedef void (*(*qt_glXGetProcAddressARB)(const char *))();
static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
static bool triedResolvingGlxGetProcAddress = false;
if (!triedResolvingGlxGetProcAddress) {
@@ -378,7 +378,7 @@ void* qglx_getProcAddress(const char* procName)
}
}
- void *procAddress = 0;
+ void (*procAddress)() = 0;
if (glXGetProcAddressARB)
procAddress = glXGetProcAddressARB(procName);
@@ -387,7 +387,7 @@ void* qglx_getProcAddress(const char* procName)
if (!procAddress) {
void *handle = dlopen(NULL, RTLD_LAZY);
if (handle) {
- procAddress = dlsym(handle, procName);
+ procAddress = (void (*)())dlsym(handle, procName);
dlclose(handle);
}
}
diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp
index 9e8beba311..fcd7b521bb 100644
--- a/src/opengl/qglpixelbuffer_x11.cpp
+++ b/src/opengl/qglpixelbuffer_x11.cpp
@@ -93,7 +93,7 @@ static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0;
#define glXGetFBConfigAttrib qt_glXGetFBConfigAttrib
#define glXMakeContextCurrent qt_glXMakeContextCurrent
-extern void* qglx_getProcAddress(const char* procName); // in qgl_x11.cpp
+extern void (*qglx_getProcAddress(const char* procName))(); // in qgl_x11.cpp
static bool qt_resolve_pbuffer_extensions()
{
diff --git a/src/plugins/platforms/xlib/qxlibstatic.cpp b/src/plugins/platforms/xlib/qxlibstatic.cpp
index ee4c463b94..3ba0eb4c32 100644
--- a/src/plugins/platforms/xlib/qxlibstatic.cpp
+++ b/src/plugins/platforms/xlib/qxlibstatic.cpp
@@ -218,8 +218,8 @@ static const char * x11_atomnames = {
\c XFIXES_MAJOR - it is a part of soname and may differ from the Xfixes
version.
*/
-static void* qt_load_library_runtime(const char *library, int vernum,
- int highestVernum, const char *symbol)
+static QFunctionPointer qt_load_library_runtime(const char *library, int vernum,
+ int highestVernum, const char *symbol)
{
QList<int> versions;
// we try to load in the following order:
@@ -234,7 +234,7 @@ static void* qt_load_library_runtime(const char *library, int vernum,
Q_FOREACH(int version, versions) {
QLatin1String libName(library);
QLibrary xfixesLib(libName, version);
- void *ptr = xfixesLib.resolve(symbol);
+ QFunctionPointer ptr = xfixesLib.resolve(symbol);
if (ptr)
return ptr;
}
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index f6c401842f..5b0406f4b0 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -119,6 +119,8 @@ QT_BEGIN_NAMESPACE
returns false.
*/
+class QRelatedTableModel;
+
struct QRelation
{
public:
@@ -135,7 +137,7 @@ struct QRelation
bool isValid();
QSqlRelation rel;
- QSqlTableModel *model;
+ QRelatedTableModel *model;
QHash<QString, QVariant> dictionary;//maps keys to display values
private:
@@ -143,6 +145,15 @@ struct QRelation
bool m_dictInitialized;
};
+class QRelatedTableModel : public QSqlTableModel
+{
+public:
+ QRelatedTableModel(QRelation *rel, QObject *parent = 0, QSqlDatabase db = QSqlDatabase());
+ bool select();
+private:
+ bool firstSelect;
+ QRelation *relation;
+};
/*
A QRelation must be initialized before it is considered valid.
Note: population of the model and dictionary are kept separate
@@ -162,7 +173,7 @@ void QRelation::populateModel()
Q_ASSERT(m_parent != NULL);
if (!model) {
- model = new QSqlTableModel(m_parent, m_parent->database());
+ model = new QRelatedTableModel(this, m_parent, m_parent->database());
model->setTable(rel.tableName());
model->select();
}
@@ -219,6 +230,27 @@ bool QRelation::isValid()
return (rel.isValid() && m_parent != NULL);
}
+
+
+QRelatedTableModel::QRelatedTableModel(QRelation *rel, QObject *parent, QSqlDatabase db) :
+ QSqlTableModel(parent, db), firstSelect(true), relation(rel)
+{
+}
+
+bool QRelatedTableModel::select()
+{
+ if (firstSelect) {
+ firstSelect = false;
+ return QSqlTableModel::select();
+ }
+ relation->clearDictionary();
+ bool res = QSqlTableModel::select();
+ if (res)
+ relation->populateDictionary();
+ return res;
+}
+
+
class QSqlRelationalTableModelPrivate: public QSqlTableModelPrivate
{
Q_DECLARE_PUBLIC(QSqlRelationalTableModel)
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 435036e0c8..a017d33b4a 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -88,7 +88,7 @@ qpa:mac: {
load(qt_module_config)
-HEADERS += $$QT_SOURCE_TREE/src/testlib/qttestlibversion.h
+HEADERS += $$QT_SOURCE_TREE/src/testlib/qttestversion.h
QMAKE_TARGET_PRODUCT = QTestLib
QMAKE_TARGET_DESCRIPTION = Qt \
diff --git a/src/widgets/platforms/mac/qrawfont_mac.cpp b/src/widgets/platforms/mac/qrawfont_mac.cpp
index df68eb7e7a..40c719a1af 100644
--- a/src/widgets/platforms/mac/qrawfont_mac.cpp
+++ b/src/widgets/platforms/mac/qrawfont_mac.cpp
@@ -55,7 +55,7 @@ void QRawFontPrivate::platformCleanUp()
extern int qt_defaultDpi();
void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
// Mac OS X ignores it
diff --git a/src/widgets/platforms/win/qrawfont_win.cpp b/src/widgets/platforms/win/qrawfont_win.cpp
index 6c62673b54..d8aa557975 100644
--- a/src/widgets/platforms/win/qrawfont_win.cpp
+++ b/src/widgets/platforms/win/qrawfont_win.cpp
@@ -529,7 +529,8 @@ void QRawFontPrivate::platformCleanUp()
{
if (fontHandle != NULL) {
if (ptrRemoveFontMemResourceEx == NULL) {
- void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
+ QFunctionPointer func =
+ QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
ptrRemoveFontMemResourceEx =
reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
}
@@ -545,7 +546,7 @@ void QRawFontPrivate::platformCleanUp()
}
void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
- int pixelSize,
+ qreal pixelSize,
QFont::HintingPreference hintingPreference)
{
QByteArray fontData(_fontData);
@@ -572,7 +573,8 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData,
}
if (ptrAddFontMemResourceEx == NULL || ptrRemoveFontMemResourceEx == NULL) {
- void *func = QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
+ QFunctionPointer func =
+ QSystemLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx");
ptrRemoveFontMemResourceEx =
reinterpret_cast<QRawFontPrivate::PtrRemoveFontMemResourceEx>(func);
diff --git a/src/widgets/platforms/x11/qkeymapper_x11.cpp b/src/widgets/platforms/x11/qkeymapper_x11.cpp
index e243716f6a..455840f8b2 100644
--- a/src/widgets/platforms/x11/qkeymapper_x11.cpp
+++ b/src/widgets/platforms/x11/qkeymapper_x11.cpp
@@ -513,7 +513,7 @@ void QKeyMapperPrivate::clearMappings()
// ### ???
// if (keyboardLayoutName.isEmpty())
- // qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ?
+ // qWarning("Qt: unable to determine keyboard layout, please talk to qt-info@nokia.com"); ?
keyboardInputLocale = q_getKeyboardLocale(layoutName, variantName);
keyboardInputDirection = keyboardInputLocale.textDirection();
diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h
index 447560f332..899b7a5dba 100644
--- a/src/widgets/widgets/qtabwidget.h
+++ b/src/widgets/widgets/qtabwidget.h
@@ -148,6 +148,8 @@ public:
void clear();
+ QTabBar* tabBar() const;
+
public Q_SLOTS:
void setCurrentIndex(int index);
void setCurrentWidget(QWidget *widget);
@@ -165,7 +167,6 @@ protected:
void keyPressEvent(QKeyEvent *);
void paintEvent(QPaintEvent *);
void setTabBar(QTabBar *);
- QTabBar* tabBar() const;
void changeEvent(QEvent *);
bool event(QEvent *);
void initStyleOption(QStyleOptionTabWidgetFrame *option) const;
diff --git a/src/winmain/winmain.pro b/src/winmain/winmain.pro
index b353e8e382..6630d86326 100644
--- a/src/winmain/winmain.pro
+++ b/src/winmain/winmain.pro
@@ -1,7 +1,6 @@
# Additional Qt project file for qtmain lib on Windows
TEMPLATE = lib
TARGET = qtmain
-DESTDIR = $$QMAKE_LIBDIR_QT
QT =
CONFIG += staticlib warn_on
@@ -17,5 +16,6 @@ win32 {
!win32:error("$$_FILE_ is intended only for Windows!")
load(qt_module_config)
+DESTDIR = $$QMAKE_LIBDIR_QT
wince*:QMAKE_POST_LINK =
diff --git a/tests/auto/corelib.pro b/tests/auto/corelib.pro
index 95a16f67d9..7a655d6208 100644
--- a/tests/auto/corelib.pro
+++ b/tests/auto/corelib.pro
@@ -30,6 +30,7 @@ SUBDIRS=\
qfileinfo \
qfilesystemwatcher \
qflags \
+ qfreelist \
qfuture \
qfuturewatcher \
qgetputenv \
diff --git a/tests/auto/moc/moc.pro b/tests/auto/moc/moc.pro
index 59106aa11d..056c6b0958 100644
--- a/tests/auto/moc/moc.pro
+++ b/tests/auto/moc/moc.pro
@@ -26,5 +26,3 @@ contains(QT_CONFIG, dbus){
QT += dbus
}
-CONFIG+=insignificant_test
-
diff --git a/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro b/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro
index 6f5044f6bb..4dea3c9c8c 100644
--- a/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro
+++ b/tests/auto/qabstractnetworkcache/qabstractnetworkcache.pro
@@ -10,3 +10,5 @@ wince*|symbian: {
}
symbian: TARGET.CAPABILITY = NetworkServices
+
+CONFIG += insignificant_test # QTBUG-20686; note, assumed unstable on all platforms
diff --git a/tests/auto/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/qcoreapplication/tst_qcoreapplication.cpp
index 0b581af77b..99f0941ac2 100644
--- a/tests/auto/qcoreapplication/tst_qcoreapplication.cpp
+++ b/tests/auto/qcoreapplication/tst_qcoreapplication.cpp
@@ -361,26 +361,25 @@ class DeliverInDefinedOrderObject : public QObject
QPointer<QThread> thread;
int count;
+ int startCount;
+ int loopLevel;
public:
DeliverInDefinedOrderObject(QObject *parent)
- : QObject(parent), thread(0), count(0)
+ : QObject(parent), thread(0), count(0), startCount(0), loopLevel(0)
{ }
- ~DeliverInDefinedOrderObject()
- {
- if (!thread.isNull())
- thread->wait();
- }
+
+signals:
+ void done();
public slots:
- void start()
+ void startThread()
{
QVERIFY(!thread);
thread = new DeliverInDefinedOrderThread();
connect(thread, SIGNAL(progress(int)), this, SLOT(threadProgress(int)));
connect(thread, SIGNAL(finished()), this, SLOT(threadFinished()));
- connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- connect(thread, SIGNAL(destroyed()), this, SLOT(start()));
+ connect(thread, SIGNAL(destroyed()), this, SLOT(threadDestroyed()));
thread->start();
QCoreApplication::postEvent(this, new QEvent(QEvent::MaxUser), -1);
@@ -398,21 +397,34 @@ public slots:
{
QVERIFY(count == 7);
count = 0;
+ thread->deleteLater();
QCoreApplication::postEvent(this, new QEvent(QEvent::MaxUser), -1);
}
+ void threadDestroyed()
+ {
+ if (++startCount < 20)
+ startThread();
+ else
+ emit done();
+ }
+
public:
bool event(QEvent *event)
{
switch (event->type()) {
case QEvent::User:
- {
- (void) QEventLoop().exec();
- break;
+ {
+ ++loopLevel;
+ if (loopLevel == 2) {
+ // Ready. Starts a thread that emits (queued) signals, which should be handled in order
+ startThread();
}
- case QEvent::User + 1:
+ QCoreApplication::postEvent(this, new QEvent(QEvent::MaxUser), -1);
+ (void) QEventLoop().exec();
break;
+ }
default:
break;
}
@@ -430,11 +442,8 @@ void tst_QCoreApplication::deliverInDefinedOrder()
// causes sendPostedEvents() to recurse twice
QCoreApplication::postEvent(&obj, new QEvent(QEvent::User));
QCoreApplication::postEvent(&obj, new QEvent(QEvent::User));
- // starts a thread that emits (queued) signals, which should be handled in order
- obj.start();
- // run for 15 seconds
- QTimer::singleShot(15000, &app, SLOT(quit()));
+ QObject::connect(&obj, SIGNAL(done()), &app, SLOT(quit()));
app.exec();
}
#endif // QT_NO_QTHREAD
@@ -524,7 +533,7 @@ void tst_QCoreApplication::processEventsAlwaysSendsPostedEvents()
QCoreApplication::processEvents();
QCOMPARE(object.counter, i);
++i;
- } while (t.elapsed() < 3000);
+ } while (t.elapsed() < 1000);
}
void tst_QCoreApplication::reexec()
diff --git a/tests/auto/qdialog/qdialog.pro b/tests/auto/qdialog/qdialog.pro
index 0d59590117..7c4defacd9 100644
--- a/tests/auto/qdialog/qdialog.pro
+++ b/tests/auto/qdialog/qdialog.pro
@@ -1,6 +1,3 @@
load(qttest_p4)
QT += widgets
SOURCES += tst_qdialog.cpp
-
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qdialog/tst_qdialog.cpp b/tests/auto/qdialog/tst_qdialog.cpp
index 6d9f7988cd..86dde21ba0 100644
--- a/tests/auto/qdialog/tst_qdialog.cpp
+++ b/tests/auto/qdialog/tst_qdialog.cpp
@@ -467,6 +467,22 @@ void tst_QDialog::throwInExec()
#if defined(Q_WS_MAC) || (defined(Q_WS_WINCE) && defined(_ARM_))
QSKIP("Throwing exceptions in exec() is not supported on this platform.", SkipAll);
#endif
+
+#if defined(Q_OS_LINUX)
+ // C++ exceptions can't be passed through glib callbacks. Skip the test if
+ // we're using the glib event loop.
+ QByteArray dispatcher = QAbstractEventDispatcher::instance()->metaObject()->className();
+ if (dispatcher.contains("Glib")) {
+ QSKIP(
+ qPrintable(QString(
+ "Throwing exceptions in exec() won't work if %1 event dispatcher is used.\n"
+ "Try running with QT_NO_GLIB=1 in environment."
+ ).arg(QString::fromLatin1(dispatcher))),
+ SkipAll
+ );
+ }
+#endif
+
int caughtExceptions = 0;
try {
ExceptionDialog dialog;
diff --git a/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp
index 76d4494a39..6014ce5165 100644
--- a/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp
+++ b/tests/auto/qdoublevalidator/tst_qdoublevalidator.cpp
@@ -55,6 +55,7 @@ private slots:
void validateThouSep();
void validateIntEquiv_data();
void validateIntEquiv();
+ void notifySignals();
};
Q_DECLARE_METATYPE(QValidator::State);
@@ -244,6 +245,62 @@ void tst_QDoubleValidator::validate()
dv.setNotation(QDoubleValidator::StandardNotation);
QCOMPARE((int)dv.validate(value, dummy), (int)standard_state);
}
+void tst_QDoubleValidator::notifySignals()
+{
+ QDoubleValidator dv(0.1, 0.9, 10, 0);
+ QSignalSpy topSpy(&dv, SIGNAL(topChanged(double)));
+ QSignalSpy bottomSpy(&dv, SIGNAL(bottomChanged(double)));
+ QSignalSpy decSpy(&dv, SIGNAL(decimalsChanged(int)));
+
+ qRegisterMetaType<QDoubleValidator::Notation>("QDoubleValidator::Notation");
+ QSignalSpy notSpy(&dv, SIGNAL(notationChanged(QDoubleValidator::Notation)));
+
+ dv.setTop(0.8);
+ QCOMPARE(topSpy.count(), 1);
+ QVERIFY(dv.top() == 0.8);
+ dv.setBottom(0.2);
+ QCOMPARE(bottomSpy.count(), 1);
+ QVERIFY(dv.bottom() == 0.2);
+
+ dv.setRange(0.2, 0.7);
+ QCOMPARE(topSpy.count(), 2);
+ QCOMPARE(bottomSpy.count(), 1);
+ QCOMPARE(decSpy.count(), 1);
+ QVERIFY(dv.bottom() == 0.2);
+ QVERIFY(dv.top() == 0.7);
+ QVERIFY(dv.decimals() == 0.);
+
+ dv.setRange(0.3, 0.7);
+ QCOMPARE(topSpy.count(), 2);
+ QCOMPARE(bottomSpy.count(), 2);
+ QVERIFY(dv.bottom() == 0.3);
+ QVERIFY(dv.top() == 0.7);
+ QVERIFY(dv.decimals() == 0.);
+
+ dv.setRange(0.4, 0.6);
+ QCOMPARE(topSpy.count(), 3);
+ QCOMPARE(bottomSpy.count(), 3);
+ QVERIFY(dv.bottom() == 0.4);
+ QVERIFY(dv.top() == 0.6);
+ QVERIFY(dv.decimals() == 0.);
+
+ dv.setDecimals(10);
+ QCOMPARE(decSpy.count(), 2);
+ QVERIFY(dv.decimals() == 10.);
+
+
+ dv.setRange(0.4, 0.6, 100);
+ QCOMPARE(topSpy.count(), 3);
+ QCOMPARE(bottomSpy.count(), 3);
+ QCOMPARE(decSpy.count(), 3);
+ QVERIFY(dv.bottom() == 0.4);
+ QVERIFY(dv.top() == 0.6);
+ QVERIFY(dv.decimals() == 100.);
+
+ dv.setNotation(QDoubleValidator::StandardNotation);
+ QCOMPARE(notSpy.count(), 1);
+ QVERIFY(dv.notation() == QDoubleValidator::StandardNotation);
+}
void tst_QDoubleValidator::validateIntEquiv_data()
{
diff --git a/tests/auto/qfile/test/test.pro b/tests/auto/qfile/test/test.pro
index 0f211b9de5..f4ec12f874 100644
--- a/tests/auto/qfile/test/test.pro
+++ b/tests/auto/qfile/test/test.pro
@@ -41,4 +41,4 @@ symbian {
LIBS+=-lefsrv
}
-CONFIG+=insignificant_test
+mac*:CONFIG+=insignificant_test
diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp
index 4a78876843..aafe79484e 100644
--- a/tests/auto/qfile/tst_qfile.cpp
+++ b/tests/auto/qfile/tst_qfile.cpp
@@ -2438,7 +2438,7 @@ void tst_QFile::rename_data()
QTest::newRow("a -> b") << QString("a") << QString("b") << false;
QTest::newRow("a -> .") << QString("a") << QString(".") << false;
QTest::newRow("renamefile -> renamefile") << QString("renamefile") << QString("renamefile") << false;
- QTest::newRow("renamefile -> Makefile") << QString("renamefile") << QString("Makefile") << false;
+ QTest::newRow("renamefile -> noreadfile") << QString("renamefile") << QString("noreadfile") << false;
#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
QTest::newRow("renamefile -> /etc/renamefile") << QString("renamefile") << QString("/etc/renamefile") << false;
#endif
diff --git a/tests/auto/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/qfilesystemmodel/qfilesystemmodel.pro
index 5c97761b99..b0b6d7a18d 100644
--- a/tests/auto/qfilesystemmodel/qfilesystemmodel.pro
+++ b/tests/auto/qfilesystemmodel/qfilesystemmodel.pro
@@ -15,5 +15,3 @@ symbian: {
DEPLOYMENT += dummyDeploy
LIBS += -lefsrv
}
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
index c2b3e7c521..a9a4fc7fc3 100644
--- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -909,12 +909,16 @@ void tst_QFileSystemModel::sort()
expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + "." << dirPath + QChar('/') + "..";
//File dialog Mode means sub trees are not sorted, only the current root
if (fileDialogMode) {
+ // FIXME: we were only able to disableRecursiveSort in developer builds, so we can only
+ // stably perform this test for developer builds
+#ifdef QT_BUILD_INTERNAL
QList<QString> actualRows;
for(int i = 0; i < myModel->rowCount(parent); ++i)
{
actualRows << dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString();
}
QVERIFY(actualRows != expectedOrder);
+#endif
} else {
for(int i = 0; i < myModel->rowCount(parent); ++i)
{
diff --git a/tests/auto/qfreelist/qfreelist.pro b/tests/auto/qfreelist/qfreelist.pro
new file mode 100644
index 0000000000..b7f2b3d38f
--- /dev/null
+++ b/tests/auto/qfreelist/qfreelist.pro
@@ -0,0 +1,6 @@
+load(qttest_p4)
+SOURCES += tst_qfreelist.cpp
+QT += core-private
+QT -= gui
+
+!private_tests:SOURCES += $$QT_SOURCE_TREE/src/corelib/tools/qfreelist.cpp
diff --git a/tests/auto/qfreelist/tst_qfreelist.cpp b/tests/auto/qfreelist/tst_qfreelist.cpp
new file mode 100644
index 0000000000..139d76e64a
--- /dev/null
+++ b/tests/auto/qfreelist/tst_qfreelist.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QList>
+#include <QtCore/QThread>
+#include <private/qfreelist_p.h>
+#include <QtTest/QtTest>
+
+//TESTED_CLASS=QFreeList
+//TESTED_FILES=corelib/tools/qfreelist_p.h
+
+class tst_QFreeList : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void basicTest();
+ void customized();
+ void threadedTest();
+};
+
+void tst_QFreeList::basicTest()
+{
+ {
+ QFreeList<void> voidFreeList;
+ int zero = voidFreeList.next();
+ int one = voidFreeList.next();
+ int two = voidFreeList.next();
+ QCOMPARE(zero, 0);
+ QCOMPARE(one, 1);
+ QCOMPARE(two, 2);
+ voidFreeList[zero];
+ voidFreeList[one];
+ voidFreeList[two];
+ voidFreeList.at(zero);
+ voidFreeList.at(one);
+ voidFreeList.at(two);
+ voidFreeList.release(one);
+ int next = voidFreeList.next();
+ QCOMPARE(next, 1);
+ voidFreeList[next];
+ voidFreeList.at(next);
+ }
+
+ {
+ QFreeList<int> intFreeList;
+ int zero = intFreeList.next();
+ int one = intFreeList.next();
+ int two = intFreeList.next();
+ QCOMPARE(zero, 0);
+ QCOMPARE(one, 1);
+ QCOMPARE(two, 2);
+ intFreeList[zero] = zero;
+ intFreeList[one] = one;
+ intFreeList[two] = two;
+ QCOMPARE(intFreeList.at(zero), zero);
+ QCOMPARE(intFreeList.at(one), one);
+ QCOMPARE(intFreeList.at(two), two);
+ intFreeList.release(one);
+ int next = intFreeList.next();
+ QCOMPARE(next, 1);
+ QCOMPARE(intFreeList.at(next), one);
+ intFreeList[next] = -one;
+ QCOMPARE(intFreeList.at(next), -one);
+ }
+}
+
+struct CustomFreeListConstants : public QFreeListDefaultConstants
+{
+ enum {
+ InitialNextValue = 50,
+ BlockCount = 10
+ };
+
+ static const int Sizes[10];
+};
+
+const int CustomFreeListConstants::Sizes[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 16777216 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 };
+
+void tst_QFreeList::customized()
+{
+ QFreeList<void, CustomFreeListConstants> customFreeList;
+ int next = customFreeList.next();
+ QCOMPARE(next, int(CustomFreeListConstants::InitialNextValue));
+ customFreeList[next];
+ customFreeList.at(next);
+ customFreeList.release(next);
+}
+
+enum { TimeLimit = 3000 };
+
+class FreeListThread : public QThread
+{
+ static QFreeList<void> freelist;
+
+public:
+ inline FreeListThread() : QThread() { }
+ inline void run()
+ {
+ QElapsedTimer t;
+ t.start();
+ QList<int> needToRelease;
+ do {
+ int i = freelist.next();
+ int j = freelist.next();
+ int k = freelist.next();
+ int l = freelist.next();
+ freelist.release(k);
+ int n = freelist.next();
+ int m = freelist.next();
+ freelist.release(l);
+ freelist.release(m);
+ freelist.release(n);
+ freelist.release(j);
+ // freelist.release(i);
+ needToRelease << i;
+ } while (t.elapsed() < TimeLimit);
+
+ foreach (int x, needToRelease)
+ freelist.release(x);
+ }
+};
+
+QFreeList<void> FreeListThread::freelist;
+
+void tst_QFreeList::threadedTest()
+{
+ const int ThreadCount = QThread::idealThreadCount();
+ FreeListThread *threads = new FreeListThread[ThreadCount];
+ for (int i = 0; i < ThreadCount; ++i)
+ threads[i].start();
+ for (int i = 0; i < ThreadCount; ++i)
+ threads[i].wait();
+ delete [] threads;
+}
+
+QTEST_MAIN(tst_QFreeList)
+#include "tst_qfreelist.moc"
diff --git a/tests/auto/qftp/qftp.pro b/tests/auto/qftp/qftp.pro
index 42c700e72e..69f89572ba 100644
--- a/tests/auto/qftp/qftp.pro
+++ b/tests/auto/qftp/qftp.pro
@@ -18,5 +18,3 @@ wince*: {
} else {
DEFINES += SRCDIR=\\\"$$PWD/\\\"
}
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qftp/tst_qftp.cpp b/tests/auto/qftp/tst_qftp.cpp
index 62b454099b..e31b5acda3 100644
--- a/tests/auto/qftp/tst_qftp.cpp
+++ b/tests/auto/qftp/tst_qftp.cpp
@@ -378,6 +378,8 @@ void tst_QFtp::connectToUnresponsiveHost()
a lot of other stuff in QFtp, so we just expect this test to fail on Windows.
*/
QEXPECT_FAIL("", "timeout not working due to strange Windows socket behaviour (see source file of this test for explanation)", Abort);
+#else
+ QEXPECT_FAIL("", "QTBUG-20687", Abort);
#endif
QVERIFY2(! QTestEventLoop::instance().timeout(), "Network timeout longer than expected (should have been 60 seconds)");
diff --git a/tests/auto/qglobal/tst_qglobal.cpp b/tests/auto/qglobal/tst_qglobal.cpp
index 841151efc4..19a13f6ad0 100644
--- a/tests/auto/qglobal/tst_qglobal.cpp
+++ b/tests/auto/qglobal/tst_qglobal.cpp
@@ -130,10 +130,12 @@ void tst_QGlobal::qInternalCallbacks()
QInternal::unregisterCallback(QInternal::DisconnectCallback, disconnect_callback);
connect_info.reset();
+ QTest::ignoreMessage(QtWarningMsg, "Object::connect: No such signal QObject::mysignal(x)");
ok = QObject::connect(&a, signal.toLatin1(), &b, slot.toLatin1(), Qt::AutoConnection);
QVERIFY(!ok);
QCOMPARE(connect_info.sender, (QObject *) 0);
+ QTest::ignoreMessage(QtWarningMsg, "Object::disconnect: No such signal QObject::mysignal(x)");
ok = QObject::disconnect(&a, signal.toLatin1(), &b, slot.toLatin1());
QVERIFY(!ok);
QCOMPARE(connect_info.sender, (QObject *) 0);
diff --git a/tests/auto/qgraphicstransform/qgraphicstransform.pro b/tests/auto/qgraphicstransform/qgraphicstransform.pro
index 57cbb0e5bd..4f9d001717 100644
--- a/tests/auto/qgraphicstransform/qgraphicstransform.pro
+++ b/tests/auto/qgraphicstransform/qgraphicstransform.pro
@@ -2,5 +2,3 @@ load(qttest_p4)
QT += widgets
SOURCES += tst_qgraphicstransform.cpp
CONFIG += parallel_test
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp
index f229ee7d5f..7b928909ff 100644
--- a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp
+++ b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp
@@ -61,6 +61,9 @@ private slots:
void rotation3d();
void rotation3dArbitraryAxis_data();
void rotation3dArbitraryAxis();
+
+private:
+ QString toString(QTransform const&);
};
@@ -305,6 +308,15 @@ void tst_QGraphicsTransform::rotation3d()
QVERIFY(transform2D(rotation).isIdentity());
}
+QByteArray labelForTest(QVector3D const& axis, int angle) {
+ return QString("rotation of %1 on (%2, %3, %4)")
+ .arg(angle)
+ .arg(axis.x())
+ .arg(axis.y())
+ .arg(axis.z())
+ .toLatin1();
+}
+
void tst_QGraphicsTransform::rotation3dArbitraryAxis_data()
{
QTest::addColumn<QVector3D>("axis");
@@ -317,11 +329,11 @@ void tst_QGraphicsTransform::rotation3dArbitraryAxis_data()
QVector3D axis5 = QVector3D(0.01f, 0.01f, 0.01f);
for (int angle = 0; angle <= 360; angle++) {
- QTest::newRow("test rotation on (1, 1, 1)") << axis1 << qreal(angle);
- QTest::newRow("test rotation on (2, -3, .5)") << axis2 << qreal(angle);
- QTest::newRow("test rotation on (-2, 0, -.5)") << axis3 << qreal(angle);
- QTest::newRow("test rotation on (.0001, .0001, .0001)") << axis4 << qreal(angle);
- QTest::newRow("test rotation on (.01, .01, .01)") << axis5 << qreal(angle);
+ QTest::newRow(labelForTest(axis1, angle).constData()) << axis1 << qreal(angle);
+ QTest::newRow(labelForTest(axis2, angle).constData()) << axis2 << qreal(angle);
+ QTest::newRow(labelForTest(axis3, angle).constData()) << axis3 << qreal(angle);
+ QTest::newRow(labelForTest(axis4, angle).constData()) << axis4 << qreal(angle);
+ QTest::newRow(labelForTest(axis5, angle).constData()) << axis5 << qreal(angle);
}
}
@@ -347,7 +359,26 @@ void tst_QGraphicsTransform::rotation3dArbitraryAxis()
exp.rotate(angle, axis);
QTransform expected = exp.toTransform(1024.0f);
- QVERIFY(fuzzyCompare(transform2D(rotation), expected));
+#ifdef Q_OS_LINUX
+ // These failures possibly relate to the float vs qreal issue mentioned
+ // in the comment above fuzzyCompare().
+ if (sizeof(qreal) == sizeof(double)) {
+ QEXPECT_FAIL("rotation of 120 on (1, 1, 1)", "QTBUG-20661", Abort);
+ QEXPECT_FAIL("rotation of 240 on (1, 1, 1)", "QTBUG-20661", Abort);
+ QEXPECT_FAIL("rotation of 120 on (0.01, 0.01, 0.01)", "QTBUG-20661", Abort);
+ QEXPECT_FAIL("rotation of 240 on (0.01, 0.01, 0.01)", "QTBUG-20661", Abort);
+ QEXPECT_FAIL("rotation of 120 on (0.0001, 0.0001, 0.0001)", "QTBUG-20661", Abort);
+ QEXPECT_FAIL("rotation of 240 on (0.0001, 0.0001, 0.0001)", "QTBUG-20661", Abort);
+ }
+#endif
+
+ QTransform actual = transform2D(rotation);
+ QVERIFY2(fuzzyCompare(actual, expected), qPrintable(
+ QString("\nactual: %1\n"
+ "expected: %2")
+ .arg(toString(actual))
+ .arg(toString(expected))
+ ));
// Check that "rotation" produces the 4x4 form of the 3x3 matrix.
// i.e. third row and column are 0 0 1 0.
@@ -357,6 +388,21 @@ void tst_QGraphicsTransform::rotation3dArbitraryAxis()
QVERIFY(qFuzzyCompare(t, r));
}
+QString tst_QGraphicsTransform::toString(QTransform const& t)
+{
+ return QString("[ [ %1 %2 %3 ]; [ %4 %5 %6 ]; [ %7 %8 %9 ] ]")
+ .arg(t.m11())
+ .arg(t.m12())
+ .arg(t.m13())
+ .arg(t.m21())
+ .arg(t.m22())
+ .arg(t.m23())
+ .arg(t.m31())
+ .arg(t.m32())
+ .arg(t.m33())
+ ;
+}
+
QTEST_MAIN(tst_QGraphicsTransform)
#include "tst_qgraphicstransform.moc"
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index 196519096c..d6bc8ff3e8 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -104,6 +104,7 @@ static void sendMouseMove(QWidget *widget, const QPoint &point, Qt::MouseButton
QTest::mouseMove(widget, point);
QMouseEvent event(QEvent::MouseMove, point, button, buttons, 0);
QApplication::sendEvent(widget, &event);
+ QApplication::processEvents();
}
static void sendMouseRelease(QWidget *widget, const QPoint &point, Qt::MouseButton button = Qt::LeftButton)
diff --git a/tests/auto/qicon/qicon.pro b/tests/auto/qicon/qicon.pro
index aea7b9db64..cc87fae539 100644
--- a/tests/auto/qicon/qicon.pro
+++ b/tests/auto/qicon/qicon.pro
@@ -28,5 +28,3 @@ wince* {
} else {
DEFINES += SRCDIR=\\\"$$PWD\\\"
}
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qicon/tst_qicon.cpp b/tests/auto/qicon/tst_qicon.cpp
index cd3f84f4b0..4c430f9435 100644
--- a/tests/auto/qicon/tst_qicon.cpp
+++ b/tests/auto/qicon/tst_qicon.cpp
@@ -41,7 +41,7 @@
#include <QtTest/QtTest>
-
+#include <QImageReader>
#include <qicon.h>
#if defined(Q_OS_SYMBIAN)
@@ -87,6 +87,8 @@ private slots:
void task239461_custom_iconengine_crash();
private:
+ bool haveImageFormat(QByteArray const&);
+
QString oldCurrentDir;
const static QIcon staticIcon;
@@ -112,6 +114,11 @@ void tst_QIcon::cleanup()
}
}
+bool tst_QIcon::haveImageFormat(QByteArray const& desiredFormat)
+{
+ return QImageReader::supportedImageFormats().contains(desiredFormat);
+}
+
tst_QIcon::tst_QIcon()
{
}
@@ -205,6 +212,10 @@ void tst_QIcon::actualSize2()
void tst_QIcon::svgActualSize()
{
+ if (!haveImageFormat("svg")) {
+ QSKIP("SVG support is not available", SkipAll);
+ }
+
const QString prefix = QLatin1String(SRCDIR) + QLatin1String("/");
QIcon icon(prefix + "rect.svg");
QCOMPARE(icon.actualSize(QSize(16, 16)), QSize(16, 2));
@@ -415,6 +426,9 @@ void tst_QIcon::detach()
void tst_QIcon::svg()
{
+ if (!haveImageFormat("svg")) {
+ QSKIP("SVG support is not available", SkipAll);
+ }
QIcon icon1("heart.svg");
QVERIFY(!icon1.pixmap(32).isNull());
@@ -521,14 +535,14 @@ void tst_QIcon::availableSizes()
QCOMPARE(availableSizes.at(0), QSize(16,16));
}
- {
+ if (haveImageFormat("svg")) {
// checks that there are no availableSizes for scalable images.
QIcon icon("heart.svg");
QList<QSize> availableSizes = icon.availableSizes();
QVERIFY(availableSizes.isEmpty());
}
- {
+ if (haveImageFormat("svg")) {
// even if an a scalable image contain added pixmaps,
// availableSizes still should be empty.
QIcon icon("heart.svg");
diff --git a/tests/auto/qimagereader/images/test32bfv4.bmp b/tests/auto/qimagereader/images/test32bfv4.bmp
new file mode 100644
index 0000000000..37060373ed
--- /dev/null
+++ b/tests/auto/qimagereader/images/test32bfv4.bmp
Binary files differ
diff --git a/tests/auto/qimagereader/images/test32v5.bmp b/tests/auto/qimagereader/images/test32v5.bmp
new file mode 100644
index 0000000000..8ad3cfa60d
--- /dev/null
+++ b/tests/auto/qimagereader/images/test32v5.bmp
Binary files differ
diff --git a/tests/auto/qimagereader/qimagereader.pro b/tests/auto/qimagereader/qimagereader.pro
index 34ec607570..43d587ea48 100644
--- a/tests/auto/qimagereader/qimagereader.pro
+++ b/tests/auto/qimagereader/qimagereader.pro
@@ -5,12 +5,6 @@ QT += widgets widgets-private core-private gui-private network
RESOURCES += qimagereader.qrc
!symbian:DEFINES += SRCDIR=\\\"$$PWD\\\"
-!contains(QT_CONFIG, no-gif):DEFINES += QTEST_HAVE_GIF
-!contains(QT_CONFIG, no-jpeg):DEFINES += QTEST_HAVE_JPEG
-!contains(QT_CONFIG, no-mng):DEFINES += QTEST_HAVE_MNG
-!contains(QT_CONFIG, no-tiff):DEFINES += QTEST_HAVE_TIFF
-!contains(QT_CONFIG, no-svg):DEFINES += QTEST_HAVE_SVG
-
win32-msvc:QMAKE_CXXFLAGS -= -Zm200
win32-msvc:QMAKE_CXXFLAGS += -Zm800
win32-msvc.net:QMAKE_CXXFLAGS -= -Zm300
@@ -40,5 +34,3 @@ symbian: {
DEPLOYMENT += imagePlugins
}
}
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qimagereader/qimagereader.qrc b/tests/auto/qimagereader/qimagereader.qrc
index 632b73abb0..2c70652389 100644
--- a/tests/auto/qimagereader/qimagereader.qrc
+++ b/tests/auto/qimagereader/qimagereader.qrc
@@ -42,6 +42,8 @@
<file>images/teapot.ppm</file>
<file>images/test.ppm</file>
<file>images/test.xpm</file>
+ <file>images/test32bfv4.bmp</file>
+ <file>images/test32v5.bmp</file>
<file>images/tst7.bmp</file>
<file>images/tst7.png</file>
<file>images/transparent.xpm</file>
diff --git a/tests/auto/qimagereader/tst_qimagereader.cpp b/tests/auto/qimagereader/tst_qimagereader.cpp
index 5c65cb3044..6359468597 100644
--- a/tests/auto/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/qimagereader/tst_qimagereader.cpp
@@ -143,12 +143,10 @@ private slots:
void imageFormatBeforeRead_data();
void imageFormatBeforeRead();
-#if defined QTEST_HAVE_GIF
void gifHandlerBugs();
void animatedGif();
void gifImageCount();
void gifLoopCount();
-#endif
void readCorruptImage_data();
void readCorruptImage();
@@ -157,7 +155,6 @@ private slots:
void supportsOption_data();
void supportsOption();
-#if defined QTEST_HAVE_TIFF
void tiffCompression_data();
void tiffCompression();
void tiffEndianness();
@@ -166,7 +163,6 @@ private slots:
void tiffOrientation();
void tiffGrayscale();
-#endif
void autoDetectImageFormat();
void fileNameProbing();
@@ -192,6 +188,12 @@ private slots:
static const QLatin1String prefix(SRCDIR "/images/");
+// helper to skip an autotest when the given image format is not supported
+#define SKIP_IF_UNSUPPORTED(format) do { \
+ if (!QByteArray(format).isEmpty() && !QImageReader::supportedImageFormats().contains(format)) \
+ QSKIP("\"" + QByteArray(format) + "\" images are not supported", SkipSingle); \
+} while (0)
+
// Testing get/set functions
void tst_QImageReader::getSetCheck()
{
@@ -234,6 +236,8 @@ void tst_QImageReader::readImage_data()
QTest::newRow("empty") << QString() << false << QByteArray();
QTest::newRow("BMP: colorful") << QString("colorful.bmp") << true << QByteArray("bmp");
+ QTest::newRow("BMP: test32bfv4") << QString("test32bfv4.bmp") << true << QByteArray("bmp");
+ QTest::newRow("BMP: test32v5") << QString("test32v5.bmp") << true << QByteArray("bmp");
QTest::newRow("BMP: font") << QString("font.bmp") << true << QByteArray("bmp");
QTest::newRow("BMP: signed char") << QString("crash-signed-char.bmp") << true << QByteArray("bmp");
QTest::newRow("BMP: 4bpp RLE") << QString("4bpp-rle.bmp") << true << QByteArray("bmp");
@@ -247,22 +251,17 @@ void tst_QImageReader::readImage_data()
QTest::newRow("PPM: test") << QString("test.ppm") << true << QByteArray("ppm");
QTest::newRow("XBM: gnus") << QString("gnus.xbm") << true << QByteArray("xbm");
-#if defined QTEST_HAVE_JPEG
QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << true << QByteArray("jpeg");
QTest::newRow("JPEG: qtbug13653") << QString("qtbug13653-no_eoi.jpg") << true << QByteArray("jpeg");
-#endif
-#if defined QTEST_HAVE_GIF
+
QTest::newRow("GIF: earth") << QString("earth.gif") << true << QByteArray("gif");
QTest::newRow("GIF: trolltech") << QString("trolltech.gif") << true << QByteArray("gif");
-#endif
-#if defined QTEST_HAVE_MNG
+
QTest::newRow("MNG: ball") << QString("ball.mng") << true << QByteArray("mng");
QTest::newRow("MNG: fire") << QString("fire.mng") << true << QByteArray("mng");
-#endif
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("SVG: rect") << QString("rect.svg") << true << QByteArray("svg");
QTest::newRow("SVGZ: rect") << QString("rect.svgz") << true << QByteArray("svgz");
-#endif
}
void tst_QImageReader::readImage()
@@ -271,6 +270,8 @@ void tst_QImageReader::readImage()
QFETCH(bool, success);
QFETCH(QByteArray, format);
+ SKIP_IF_UNSUPPORTED(format);
+
for (int i = 0; i < 2; ++i) {
QImageReader io(prefix + fileName, i ? QByteArray() : format);
if (success) {
@@ -361,7 +362,7 @@ void tst_QImageReader::setScaledSize_data()
QTest::newRow("PPM: runners") << "runners.ppm" << QSize(400, 400) << QByteArray("ppm");
QTest::newRow("PPM: test") << "test.ppm" << QSize(10, 10) << QByteArray("ppm");
QTest::newRow("XBM: gnus") << "gnus" << QSize(200, 200) << QByteArray("xbm");
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("JPEG: beavis A") << "beavis" << QSize(200, 200) << QByteArray("jpeg");
QTest::newRow("JPEG: beavis B") << "beavis" << QSize(175, 175) << QByteArray("jpeg");
QTest::newRow("JPEG: beavis C") << "beavis" << QSize(100, 100) << QByteArray("jpeg");
@@ -371,19 +372,15 @@ void tst_QImageReader::setScaledSize_data()
QTest::newRow("JPEG: beavis G") << "beavis" << QSize(50, 45) << QByteArray("jpeg");
QTest::newRow("JPEG: beavis H") << "beavis" << QSize(43, 43) << QByteArray("jpeg");
QTest::newRow("JPEG: beavis I") << "beavis" << QSize(25, 25) << QByteArray("jpeg");
-#endif // QTEST_HAVE_JPEG
-#ifdef QTEST_HAVE_GIF
+
QTest::newRow("GIF: earth") << "earth" << QSize(200, 200) << QByteArray("gif");
QTest::newRow("GIF: trolltech") << "trolltech" << QSize(200, 200) << QByteArray("gif");
-#endif // QTEST_HAVE_GIF
-#ifdef QTEST_HAVE_MNG
+
QTest::newRow("MNG: ball") << "ball" << QSize(200, 200) << QByteArray("mng");
QTest::newRow("MNG: fire") << "fire" << QSize(200, 200) << QByteArray("mng");
-#endif // QTEST_HAVE_MNG
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("SVG: rect") << "rect" << QSize(200, 200) << QByteArray("svg");
QTest::newRow("SVGZ: rect") << "rect" << QSize(200, 200) << QByteArray("svgz");
-#endif
}
void tst_QImageReader::setScaledSize()
@@ -392,8 +389,7 @@ void tst_QImageReader::setScaledSize()
QFETCH(QSize, newSize);
QFETCH(QByteArray, format);
- if (!format.isEmpty() && !QImageReader::supportedImageFormats().contains(format))
- QSKIP("Qt does not support reading the \"" + format + "\" format", SkipSingle);
+ SKIP_IF_UNSUPPORTED(format);
QImageReader reader(prefix + fileName);
reader.setScaledSize(newSize);
@@ -413,8 +409,7 @@ void tst_QImageReader::task255627_setNullScaledSize()
QFETCH(QString, fileName);
QFETCH(QByteArray, format);
- if (!format.isEmpty() && !QImageReader::supportedImageFormats().contains(format))
- QSKIP("Qt does not support reading the \"" + format + "\" format", SkipSingle);
+ SKIP_IF_UNSUPPORTED(format);
QImageReader reader(prefix + fileName);
@@ -432,6 +427,8 @@ void tst_QImageReader::setClipRect_data()
QTest::addColumn<QRect>("newRect");
QTest::addColumn<QByteArray>("format");
QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp");
QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp");
QTest::newRow("BMP: 4bpp uncompressed") << "tst7.bmp" << QRect(0, 0, 31, 31) << QByteArray("bmp");
QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm");
@@ -440,21 +437,17 @@ void tst_QImageReader::setClipRect_data()
QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm");
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg");
-#endif // QTEST_HAVE_JPEG
-#ifdef QTEST_HAVE_GIF
+
QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif");
QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif");
-#endif // QTEST_HAVE_GIF
-#ifdef QTEST_HAVE_MNG
+
QTest::newRow("MNG: ball") << "ball" << QRect(0, 0, 50, 50) << QByteArray("mng");
QTest::newRow("MNG: fire") << "fire" << QRect(0, 0, 50, 50) << QByteArray("mng");
-#endif // QTEST_HAVE_MNG
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg");
QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz");
-#endif
}
void tst_QImageReader::setClipRect()
@@ -463,8 +456,7 @@ void tst_QImageReader::setClipRect()
QFETCH(QRect, newRect);
QFETCH(QByteArray, format);
- if (!format.isEmpty() && !QImageReader::supportedImageFormats().contains(format))
- QSKIP("Qt does not support reading the \"" + format + "\" format", SkipSingle);
+ SKIP_IF_UNSUPPORTED(format);
QImageReader reader(prefix + fileName);
reader.setClipRect(newRect);
@@ -484,6 +476,8 @@ void tst_QImageReader::setScaledClipRect_data()
QTest::addColumn<QByteArray>("format");
QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp");
+ QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp");
QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp");
QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm");
QTest::newRow("PNG: kollada") << "kollada" << QRect(0, 0, 50, 50) << QByteArray("png");
@@ -491,21 +485,17 @@ void tst_QImageReader::setScaledClipRect_data()
QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm");
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg");
-#endif // QTEST_HAVE_JPEG
-#ifdef QTEST_HAVE_GIF
+
QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif");
QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif");
-#endif // QTEST_HAVE_GIF
-#ifdef QTEST_HAVE_MNG
+
QTest::newRow("MNG: ball") << "ball" << QRect(0, 0, 50, 50) << QByteArray("mng");
QTest::newRow("MNG: fire") << "fire" << QRect(0, 0, 50, 50) << QByteArray("mng");
-#endif // QTEST_HAVE_MNG
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg");
QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz");
-#endif
}
void tst_QImageReader::setScaledClipRect()
@@ -514,8 +504,7 @@ void tst_QImageReader::setScaledClipRect()
QFETCH(QRect, newRect);
QFETCH(QByteArray, format);
- if (!format.isEmpty() && !QImageReader::supportedImageFormats().contains(format))
- QSKIP("Qt does not support reading the \"" + format + "\" format", SkipSingle);
+ SKIP_IF_UNSUPPORTED(format);
QImageReader reader(prefix + fileName);
reader.setScaledSize(QSize(300, 300));
@@ -542,19 +531,20 @@ void tst_QImageReader::imageFormat_data()
QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
QTest::newRow("ppm-3") << QString("runners.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
QTest::newRow("ppm-4") << QString("test.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg") << QImage::Format_Indexed8;
QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg") << QImage::Format_RGB32;
QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg") << QImage::Format_RGB32;
-#endif
-#if defined QTEST_HAVE_GIF
+
QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif") << QImage::Format_Invalid;
QTest::newRow("gif-2") << QString("trolltech.gif") << QByteArray("gif") << QImage::Format_Invalid;
-#endif
+
QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm") << QImage::Format_MonoLSB;
QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm") << QImage::Format_Indexed8;
QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp") << QImage::Format_Indexed8;
QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp") << QImage::Format_Indexed8;
+ QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp") << QImage::Format_RGB32;
+ QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp") << QImage::Format_RGB32;
QTest::newRow("png") << QString("kollada.png") << QByteArray("png") << QImage::Format_ARGB32;
QTest::newRow("png-2") << QString("YCbCr_cmyk.png") << QByteArray("png") << QImage::Format_RGB32;
QTest::newRow("mng-1") << QString("ball.mng") << QByteArray("mng") << QImage::Format_Invalid;
@@ -569,27 +559,9 @@ void tst_QImageReader::imageFormat()
QFETCH(QByteArray, format);
QFETCH(QImage::Format, imageFormat);
- if (QImageReader::imageFormat(prefix + fileName).isEmpty()) {
- if (QByteArray("jpeg") == format)
-#ifndef QTEST_HAVE_JPEG
- return;
-#endif // !QTEST_HAVE_JPEG
- if (QByteArray("gif") == format)
-#ifndef QTEST_HAVE_GIF
- return;
-#endif // !QTEST_HAVE_GIF
- if (QByteArray("mng") == format)
-#ifndef QTEST_HAVE_MNG
- return;
-#endif // !QTEST_HAVE_MNG
- if (QByteArray("svg") == format || QByteArray("svgz") == format)
-#ifndef QTEST_HAVE_SVG
- return;
-#endif // !QTEST_HAVE_SVG
- QSKIP(("Qt does not support the " + format + " format.").constData(), SkipSingle);
- } else {
- QCOMPARE(QImageReader::imageFormat(prefix + fileName), format);
- }
+ SKIP_IF_UNSUPPORTED(format);
+
+ QCOMPARE(QImageReader::imageFormat(prefix + fileName), format);
QImageReader reader(prefix + fileName);
QCOMPARE(reader.imageFormat(), imageFormat);
}
@@ -649,21 +621,17 @@ void tst_QImageReader::setBackgroundColor_data()
QTest::newRow("PPM: runners") << QString("runners.ppm") << QColor(Qt::red);
QTest::newRow("PPM: test") << QString("test.ppm") << QColor(Qt::white);
QTest::newRow("XBM: gnus") << QString("gnus.xbm") << QColor(Qt::blue);
-#if defined QTEST_HAVE_JPEG
+
QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << QColor(Qt::darkBlue);
-#endif
-#if defined QTEST_HAVE_GIF
+
QTest::newRow("GIF: earth") << QString("earth.gif") << QColor(Qt::cyan);
QTest::newRow("GIF: trolltech") << QString("trolltech.gif") << QColor(Qt::magenta);
-#endif
-#if defined QTEST_HAVE_MNG
+
QTest::newRow("MNG: ball") << QString("ball.mng") << QColor(Qt::yellow);
QTest::newRow("MNG: fire") << QString("fire.mng") << QColor(Qt::gray);
-#endif
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("SVG: rect") << QString("rect.svg") << QColor(Qt::darkGreen);
QTest::newRow("SVGZ: rect") << QString("rect.svgz") << QColor(Qt::darkGreen);
-#endif
}
void tst_QImageReader::setBackgroundColor()
@@ -684,27 +652,25 @@ void tst_QImageReader::supportsAnimation_data()
QTest::newRow("BMP: colorful") << QString("colorful.bmp") << false;
QTest::newRow("BMP: font") << QString("font.bmp") << false;
QTest::newRow("BMP: signed char") << QString("crash-signed-char.bmp") << false;
+ QTest::newRow("BMP: test32bfv4") << QString("test32bfv4.bmp") << false;;
+ QTest::newRow("BMP: test32v5") << QString("test32v5.bmp") << false;
QTest::newRow("XPM: marble") << QString("marble.xpm") << false;
QTest::newRow("PNG: kollada") << QString("kollada.png") << false;
QTest::newRow("PPM: teapot") << QString("teapot.ppm") << false;
QTest::newRow("PPM: teapot") << QString("teapot.ppm") << false;
QTest::newRow("PPM: runners") << QString("runners.ppm") << false;
QTest::newRow("XBM: gnus") << QString("gnus.xbm") << false;
-#if defined QTEST_HAVE_JPEG
+
QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << false;
-#endif
-#if defined QTEST_HAVE_GIF
+
QTest::newRow("GIF: earth") << QString("earth.gif") << true;
QTest::newRow("GIF: trolltech") << QString("trolltech.gif") << true;
-#endif
-#if defined QTEST_HAVE_MNG
+
QTest::newRow("MNG: ball") << QString("ball.mng") << true;
QTest::newRow("MNG: fire") << QString("fire.mng") << true;
-#endif
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("SVG: rect") << QString("rect.svg") << false;
QTest::newRow("SVGZ: rect") << QString("rect.svgz") << false;
-#endif
}
void tst_QImageReader::supportsAnimation()
@@ -724,6 +690,9 @@ void tst_QImageReader::sizeBeforeRead()
{
QFETCH(QString, fileName);
QFETCH(QByteArray, format);
+
+ SKIP_IF_UNSUPPORTED(format);
+
QImageReader reader(prefix + fileName);
QVERIFY(reader.canRead());
if (format == "mng") {
@@ -771,7 +740,11 @@ void tst_QImageReader::imageFormatBeforeRead_data()
void tst_QImageReader::imageFormatBeforeRead()
{
QFETCH(QString, fileName);
+ QFETCH(QByteArray, format);
QFETCH(QImage::Format, imageFormat);
+
+ SKIP_IF_UNSUPPORTED(format);
+
QImageReader reader(fileName);
if (reader.supportsOption(QImageIOHandler::ImageFormat)) {
QImage::Format fileFormat = reader.imageFormat();
@@ -783,9 +756,10 @@ void tst_QImageReader::imageFormatBeforeRead()
}
}
-#if defined QTEST_HAVE_GIF
void tst_QImageReader::gifHandlerBugs()
{
+ SKIP_IF_UNSUPPORTED("gif");
+
{
QImageReader io(prefix + "trolltech.gif");
QVERIFY(io.loopCount() != 1);
@@ -827,6 +801,8 @@ void tst_QImageReader::gifHandlerBugs()
void tst_QImageReader::animatedGif()
{
+ SKIP_IF_UNSUPPORTED("gif");
+
QImageReader io(":images/qt.gif");
QImage image = io.read();
QVERIFY(!image.isNull());
@@ -842,6 +818,8 @@ void tst_QImageReader::animatedGif()
// Check the count of images in various call orders...
void tst_QImageReader::gifImageCount()
{
+ SKIP_IF_UNSUPPORTED("gif");
+
// just read every frame... and see how much we got..
{
QImageReader io(":images/four-frames.gif");
@@ -977,6 +955,8 @@ void tst_QImageReader::gifImageCount()
void tst_QImageReader::gifLoopCount()
{
+ SKIP_IF_UNSUPPORTED("gif");
+
{
QImageReader io(":images/qt-gif-anim.gif");
QCOMPARE(io.loopCount(), -1); // infinite loop
@@ -987,8 +967,6 @@ void tst_QImageReader::gifLoopCount()
}
}
-#endif
-
class Server : public QObject
{
Q_OBJECT
@@ -1050,29 +1028,28 @@ void tst_QImageReader::readFromDevice_data()
QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm");
QTest::newRow("ppm-3") << QString("teapot.ppm") << QByteArray("ppm");
QTest::newRow("ppm-4") << QString("runners.ppm") << QByteArray("ppm");
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-4") << QString("qtbug13653-no_eoi.jpg") << QByteArray("jpeg");
-#endif // QTEST_HAVE_JPEG
-#ifdef QTEST_HAVE_GIF
+
QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif");
QTest::newRow("gif-2") << QString("trolltech.gif") << QByteArray("gif");
-#endif // QTEST_HAVE_GIF
+
QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm");
QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm");
QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp");
QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp");
+ QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp");
+ QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp");
QTest::newRow("png") << QString("kollada.png") << QByteArray("png");
-#ifdef QTEST_HAVE_MNG
+
QTest::newRow("mng-1") << QString("ball.mng") << QByteArray("mng");
QTest::newRow("mng-2") << QString("fire.mng") << QByteArray("mng");
-#endif // QTEST_HAVE_MNG
-#if defined QTEST_HAVE_SVG
+
QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg");
QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz");
-#endif
}
void tst_QImageReader::readFromDevice()
@@ -1080,6 +1057,8 @@ void tst_QImageReader::readFromDevice()
QFETCH(QString, fileName);
QFETCH(QByteArray, format);
+ SKIP_IF_UNSUPPORTED(format);
+
QImage expectedImage(prefix + fileName, format);
QFile file(prefix + fileName);
@@ -1142,26 +1121,20 @@ void tst_QImageReader::readFromFileAfterJunk_data()
QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm");
QTest::newRow("ppm-3") << QString("teapot.ppm") << QByteArray("ppm");
QTest::newRow("ppm-4") << QString("runners.ppm") << QByteArray("ppm");
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg");
-#endif
-#if defined QTEST_HAVE_GIF
-// QTest::newRow("gif-1") << QString("images/earth.gif") << QByteArray("gif");
-// QTest::newRow("gif-2") << QString("images/trolltech.gif") << QByteArray("gif");
-#endif
+
QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm");
QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm");
QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp");
QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp");
+ QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp");
+ QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp");
QTest::newRow("png") << QString("kollada.png") << QByteArray("png");
-// QTest::newRow("mng-1") << QString("images/ball.mng") << QByteArray("mng");
-// QTest::newRow("mng-2") << QString("images/fire.mng") << QByteArray("mng");
-#if defined QTEST_HAVE_SVG
QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg");
QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz");
-#endif
}
void tst_QImageReader::readFromFileAfterJunk()
@@ -1169,10 +1142,7 @@ void tst_QImageReader::readFromFileAfterJunk()
QFETCH(QString, fileName);
QFETCH(QByteArray, format);
- if (!QImageReader::supportedImageFormats().contains(format)) {
- QString cause = QString("Skipping %1; no %2 support").arg(fileName).arg(QString(format));
- QSKIP(qPrintable(cause), SkipSingle);
- }
+ SKIP_IF_UNSUPPORTED(format);
QFile::remove("junk");
QFile junkFile("junk");
@@ -1221,25 +1191,22 @@ void tst_QImageReader::devicePosition_data()
QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm");
QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm");
QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm");
-#ifdef QTEST_HAVE_JPEG
+
QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg");
QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg");
-#endif
-#if defined QTEST_HAVE_GIF
+
QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif");
-#endif
+
QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm");
QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm");
QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp");
QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp");
+ QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp");
+ QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp");
QTest::newRow("png") << QString("kollada.png") << QByteArray("png");
-// QTest::newRow("mng-1") << QString("images/ball.mng") << QByteArray("mng");
-// QTest::newRow("mng-2") << QString("images/fire.mng") << QByteArray("mng");
-#if defined QTEST_HAVE_SVG
QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg");
QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz");
-#endif
}
void tst_QImageReader::devicePosition()
@@ -1247,6 +1214,8 @@ void tst_QImageReader::devicePosition()
QFETCH(QString, fileName);
QFETCH(QByteArray, format);
+ SKIP_IF_UNSUPPORTED(format);
+
QImage expected(prefix + fileName);
QVERIFY(!expected.isNull());
@@ -1305,7 +1274,12 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("4bpp-rle.bmp") << QString("4bpp-rle.bmp")
<< QByteArray("bmp") << QSize(640, 480)
<< QString("");
-#ifdef QTEST_HAVE_GIF
+ QTest::newRow("test32bfv4.bmp") << QString("test32bfv4.bmp")
+ << QByteArray("bmp") << QSize(373, 156)
+ << QString("");
+ QTest::newRow("test32v5.bmp") << QString("test32v5.bmp")
+ << QByteArray("bmp") << QSize(373, 156)
+ << QString("");
QTest::newRow("corrupt.gif") << QString("corrupt.gif")
<< QByteArray("gif") << QSize(0, 0)
<< QString("");
@@ -1324,8 +1298,6 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("bat2.gif") << QString("bat2.gif")
<< QByteArray("gif") << QSize(32, 32)
<< QString("");
-#endif
-#ifdef QTEST_HAVE_JPEG
QTest::newRow("corrupt.jpg") << QString("corrupt.jpg")
<< QByteArray("jpg") << QSize(0, 0)
<< QString("JPEG datastream contains no image");
@@ -1341,8 +1313,6 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("qtbug13653-no_eoi.jpg") << QString("qtbug13653-no_eoi.jpg")
<< QByteArray("jpg") << QSize(240, 180)
<< QString("");
-#endif
-#ifdef QTEST_HAVE_MNG
QTest::newRow("corrupt.mng") << QString("corrupt.mng")
<< QByteArray("mng") << QSize(0, 0)
<< QString("MNG error 901: Application signalled I/O error; chunk IHDR; subcode 0:0");
@@ -1352,8 +1322,6 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("ball.mng") << QString("ball.mng")
<< QByteArray("mng") << QSize(32, 32)
<< QString("");
-#endif
-#ifdef QTEST_HAVE_SVG
QTest::newRow("rect.svg") << QString("rect.svg")
<< QByteArray("svg") << QSize(105, 137)
<< QString("");
@@ -1366,7 +1334,6 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("corrupt.svgz") << QString("corrupt.svgz")
<< QByteArray("svgz") << QSize(0, 0)
<< QString("");
-#endif
QTest::newRow("image.pbm") << QString("image.pbm")
<< QByteArray("pbm") << QSize(16, 6)
<< QString("");
@@ -1403,7 +1370,6 @@ void tst_QImageReader::readFromResources_data()
QTest::newRow("test.ppm") << QString("test.ppm")
<< QByteArray("ppm") << QSize(10, 10)
<< QString("");
-// QTest::newRow("corrupt.xbm") << QString("corrupt.xbm") << QByteArray("xbm") << QSize(0, 0);
QTest::newRow("gnus.xbm") << QString("gnus.xbm")
<< QByteArray("xbm") << QSize(271, 273)
<< QString("");
@@ -1442,6 +1408,9 @@ void tst_QImageReader::readFromResources()
QFETCH(QByteArray, format);
QFETCH(QSize, size);
QFETCH(QString, message);
+
+ SKIP_IF_UNSUPPORTED(format);
+
for (int i = 0; i < 2; ++i) {
QString file = i ? (":/images/" + fileName) : (prefix + fileName);
{
@@ -1515,31 +1484,26 @@ void tst_QImageReader::readCorruptImage_data()
QTest::addColumn<QString>("fileName");
QTest::addColumn<bool>("shouldFail");
QTest::addColumn<QString>("message");
-#if defined QTEST_HAVE_JPEG
+ QTest::addColumn<QByteArray>("format");
QTest::newRow("corrupt jpeg") << QString("corrupt.jpg") << true
- << QString("JPEG datastream contains no image");
-#endif
-#if defined QTEST_HAVE_GIF
- QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("");
-#endif
-#ifdef QTEST_HAVE_MNG
+ << QString("JPEG datastream contains no image")
+ << QByteArray("jpeg");
+ QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("") << QByteArray("gif");
QTest::newRow("corrupt mng") << QString("corrupt.mng") << true
- << QString("MNG error 901: Application signalled I/O error; chunk IHDR; subcode 0:0");
-#endif
- QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("");
- QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("");
+ << QString("MNG error 901: Application signalled I/O error; chunk IHDR; subcode 0:0")
+ << QByteArray("mng");
+ QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("") << QByteArray("png");
+ QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("") << QByteArray("bmp");
QTest::newRow("corrupt xpm (colors)") << QString("corrupt-colors.xpm") << true
- << QString("QImage: XPM color specification is missing: bla9an.n#x");
+ << QString("QImage: XPM color specification is missing: bla9an.n#x")
+ << QByteArray("xpm");
QTest::newRow("corrupt xpm (pixels)") << QString("corrupt-pixels.xpm") << true
- << QString("QImage: XPM pixels missing on image line 3");
- QTest::newRow("corrupt xbm") << QString("corrupt.xbm") << false << QString("");
-#if defined QTEST_HAVE_TIFF
- QTest::newRow("corrupt tiff") << QString("corrupt-data.tif") << true << QString("");
-#endif
-#if defined QTEST_HAVE_SVG
- QTest::newRow("corrupt svg") << QString("corrupt.svg") << true << QString("");
- QTest::newRow("corrupt svgz") << QString("corrupt.svgz") << true << QString("");
-#endif
+ << QString("QImage: XPM pixels missing on image line 3")
+ << QByteArray("xpm");
+ QTest::newRow("corrupt xbm") << QString("corrupt.xbm") << false << QString("") << QByteArray("xbm");
+ QTest::newRow("corrupt tiff") << QString("corrupt-data.tif") << true << QString("") << QByteArray("tiff");
+ QTest::newRow("corrupt svg") << QString("corrupt.svg") << true << QString("") << QByteArray("svg");
+ QTest::newRow("corrupt svgz") << QString("corrupt.svgz") << true << QString("") << QByteArray("svgz");
}
void tst_QImageReader::readCorruptImage()
@@ -1547,6 +1511,9 @@ void tst_QImageReader::readCorruptImage()
QFETCH(QString, fileName);
QFETCH(bool, shouldFail);
QFETCH(QString, message);
+ QFETCH(QByteArray, format);
+
+ SKIP_IF_UNSUPPORTED(format);
if (!message.isEmpty())
QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
@@ -1603,7 +1570,6 @@ void tst_QImageReader::supportsOption()
QVERIFY(!reader.supportsOption(option));
}
-#if defined QTEST_HAVE_TIFF
void tst_QImageReader::tiffCompression_data()
{
QTest::addColumn<QString>("uncompressedFile");
@@ -1624,6 +1590,8 @@ void tst_QImageReader::tiffCompression()
QFETCH(QString, uncompressedFile);
QFETCH(QString, compressedFile);
+ SKIP_IF_UNSUPPORTED("tiff");
+
QImage uncompressedImage(prefix + uncompressedFile);
QImage compressedImage(prefix + compressedFile);
@@ -1632,6 +1600,8 @@ void tst_QImageReader::tiffCompression()
void tst_QImageReader::tiffEndianness()
{
+ SKIP_IF_UNSUPPORTED("tiff");
+
QImage littleEndian(prefix + "rgba_nocompression_littleendian.tif");
QImage bigEndian(prefix + "rgba_nocompression_bigendian.tif");
@@ -1675,6 +1645,8 @@ void tst_QImageReader::tiffOrientation()
QFETCH(QString, expected);
QFETCH(QString, oriented);
+ SKIP_IF_UNSUPPORTED("tiff");
+
QImage expectedImage(prefix + expected);
QImage orientedImage(prefix + oriented);
QCOMPARE(expectedImage, orientedImage);
@@ -1682,22 +1654,22 @@ void tst_QImageReader::tiffOrientation()
void tst_QImageReader::tiffGrayscale()
{
+ SKIP_IF_UNSUPPORTED("tiff");
+
QImage actualImage(prefix + "grayscale.tif");
QImage expectedImage(prefix + "grayscale-ref.tif");
QCOMPARE(expectedImage, actualImage.convertToFormat(expectedImage.format()));
}
-#endif
void tst_QImageReader::dotsPerMeter_data()
{
QTest::addColumn<QString>("fileName");
QTest::addColumn<int>("expectedDotsPerMeterX");
QTest::addColumn<int>("expectedDotsPerMeterY");
-#if defined QTEST_HAVE_TIFF
- QTest::newRow("TIFF: 72 dpi") << ("rgba_nocompression_littleendian.tif") << qRound(72 * (100 / 2.54)) << qRound(72 * (100 / 2.54));
- QTest::newRow("TIFF: 100 dpi") << ("image_100dpi.tif") << qRound(100 * (100 / 2.54)) << qRound(100 * (100 / 2.54));
-#endif
+ QTest::addColumn<QByteArray>("format");
+ QTest::newRow("TIFF: 72 dpi") << ("rgba_nocompression_littleendian.tif") << qRound(72 * (100 / 2.54)) << qRound(72 * (100 / 2.54)) << QByteArray("tiff");
+ QTest::newRow("TIFF: 100 dpi") << ("image_100dpi.tif") << qRound(100 * (100 / 2.54)) << qRound(100 * (100 / 2.54)) << QByteArray("tiff");
}
void tst_QImageReader::dotsPerMeter()
@@ -1705,6 +1677,9 @@ void tst_QImageReader::dotsPerMeter()
QFETCH(QString, fileName);
QFETCH(int, expectedDotsPerMeterX);
QFETCH(int, expectedDotsPerMeterY);
+ QFETCH(QByteArray, format);
+
+ SKIP_IF_UNSUPPORTED(format);
QImage image(prefix + fileName);
@@ -1717,10 +1692,9 @@ void tst_QImageReader::physicalDpi_data()
QTest::addColumn<QString>("fileName");
QTest::addColumn<int>("expectedPhysicalDpiX");
QTest::addColumn<int>("expectedPhysicalDpiY");
-#if defined QTEST_HAVE_TIFF
- QTest::newRow("TIFF: 72 dpi") << "rgba_nocompression_littleendian.tif" << 72 << 72;
- QTest::newRow("TIFF: 100 dpi") << "image_100dpi.tif" << 100 << 100;
-#endif
+ QTest::addColumn<QByteArray>("format");
+ QTest::newRow("TIFF: 72 dpi") << "rgba_nocompression_littleendian.tif" << 72 << 72 << QByteArray("tiff");
+ QTest::newRow("TIFF: 100 dpi") << "image_100dpi.tif" << 100 << 100 << QByteArray("tiff");
}
void tst_QImageReader::physicalDpi()
@@ -1728,6 +1702,9 @@ void tst_QImageReader::physicalDpi()
QFETCH(QString, fileName);
QFETCH(int, expectedPhysicalDpiX);
QFETCH(int, expectedPhysicalDpiY);
+ QFETCH(QByteArray, format);
+
+ SKIP_IF_UNSUPPORTED(format);
QImage image(prefix + fileName);
@@ -1769,21 +1746,19 @@ void tst_QImageReader::autoDetectImageFormat()
QVERIFY(!reader.read().isNull());
}
-#ifdef QTEST_HAVE_JPEG
- {
+ if (QImageReader::supportedImageFormats().contains("jpeg")) {
QImageReader io(prefix + "YCbCr_rgb.jpg");
io.setAutoDetectImageFormat(false);
// This should fail since no format string is given
QImage image;
QVERIFY(!io.read(&image));
}
- {
+ if (QImageReader::supportedImageFormats().contains("jpeg")) {
QImageReader io(prefix + "YCbCr_rgb.jpg", "jpg");
io.setAutoDetectImageFormat(false);
QImage image;
QVERIFY(io.read(&image));
}
-#endif
{
QImageReader io(prefix + "tst7.png");
io.setAutoDetectImageFormat(false);
@@ -1873,26 +1848,16 @@ void tst_QImageReader::testIgnoresFormatAndExtension_data()
QTest::newRow("image.pbm") << "image" << "pbm" << "pbm";
QTest::newRow("image.pgm") << "image" << "pgm" << "pgm";
-#if defined QTEST_HAVE_GIF
QTest::newRow("bat1.gif") << "bat1" << "gif" << "gif";
-#endif
-#if defined QTEST_HAVE_JPEG
QTest::newRow("beavis.jpg") << "beavis" << "jpg" << "jpeg";
-#endif
-#if defined QTEST_HAVE_MNG
QTest::newRow("fire.mng") << "fire" << "mng" << "mng";
-#endif
-#if defined QTEST_HAVE_TIFF
QTest::newRow("image_100dpi.tif") << "image_100dpi" << "tif" << "tiff";
-#endif
-#if defined QTEST_HAVE_SVG
QTest::newRow("rect.svg") << "rect" << "svg" << "svg";
QTest::newRow("rect.svgz") << "rect" << "svgz" << "svgz";
-#endif
}
@@ -1902,6 +1867,8 @@ void tst_QImageReader::testIgnoresFormatAndExtension()
QFETCH(QString, extension);
QFETCH(QString, expected);
+ SKIP_IF_UNSUPPORTED(expected.toLatin1());
+
QList<QByteArray> formats = QImageReader::supportedImageFormats();
QString fileNameBase = prefix + name + ".";
diff --git a/tests/auto/qintvalidator/tst_qintvalidator.cpp b/tests/auto/qintvalidator/tst_qintvalidator.cpp
index d53763566d..369e3254e8 100644
--- a/tests/auto/qintvalidator/tst_qintvalidator.cpp
+++ b/tests/auto/qintvalidator/tst_qintvalidator.cpp
@@ -51,6 +51,7 @@ private slots:
void validate();
void validateArabic();
void validateFrench();
+ void notifySignals();
};
Q_DECLARE_METATYPE(QValidator::State);
@@ -189,7 +190,6 @@ void tst_QIntValidator::validateFrench()
QIntValidator validator(-2000, 2000, 0);
validator.setLocale(QLocale::French);
int i;
-
QString s = QLatin1String("1 ");
QCOMPARE(validator.validate(s, i), QValidator::Acceptable);
validator.fixup(s);
@@ -220,5 +220,36 @@ void tst_QIntValidator::validate()
QCOMPARE((int)iv.validate(value, dummy), (int)state);
}
+void tst_QIntValidator::notifySignals()
+{
+ QIntValidator iv(0, 10, 0);
+ QSignalSpy topSpy(&iv, SIGNAL(topChanged(int)));
+ QSignalSpy bottomSpy(&iv, SIGNAL(bottomChanged(int)));
+ iv.setTop(9);
+ QCOMPARE(topSpy.count(), 1);
+ QVERIFY(iv.top() == 9);
+ iv.setBottom(1);
+ QCOMPARE(bottomSpy.count(), 1);
+ QVERIFY(iv.bottom() == 1);
+
+ iv.setRange(1, 8);
+ QCOMPARE(topSpy.count(), 2);
+ QCOMPARE(bottomSpy.count(), 1);
+ QVERIFY(iv.top() == 8);
+ QVERIFY(iv.bottom() == 1);
+
+ iv.setRange(2, 8);
+ QCOMPARE(topSpy.count(), 2);
+ QCOMPARE(bottomSpy.count(), 2);
+ QVERIFY(iv.top() == 8);
+ QVERIFY(iv.bottom() == 2);
+
+ iv.setRange(3, 7);
+ QCOMPARE(topSpy.count(), 3);
+ QCOMPARE(bottomSpy.count(), 3);
+ QVERIFY(iv.top() == 7);
+ QVERIFY(iv.bottom() == 3);
+}
+
QTEST_MAIN(tst_QIntValidator)
#include "tst_qintvalidator.moc"
diff --git a/tests/auto/qiodevice/tst_qiodevice.cpp b/tests/auto/qiodevice/tst_qiodevice.cpp
index 70debfa1f3..a0f57f9d8d 100644
--- a/tests/auto/qiodevice/tst_qiodevice.cpp
+++ b/tests/auto/qiodevice/tst_qiodevice.cpp
@@ -129,11 +129,11 @@ void tst_QIODevice::constructing_QTcpSocket()
QVERIFY(!device->isOpen());
socket.connectToHost(QtNetworkSettings::serverName(), 143);
- QVERIFY(socket.waitForConnected(5000));
+ QVERIFY(socket.waitForConnected(30000));
QVERIFY(device->isOpen());
while (!device->canReadLine())
- QVERIFY(device->waitForReadyRead(5000));
+ QVERIFY(device->waitForReadyRead(30000));
char buf[1024];
memset(buf, 0, sizeof(buf));
@@ -143,11 +143,11 @@ void tst_QIODevice::constructing_QTcpSocket()
socket.close();
socket.connectToHost(QtNetworkSettings::serverName(), 143);
- QVERIFY(socket.waitForConnected(5000));
+ QVERIFY(socket.waitForConnected(30000));
QVERIFY(device->isOpen());
while (!device->canReadLine())
- QVERIFY(device->waitForReadyRead(5000));
+ QVERIFY(device->waitForReadyRead(30000));
char buf2[1024];
memset(buf2, 0, sizeof(buf2));
diff --git a/tests/auto/qlibrary/tst_qlibrary.cpp b/tests/auto/qlibrary/tst_qlibrary.cpp
index 0c31fddfdb..675d0e6ab6 100644
--- a/tests/auto/qlibrary/tst_qlibrary.cpp
+++ b/tests/auto/qlibrary/tst_qlibrary.cpp
@@ -297,7 +297,7 @@ void tst_QLibrary::unload_after_implicit_load()
#endif
QLibrary library( "./mylib" );
- void *p = library.resolve("mylibversion");
+ QFunctionPointer p = library.resolve("mylibversion");
QVERIFY(p); // Check if it was loaded
QVERIFY(library.isLoaded());
QVERIFY(library.unload());
diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp
index 92574ea01b..68e88a87ed 100644
--- a/tests/auto/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/qlineedit/tst_qlineedit.cpp
@@ -72,6 +72,8 @@
#include "qcommonstyle.h"
#include "qstyleoption.h"
+#include "qplatformdefs.h"
+
QT_BEGIN_NAMESPACE
class QPainter;
QT_END_NAMESPACE
@@ -180,6 +182,10 @@ private slots:
void echoMode();
void passwordEchoOnEdit();
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+ void passwordEchoDelay();
+#endif
+
void maxLength_mask_data();
void maxLength_mask();
@@ -283,6 +289,9 @@ private slots:
void bidiLogicalMovement_data();
void bidiLogicalMovement();
+ void selectAndCursorPosition();
+ void inputMethodSelection();
+
protected slots:
void editingFinished();
@@ -1679,6 +1688,51 @@ void tst_QLineEdit::passwordEchoOnEdit()
testWidget->setEchoMode(QLineEdit::Normal);
}
+#ifdef QT_GUI_PASSWORD_ECHO_DELAY
+void tst_QLineEdit::passwordEchoDelay()
+{
+ QStyleOptionFrameV2 opt;
+ QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
+
+ testWidget->setEchoMode(QLineEdit::Password);
+ testWidget->setFocus();
+ testWidget->raise();
+ QTRY_VERIFY(testWidget->hasFocus());
+
+ QTest::keyPress(testWidget, '0');
+ QTest::keyPress(testWidget, '1');
+ QTest::keyPress(testWidget, '2');
+ QCOMPARE(testWidget->displayText(), QString(2, fillChar) + QLatin1Char('2'));
+ QTest::keyPress(testWidget, '3');
+ QTest::keyPress(testWidget, '4');
+ QCOMPARE(testWidget->displayText(), QString(4, fillChar) + QLatin1Char('4'));
+ QTest::keyPress(testWidget, Qt::Key_Backspace);
+ QCOMPARE(testWidget->displayText(), QString(4, fillChar));
+ QTest::keyPress(testWidget, '4');
+ QCOMPARE(testWidget->displayText(), QString(4, fillChar) + QLatin1Char('4'));
+ QTest::qWait(QT_GUI_PASSWORD_ECHO_DELAY);
+ QTRY_COMPARE(testWidget->displayText(), QString(5, fillChar));
+ QTest::keyPress(testWidget, '5');
+ QCOMPARE(testWidget->displayText(), QString(5, fillChar) + QLatin1Char('5'));
+ testWidget->clearFocus();
+ QVERIFY(!testWidget->hasFocus());
+ QCOMPARE(testWidget->displayText(), QString(6, fillChar));
+ testWidget->setFocus();
+ QTRY_VERIFY(testWidget->hasFocus());
+ QCOMPARE(testWidget->displayText(), QString(6, fillChar));
+ QTest::keyPress(testWidget, '6');
+ QCOMPARE(testWidget->displayText(), QString(6, fillChar) + QLatin1Char('6'));
+
+ QInputMethodEvent ev;
+ ev.setCommitString(QLatin1String("7"));
+ QApplication::sendEvent(testWidget, &ev);
+ QCOMPARE(testWidget->displayText(), QString(7, fillChar) + QLatin1Char('7'));
+
+ // restore clean state
+ testWidget->setEchoMode(QLineEdit::Normal);
+}
+#endif
+
void tst_QLineEdit::maxLength_mask_data()
{
QTest::addColumn<QString>("mask");
@@ -3820,5 +3874,38 @@ void tst_QLineEdit::bidiLogicalMovement()
} while (moved && i >= 0);
}
+void tst_QLineEdit::selectAndCursorPosition()
+{
+ testWidget->setText("This is a long piece of text");
+
+ testWidget->setSelection(0, 5);
+ QCOMPARE(testWidget->cursorPosition(), 5);
+ testWidget->setSelection(5, -5);
+ QCOMPARE(testWidget->cursorPosition(), 0);
+}
+
+void tst_QLineEdit::inputMethodSelection()
+{
+ testWidget->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ testWidget->setSelection(0,0);
+ QSignalSpy selectionSpy(testWidget, SIGNAL(selectionChanged()));
+
+ QCOMPARE(selectionSpy.count(), 0);
+ QCOMPARE(testWidget->selectionStart(), -1);
+
+ testWidget->setSelection(0,5);
+
+ QCOMPARE(selectionSpy.count(), 1);
+ QCOMPARE(testWidget->selectionStart(), 0);
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 12, 5, QVariant());
+ QInputMethodEvent event("", attributes);
+ QApplication::sendEvent(testWidget, &event);
+
+ QCOMPARE(selectionSpy.count(), 2);
+ QCOMPARE(testWidget->selectionStart(), 12);
+}
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/qmessagebox/qmessagebox.pro b/tests/auto/qmessagebox/qmessagebox.pro
index fe0e08aede..e3f6ddb1f6 100644
--- a/tests/auto/qmessagebox/qmessagebox.pro
+++ b/tests/auto/qmessagebox/qmessagebox.pro
@@ -7,5 +7,3 @@ INCLUDEPATH += .
# Input
SOURCES += tst_qmessagebox.cpp
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp
index 0913454263..6b737681b1 100644
--- a/tests/auto/qmessagebox/tst_qmessagebox.cpp
+++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp
@@ -127,9 +127,7 @@ private slots:
void shortcut();
void staticSourceCompat();
- void staticBinaryCompat();
void instanceSourceCompat();
- void instanceBinaryCompat();
void testSymbols();
void incorrectDefaultButton();
@@ -407,19 +405,6 @@ void tst_QMessageBox::about()
#endif
}
-// Old message box enums
-const int Old_Ok = 1;
-const int Old_Cancel = 2;
-const int Old_Yes = 3;
-const int Old_No = 4;
-const int Old_Abort = 5;
-const int Old_Retry = 6;
-const int Old_Ignore = 7;
-const int Old_YesAll = 8;
-const int Old_NoAll = 9;
-const int Old_Default = 0x100;
-const int Old_Escape = 0x200;
-
void tst_QMessageBox::staticSourceCompat()
{
int ret;
@@ -508,74 +493,6 @@ void tst_QMessageBox::instanceSourceCompat()
QCOMPARE(exec(&mb, Qt::ALT + Qt::Key_Z), 1);
}
-void tst_QMessageBox::staticBinaryCompat()
-{
- int ret;
-
- // binary compat tests for < 4.2
- keyToSend = Qt::Key_Enter;
- sendKeySoon();
- ret = QMessageBox::information(0, "title", "text", Old_Yes, Old_No, 0);
- int expectedButton = int(Old_Yes);
-#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
- if (qobject_cast<QMacStyle *>(qApp->style()))
- expectedButton = int(Old_No);
-#elif !defined(QT_NO_STYLE_CLEANLOOKS)
- if (qobject_cast<QCleanlooksStyle *>(qApp->style()))
- expectedButton = int(Old_No);
-#endif
- QCOMPARE(ret, expectedButton);
- QCOMPARE(keyToSend, -1);
-
- keyToSend = Qt::Key_Escape;
- sendKeySoon();
- ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Escape, Old_No, 0);
- QCOMPARE(ret, int(Old_Yes));
- QCOMPARE(keyToSend, -1);
-
- keyToSend = Qt::Key_Enter;
- sendKeySoon();
- ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Default, Old_No, 0);
- QCOMPARE(ret, int(Old_Yes));
- QCOMPARE(keyToSend, -1);
-
-#if 0
- keyToSend = Qt::Key_Escape;
- sendKeySoon();
- ret = QMessageBox::information(0, "title", "text", Old_Yes, Old_No | Old_Default, 0);
- QCOMPARE(ret, -1);
- QCOMPARE(keyToSend, -1);
-#endif
-
- keyToSend = Qt::Key_Escape;
- sendKeySoon();
- ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Escape, Old_No | Old_Default, 0);
- QCOMPARE(ret, Old_Yes);
- QCOMPARE(keyToSend, -1);
-
- keyToSend = Qt::Key_Escape;
- sendKeySoon();
- ret = QMessageBox::information(0, "title", "text", Old_Yes | Old_Default, Old_No | Old_Escape, 0);
- QCOMPARE(ret, Old_No);
- QCOMPARE(keyToSend, -1);
-
-}
-
-void tst_QMessageBox::instanceBinaryCompat()
-{
- QMessageBox mb("Application name here",
- "Saving the file will overwrite the original file on the disk.\n"
- "Do you really want to save?",
- QMessageBox::Information,
- Old_Yes | Old_Default,
- Old_No,
- Old_Cancel | Old_Escape);
- mb.setButtonText(Old_Yes, "Save");
- mb.setButtonText(Old_No, "Discard");
- QCOMPARE(exec(&mb, Qt::Key_Enter), int(Old_Yes));
- QCOMPARE(exec(&mb, Qt::Key_Escape), int(Old_Cancel));
-}
-
void tst_QMessageBox::testSymbols()
{
return;
diff --git a/tests/auto/qmutex/tst_qmutex.cpp b/tests/auto/qmutex/tst_qmutex.cpp
index 5fed6bb44e..7ad6a98a4d 100644
--- a/tests/auto/qmutex/tst_qmutex.cpp
+++ b/tests/auto/qmutex/tst_qmutex.cpp
@@ -65,6 +65,7 @@ private slots:
void stressTest();
void tryLockRace();
void qtbug16115_trylock();
+ void moreStress();
};
static const int iterations = 100;
@@ -83,6 +84,8 @@ QMutex normalMutex, recursiveMutex(QMutex::Recursive);
QSemaphore testsTurn;
QSemaphore threadsTurn;
+enum { waitTime = 100 };
+
void tst_QMutex::tryLock()
{
// test non-recursive mutex
@@ -109,18 +112,18 @@ void tst_QMutex::tryLock()
threadsTurn.acquire();
QTime timer;
timer.start();
- QVERIFY(!normalMutex.tryLock(1000));
- QVERIFY(timer.elapsed() >= 1000);
+ QVERIFY(!normalMutex.tryLock(waitTime));
+ QVERIFY(timer.elapsed() >= waitTime);
testsTurn.release();
threadsTurn.acquire();
timer.start();
- QVERIFY(normalMutex.tryLock(1000));
- QVERIFY(timer.elapsed() <= 1000);
+ QVERIFY(normalMutex.tryLock(waitTime));
+ QVERIFY(timer.elapsed() <= waitTime);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
timer.start();
- QVERIFY(!normalMutex.tryLock(1000));
- QVERIFY(timer.elapsed() >= 1000);
+ QVERIFY(!normalMutex.tryLock(waitTime));
+ QVERIFY(timer.elapsed() >= waitTime);
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
testsTurn.release();
@@ -132,7 +135,7 @@ void tst_QMutex::tryLock()
threadsTurn.acquire();
timer.start();
QVERIFY(normalMutex.tryLock(0));
- QVERIFY(timer.elapsed() < 1000);
+ QVERIFY(timer.elapsed() < waitTime);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(!normalMutex.tryLock(0));
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
@@ -158,13 +161,13 @@ void tst_QMutex::tryLock()
normalMutex.unlock();
threadsTurn.release();
- // thread can't acquire lock, timeout = 1000
+ // thread can't acquire lock, timeout = waitTime
testsTurn.acquire();
normalMutex.lock();
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
threadsTurn.release();
- // thread can acquire lock, timeout = 1000
+ // thread can acquire lock, timeout = waitTime
testsTurn.acquire();
QVERIFY(lockCount.testAndSetRelaxed(1, 0));
normalMutex.unlock();
@@ -215,17 +218,17 @@ void tst_QMutex::tryLock()
threadsTurn.acquire();
QTime timer;
timer.start();
- QVERIFY(!recursiveMutex.tryLock(1000));
- QVERIFY(timer.elapsed() >= 1000);
+ QVERIFY(!recursiveMutex.tryLock(waitTime));
+ QVERIFY(timer.elapsed() >= waitTime);
QVERIFY(!recursiveMutex.tryLock(0));
testsTurn.release();
threadsTurn.acquire();
timer.start();
- QVERIFY(recursiveMutex.tryLock(1000));
- QVERIFY(timer.elapsed() <= 1000);
+ QVERIFY(recursiveMutex.tryLock(waitTime));
+ QVERIFY(timer.elapsed() <= waitTime);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
- QVERIFY(recursiveMutex.tryLock(1000));
+ QVERIFY(recursiveMutex.tryLock(waitTime));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
QVERIFY(lockCount.testAndSetRelaxed(2, 1));
recursiveMutex.unlock();
@@ -241,7 +244,7 @@ void tst_QMutex::tryLock()
threadsTurn.acquire();
timer.start();
QVERIFY(recursiveMutex.tryLock(0));
- QVERIFY(timer.elapsed() < 1000);
+ QVERIFY(timer.elapsed() < waitTime);
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
QVERIFY(recursiveMutex.tryLock(0));
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
@@ -274,7 +277,7 @@ void tst_QMutex::tryLock()
recursiveMutex.unlock();
threadsTurn.release();
- // thread can't acquire lock, timeout = 1000
+ // thread can't acquire lock, timeout = waitTime
testsTurn.acquire();
recursiveMutex.lock();
QVERIFY(lockCount.testAndSetRelaxed(0, 1));
@@ -282,7 +285,7 @@ void tst_QMutex::tryLock()
QVERIFY(lockCount.testAndSetRelaxed(1, 2));
threadsTurn.release();
- // thread can acquire lock, timeout = 1000
+ // thread can acquire lock, timeout = waitTime
testsTurn.acquire();
QVERIFY(lockCount.testAndSetRelaxed(2, 1));
recursiveMutex.unlock();
@@ -436,7 +439,8 @@ void tst_QMutex::lock_unlock_locked_tryLock()
}
}
-enum { one_minute = 60 * 1000, threadCount = 10 };
+enum { one_minute = 6 * 1000, //not really one minute, but else it is too long.
+ threadCount = 10 };
class StressTestThread : public QThread
{
@@ -497,7 +501,7 @@ public:
do {
if (mutex.tryLock())
mutex.unlock();
- } while (t.elapsed() < 20000);
+ } while (t.elapsed() < one_minute/2);
}
};
QMutex TryLockRaceThread::mutex;
@@ -534,7 +538,7 @@ void tst_QMutex::qtbug16115_trylock()
TrylockThread(QMutex &mut) : mut(mut) {}
QMutex &mut;
void run() {
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < 100000; ++i) {
if (mut.tryLock(0)) {
if ((++qtbug16115_trylock_counter) != 1)
++qtbug16115_failure_count;
@@ -553,7 +557,7 @@ void tst_QMutex::qtbug16115_trylock()
t2.start();
t3.start();
- for (int i = 0; i < 1000000; ++i) {
+ for (int i = 0; i < 100000; ++i) {
mut.lock();
if ((++qtbug16115_trylock_counter) != 1)
++qtbug16115_failure_count;
@@ -567,5 +571,70 @@ void tst_QMutex::qtbug16115_trylock()
QCOMPARE(qtbug16115_failure_count, 0);
}
+
+class MoreStressTestThread : public QThread
+{
+ QTime t;
+public:
+ static QAtomicInt lockCount;
+ static QAtomicInt sentinel[threadCount];
+ static QMutex mutex[threadCount];
+ static QAtomicInt errorCount;
+ void start()
+ {
+ t.start();
+ QThread::start();
+ }
+ void run()
+ {
+ quint64 i = 0;
+ while (t.elapsed() < one_minute) {
+ i++;
+ uint nb = (i * 9 + lockCount * 13) % threadCount;
+ QMutexLocker locker(&mutex[nb]);
+ if (sentinel[nb]) errorCount.ref();
+ if (sentinel[nb].fetchAndAddRelaxed(5)) errorCount.ref();
+ if (!sentinel[nb].testAndSetRelaxed(5, 0)) errorCount.ref();
+ if (sentinel[nb]) errorCount.ref();
+ lockCount.ref();
+ nb = (nb * 17 + i * 5 + lockCount * 3) % threadCount;
+ if (mutex[nb].tryLock()) {
+ if (sentinel[nb]) errorCount.ref();
+ if (sentinel[nb].fetchAndAddRelaxed(16)) errorCount.ref();
+ if (!sentinel[nb].testAndSetRelaxed(16, 0)) errorCount.ref();
+ if (sentinel[nb]) errorCount.ref();
+ lockCount.ref();
+ mutex[nb].unlock();
+ }
+ nb = (nb * 15 + i * 47 + lockCount * 31) % threadCount;
+ if (mutex[nb].tryLock(2)) {
+ if (sentinel[nb]) errorCount.ref();
+ if (sentinel[nb].fetchAndAddRelaxed(53)) errorCount.ref();
+ if (!sentinel[nb].testAndSetRelaxed(53, 0)) errorCount.ref();
+ if (sentinel[nb]) errorCount.ref();
+ lockCount.ref();
+ mutex[nb].unlock();
+ }
+ }
+ }
+};
+QMutex MoreStressTestThread::mutex[threadCount];
+QAtomicInt MoreStressTestThread::lockCount;
+QAtomicInt MoreStressTestThread::sentinel[threadCount];
+QAtomicInt MoreStressTestThread::errorCount = 0;
+
+void tst_QMutex::moreStress()
+{
+ MoreStressTestThread threads[threadCount];
+ for (int i = 0; i < threadCount; ++i)
+ threads[i].start();
+ QVERIFY(threads[0].wait(one_minute + 10000));
+ for (int i = 1; i < threadCount; ++i)
+ QVERIFY(threads[i].wait(10000));
+ qDebug("locked %d times", int(MoreStressTestThread::lockCount));
+ QCOMPARE(int(MoreStressTestThread::errorCount), 0);
+}
+
+
QTEST_MAIN(tst_QMutex)
#include "tst_qmutex.moc"
diff --git a/tests/auto/qnetworkaddressentry/qnetworkaddressentry.pro b/tests/auto/qnetworkaddressentry/qnetworkaddressentry.pro
index 7b968723cd..885dbf796c 100644
--- a/tests/auto/qnetworkaddressentry/qnetworkaddressentry.pro
+++ b/tests/auto/qnetworkaddressentry/qnetworkaddressentry.pro
@@ -4,5 +4,3 @@ SOURCES += tst_qnetworkaddressentry.cpp
QT = core network
symbian: TARGET.CAPABILITY = NetworkServices
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qnetworkaddressentry/tst_qnetworkaddressentry.cpp b/tests/auto/qnetworkaddressentry/tst_qnetworkaddressentry.cpp
index cf14aabb41..42b9af8dd3 100644
--- a/tests/auto/qnetworkaddressentry/tst_qnetworkaddressentry.cpp
+++ b/tests/auto/qnetworkaddressentry/tst_qnetworkaddressentry.cpp
@@ -97,7 +97,7 @@ void tst_QNetworkAddressEntry::prefixAndNetmask_data()
// IPv4 set:
QHostAddress ipv4(QHostAddress::LocalHost);
- QTest::newRow("v4/0") << ipv4 << QHostAddress(QHostAddress::Any) << 0;
+ QTest::newRow("v4/0") << ipv4 << QHostAddress(QHostAddress::AnyIPv4) << 0;
QTest::newRow("v4/32") << ipv4 << QHostAddress("255.255.255.255") << 32;
QTest::newRow("v4/24") << ipv4 << QHostAddress("255.255.255.0") << 24;
QTest::newRow("v4/23") << ipv4 << QHostAddress("255.255.254.0") << 23;
diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp
index f54dfa3f68..9873c3e357 100644
--- a/tests/auto/qprocess/tst_qprocess.cpp
+++ b/tests/auto/qprocess/tst_qprocess.cpp
@@ -335,7 +335,7 @@ void tst_QProcess::crashTest()
QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
QSignalSpy spy2(process, SIGNAL(finished(int, QProcess::ExitStatus)));
- QVERIFY(process->waitForFinished(5000));
+ QVERIFY(process->waitForFinished(30000));
QCOMPARE(spy.count(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
@@ -372,7 +372,7 @@ void tst_QProcess::crashTest2()
QObject::connect(process, SIGNAL(finished(int)), this, SLOT(exitLoopSlot()));
- QTestEventLoop::instance().enterLoop(5);
+ QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout())
QFAIL("Failed to detect crash : operation timed out");
@@ -673,7 +673,7 @@ void tst_QProcess::exitStatus()
for (int i = 0; i < processList.count(); ++i) {
process->start(processList.at(i));
QVERIFY(process->waitForStarted(5000));
- QVERIFY(process->waitForFinished(5000));
+ QVERIFY(process->waitForFinished(30000));
QCOMPARE(process->exitStatus(), exitStatus.at(i));
}
diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp
index e0680c4257..eb78057b5e 100644
--- a/tests/auto/qrawfont/tst_qrawfont.cpp
+++ b/tests/auto/qrawfont/tst_qrawfont.cpp
@@ -47,7 +47,6 @@
class tst_QRawFont: public QObject
{
Q_OBJECT
-
#if !defined(QT_NO_RAWFONT)
private slots:
void invalidRawFont();
@@ -94,6 +93,11 @@ private slots:
void rawFontSetPixelSize_data();
void rawFontSetPixelSize();
+
+#if defined(Q_WS_X11) || defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+ void multipleRawFontsFromData();
+#endif
+
#endif // QT_NO_RAWFONT
};
@@ -843,6 +847,25 @@ void tst_QRawFont::rawFontSetPixelSize()
QCOMPARE(rawFont.pixelSize(), 24.0);
}
+#if defined(Q_WS_X11) || defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
+void tst_QRawFont::multipleRawFontsFromData()
+{
+ QFile file(QString::fromLatin1(SRCDIR "testfont.ttf"));
+ QRawFont testFont;
+ if (file.open(QIODevice::ReadOnly)) {
+ testFont.loadFromData(file.readAll(), 11, QFont::PreferDefaultHinting);
+ file.close();
+ }
+ file.setFileName(QLatin1String(SRCDIR "testfont_bold_italic.ttf"));
+ QRawFont testFontBoldItalic;
+ if (file.open(QIODevice::ReadOnly))
+ testFontBoldItalic.loadFromData(file.readAll(), 11, QFont::PreferDefaultHinting);
+
+ QVERIFY(testFont.familyName() != (testFontBoldItalic.familyName())
+ || testFont.styleName() != (testFontBoldItalic.styleName()));
+}
+#endif
+
#endif // QT_NO_RAWFONT
QTEST_MAIN(tst_QRawFont)
diff --git a/tests/auto/qregexpvalidator/tst_qregexpvalidator.cpp b/tests/auto/qregexpvalidator/tst_qregexpvalidator.cpp
index d8ef92a439..23cd5b1ef1 100644
--- a/tests/auto/qregexpvalidator/tst_qregexpvalidator.cpp
+++ b/tests/auto/qregexpvalidator/tst_qregexpvalidator.cpp
@@ -115,9 +115,12 @@ void tst_QRegExpValidator::validate()
QFETCH( int, state );
QRegExpValidator rv( 0 );
+ QSignalSpy spy(&rv, SIGNAL(regExpChanged(const QRegExp&)));
+
rv.setRegExp( QRegExp( rx ) );
int dummy;
QCOMPARE( (int)rv.validate( value, dummy ), state );
+ QCOMPARE(spy.count(), 1);
}
QTEST_MAIN(tst_QRegExpValidator)
diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index cc4ab67d53..5f1a6211aa 100644
--- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -92,6 +92,7 @@ private slots:
void escapedTableName();
void whiteSpaceInIdentifiers();
void psqlSchemaTest();
+ void selectAfterUpdate();
private:
void dropTestTables( QSqlDatabase db );
@@ -1467,5 +1468,27 @@ void tst_QSqlRelationalTableModel::psqlSchemaTest()
QVERIFY_SQL(model, select());
}
+void tst_QSqlRelationalTableModel::selectAfterUpdate()
+{
+ QFETCH_GLOBAL(QString, dbName);
+ QSqlDatabase db = QSqlDatabase::database(dbName);
+ CHECK_DATABASE(db);
+
+ QSqlRelationalTableModel model(0, db);
+ model.setTable(reltest1);
+ model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
+ QVERIFY_SQL(model, select());
+ QVERIFY(model.relationModel(2)->rowCount() == 2);
+ {
+ QSqlQuery q(db);
+ QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(3, 'mrs')"));
+ model.relationModel(2)->select();
+ }
+ QVERIFY(model.relationModel(2)->rowCount() == 3);
+ QVERIFY(model.setData(model.index(0,2), 3));
+ QVERIFY(model.submitAll());
+ QCOMPARE(model.data(model.index(0,2)), QVariant("mrs"));
+}
+
QTEST_MAIN(tst_QSqlRelationalTableModel)
#include "tst_qsqlrelationaltablemodel.moc"
diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp
index 451465df0c..e0bc029c71 100644
--- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp
+++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp
@@ -118,6 +118,9 @@ private slots:
void subjectAndIssuerAttributes();
void verify();
+ // helper for verbose test failure messages
+ QString toString(const QList<QSslError>&);
+
// ### add tests for certificate bundles (multiple certificates concatenated into a single
// structure); both PEM and DER formatted
#endif
@@ -907,10 +910,16 @@ void tst_QSslCertificate::verify()
QList<QSslError> errors;
QList<QSslCertificate> toVerify;
+ // Like QVERIFY, but be verbose about the content of `errors' when failing
+#define VERIFY_VERBOSE(A) \
+ QVERIFY2((A), \
+ qPrintable(QString("errors: %1").arg(toString(errors))) \
+ )
+
// Empty chain is unspecified error
errors = QSslCertificate::verify(toVerify);
- QVERIFY(errors.count() == 1);
- QVERIFY(errors[0] == QSslError(QSslError::UnspecifiedError));
+ VERIFY_VERBOSE(errors.count() == 1);
+ VERIFY_VERBOSE(errors[0] == QSslError(QSslError::UnspecifiedError));
errors.clear();
// Verify a valid cert signed by a CA
@@ -920,7 +929,8 @@ void tst_QSslCertificate::verify()
toVerify = QSslCertificate::fromPath(SRCDIR "verify-certs/test-ocsp-good-cert.pem");
errors = QSslCertificate::verify(toVerify);
- QVERIFY(errors.count() == 0);
+ QEXPECT_FAIL("", "QTBUG-20582 fails since ~5am, 27th July 2011", Continue);
+ VERIFY_VERBOSE(errors.count() == 0);
errors.clear();
// Test a blacklisted certificate
@@ -939,8 +949,8 @@ void tst_QSslCertificate::verify()
// This one is expired and untrusted
toVerify = QSslCertificate::fromPath(SRCDIR "more-certificates/cert-large-serial-number.pem");
errors = QSslCertificate::verify(toVerify);
- QVERIFY(errors.contains(QSslError(QSslError::SelfSignedCertificate, toVerify[0])));
- QVERIFY(errors.contains(QSslError(QSslError::CertificateExpired, toVerify[0])));
+ VERIFY_VERBOSE(errors.contains(QSslError(QSslError::SelfSignedCertificate, toVerify[0])));
+ VERIFY_VERBOSE(errors.contains(QSslError(QSslError::CertificateExpired, toVerify[0])));
errors.clear();
toVerify.clear();
@@ -948,23 +958,38 @@ void tst_QSslCertificate::verify()
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-not-ca-cert.pem").first();
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-ocsp-good-cert.pem").first();
errors = QSslCertificate::verify(toVerify);
- QVERIFY(errors.contains(QSslError(QSslError::InvalidCaCertificate, toVerify[1])));
+ VERIFY_VERBOSE(errors.contains(QSslError(QSslError::InvalidCaCertificate, toVerify[1])));
toVerify.clear();
// This one is signed by a valid cert, and the signer is a valid CA
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-is-ca-cert.pem").first();
toVerify << QSslCertificate::fromPath(SRCDIR "verify-certs/test-intermediate-ca-cert.pem").first();
errors = QSslCertificate::verify(toVerify);
- QVERIFY(errors.length() == 0);
+ QEXPECT_FAIL("", "QTBUG-20582 fails since ~5am, 27th July 2011", Continue);
+ VERIFY_VERBOSE(errors.count() == 0);
// Recheck the above with hostname validation
errors = QSslCertificate::verify(toVerify, QLatin1String("example.com"));
- QVERIFY(errors.length() == 0);
+ QEXPECT_FAIL("", "QTBUG-20582 fails since ~5am, 27th July 2011", Continue);
+ VERIFY_VERBOSE(errors.count() == 0);
// Recheck the above with a bad hostname
errors = QSslCertificate::verify(toVerify, QLatin1String("fail.example.com"));
- QVERIFY(errors.contains(QSslError(QSslError::HostNameMismatch, toVerify[0])));
+ VERIFY_VERBOSE(errors.contains(QSslError(QSslError::HostNameMismatch, toVerify[0])));
toVerify.clear();
+
+#undef VERIFY_VERBOSE
+}
+
+QString tst_QSslCertificate::toString(const QList<QSslError>& errors)
+{
+ QStringList errorStrings;
+
+ foreach (const QSslError& error, errors) {
+ errorStrings.append(QLatin1String("\"") + error.errorString() + QLatin1String("\""));
+ }
+
+ return QLatin1String("[ ") + errorStrings.join(QLatin1String(", ")) + QLatin1String(" ]");
}
#endif // QT_NO_OPENSSL
diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp
index 8c725fa109..f7a725c164 100644
--- a/tests/auto/qstring/tst_qstring.cpp
+++ b/tests/auto/qstring/tst_qstring.cpp
@@ -5110,7 +5110,7 @@ void tst_QString::toUpperLower_icu()
void tst_QString::literals()
{
-#if defined(QT_QSTRING_UNICODE_MARKER) && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
+#if defined(QT_UNICODE_LITERAL) && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
QString str(QStringLiteral("abcd"));
QVERIFY(str.length() == 4);
diff --git a/tests/auto/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp
index de7ad656e4..4d453b0585 100644
--- a/tests/auto/qstringbuilder1/stringbuilder.cpp
+++ b/tests/auto/qstringbuilder1/stringbuilder.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include <QtTest/QtTest>
+
#define LITERAL "some literal"
#define LITERAL_LEN (sizeof(LITERAL)-1)
#define LITERAL_EXTRA "some literal" "EXTRA"
@@ -48,6 +50,12 @@
#define UTF8_LITERAL_LEN (sizeof(UTF8_LITERAL)-1)
#define UTF8_LITERAL_EXTRA "s\xc3\xb6m\xc3\xab l\xc3\xaft\xc3\xabr\xc3\xa4l" "EXTRA"
+#ifdef Q_COMPILER_UNICODE_STRINGS
+// "some literal", but replacing all vocals by their umlauted UTF-8 string :)
+#define UNICODE_LITERAL u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l"
+#define UNICODE_LITERAL_LEN ((sizeof(UNICODE_LITERAL) - 1) / 2)
+#define UNICODE_LITERAL_EXTRA u"s\u00f6m\u00eb l\u00eft\u00ebr\u00e4l" "EXTRA"
+#endif
//fix for gcc4.0: if the operator+ does not exist without QT_USE_FAST_OPERATOR_PLUS
#ifndef QT_USE_FAST_CONCATENATION
@@ -68,6 +76,7 @@ void runScenario()
QStringRef stringref(&string, 2, 10);
QLatin1Char achar('c');
QString r2(QLatin1String(LITERAL LITERAL));
+ QString r3 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
QString r;
r = l1literal Q l1literal;
@@ -80,10 +89,23 @@ void runScenario()
QCOMPARE(r, r2);
r = string P l1string;
QCOMPARE(r, r2);
+ r = string Q QStringLiteral(LITERAL);
+ QCOMPARE(r, r2);
+ r = QStringLiteral(LITERAL) Q string;
+ QCOMPARE(r, r2);
+ r = l1string Q QStringLiteral(LITERAL);
+ QCOMPARE(r, r2);
r = string + achar;
QCOMPARE(r, QString(string P achar));
r = achar + string;
QCOMPARE(r, QString(achar P string));
+
+#ifdef Q_COMPILER_UNICODE_STRINGS
+ r = QStringLiteral(UNICODE_LITERAL);
+ r = r Q QStringLiteral(UNICODE_LITERAL);
+ QCOMPARE(r, r3);
+#endif
+
#ifndef QT_NO_CAST_FROM_ASCII
r = string P LITERAL;
QCOMPARE(r, r2);
@@ -96,6 +118,11 @@ void runScenario()
r = string P ba;
QCOMPARE(r, r2);
+ r = string P QByteArrayLiteral(LITERAL);
+ QCOMPARE(r, r2);
+ r = QByteArrayLiteral(LITERAL) P string;
+ QCOMPARE(r, r2);
+
static const char badata[] = LITERAL_EXTRA;
ba = QByteArray::fromRawData(badata, LITERAL_LEN);
r = ba P string;
@@ -109,24 +136,23 @@ void runScenario()
QCOMPARE(QTextCodec::codecForCStrings()->name(), QByteArray("UTF-8"));
string = QString::fromUtf8(UTF8_LITERAL);
- r2 = QString::fromUtf8(UTF8_LITERAL UTF8_LITERAL);
ba = UTF8_LITERAL;
r = string P UTF8_LITERAL;
- QCOMPARE(r.size(), r2.size());
- QCOMPARE(r, r2);
+ QCOMPARE(r.size(), r3.size());
+ QCOMPARE(r, r3);
r = UTF8_LITERAL P string;
- QCOMPARE(r, r2);
+ QCOMPARE(r, r3);
r = ba P string;
- QCOMPARE(r, r2);
+ QCOMPARE(r, r3);
r = string P ba;
- QCOMPARE(r, r2);
+ QCOMPARE(r, r3);
ba = QByteArray::fromRawData(UTF8_LITERAL_EXTRA, UTF8_LITERAL_LEN);
r = ba P string;
- QCOMPARE(r, r2);
+ QCOMPARE(r, r3);
r = string P ba;
- QCOMPARE(r, r2);
+ QCOMPARE(r, r3);
ba = QByteArray(); // empty
r = ba P string;
@@ -152,6 +178,11 @@ void runScenario()
QByteArray superba = ba P ba P LITERAL;
QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
+ ba = QByteArrayLiteral(LITERAL);
+ QCOMPARE(ba, QByteArray(LITERAL));
+ superba = ba P QByteArrayLiteral(LITERAL) P LITERAL;
+ QCOMPARE(superba, QByteArray(LITERAL LITERAL LITERAL));
+
QByteArray testWith0 = ba P "test\0with\0zero" P ba;
QCOMPARE(testWith0, QByteArray(LITERAL "test" LITERAL));
diff --git a/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro b/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro
index ee2b77d63c..62d4908e69 100644
--- a/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro
+++ b/tests/auto/qtconcurrentfilter/qtconcurrentfilter.pro
@@ -3,4 +3,4 @@ DEFINES += QT_STRICT_ITERATORS
SOURCES += tst_qtconcurrentfilter.cpp
QT = core
CONFIG += parallel_test
-CONFIG += parallel_test
+linux*:CONFIG += insignificant_test
diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp
index b566e5cebd..b72e61f374 100644
--- a/tests/auto/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp
@@ -575,7 +575,7 @@ void tst_QTcpServer::addressReusable()
socket.connectToHost(QHostAddress::LocalHost, 49199);
QVERIFY(socket.waitForConnected(5000));
- QVERIFY(process.waitForFinished(5000));
+ QVERIFY(process.waitForFinished(30000));
// Give the system some time.
QTest::qSleep(10);
diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp
index 67c610b21a..f10879d284 100644
--- a/tests/auto/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/qtextedit/tst_qtextedit.cpp
@@ -207,6 +207,8 @@ private slots:
void bidiLogicalMovement_data();
void bidiLogicalMovement();
+ void inputMethodSelection();
+
private:
void createSelection();
int blockCount() const;
@@ -2365,5 +2367,30 @@ void tst_QTextEdit::bidiLogicalMovement()
} while (moved && i >= 0);
}
+void tst_QTextEdit::inputMethodSelection()
+{
+ ed->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+
+ QSignalSpy selectionSpy(ed, SIGNAL(selectionChanged()));
+ QTextCursor cursor = ed->textCursor();
+ cursor.setPosition(0);
+ cursor.setPosition(5, QTextCursor::KeepAnchor);
+ ed->setTextCursor(cursor);
+
+ QCOMPARE(selectionSpy.count(), 1);
+ QCOMPARE(ed->textCursor().selectionStart(), 0);
+ QCOMPARE(ed->textCursor().selectionEnd(), 5);
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 12, 5, QVariant());
+ QInputMethodEvent event("", attributes);
+ QApplication::sendEvent(ed, &event);
+
+ QCOMPARE(selectionSpy.count(), 2);
+ QCOMPARE(ed->textCursor().selectionStart(), 12);
+ QCOMPARE(ed->textCursor().selectionEnd(), 17);
+}
+
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"
diff --git a/tests/auto/qtextscriptengine/qtextscriptengine.pro b/tests/auto/qtextscriptengine/qtextscriptengine.pro
index 1bd80d35b6..0f5076e2ed 100644
--- a/tests/auto/qtextscriptengine/qtextscriptengine.pro
+++ b/tests/auto/qtextscriptengine/qtextscriptengine.pro
@@ -5,5 +5,3 @@ QT += core-private gui-private
HEADERS +=
SOURCES += tst_qtextscriptengine.cpp
INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src
-
-CONFIG+=insignificant_test
diff --git a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp
index 6cbff362bc..cbed675cb7 100644
--- a/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/qtextscriptengine/tst_qtextscriptengine.cpp
@@ -76,9 +76,6 @@
//TESTED_CLASS=
//TESTED_FILES= gui/text/qscriptengine.cpp
-// This test depends on the fonts in the following package being installed:
-// http://people.freedesktop.org/~hausmann/harfbuzz-test-fonts-0.1.tar.bz2
-
class tst_QTextScriptEngine : public QObject
{
Q_OBJECT
@@ -89,6 +86,7 @@ public:
public slots:
+ void initTestCase();
void init();
void cleanup();
private slots:
@@ -111,9 +109,13 @@ private slots:
void mirroredChars_data();
void mirroredChars();
+
+private:
+ bool haveTestFonts;
};
tst_QTextScriptEngine::tst_QTextScriptEngine()
+ : haveTestFonts(qgetenv("QT_HAVE_TEST_FONTS") == QByteArray("1"))
{
}
@@ -121,6 +123,21 @@ tst_QTextScriptEngine::~tst_QTextScriptEngine()
{
}
+void tst_QTextScriptEngine::initTestCase()
+{
+#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ qWarning(
+ "Some of these tests depend on the internals of some test fonts which are not freely "
+ "distributable.\n"
+ "These tests will be skipped.\n"
+ "If you have the fonts available, set QT_HAVE_TEST_FONTS=1 in your environment and "
+ "run the test again."
+ );
+ }
+#endif
+}
+
void tst_QTextScriptEngine::init()
{
}
@@ -184,6 +201,10 @@ static bool shaping( const QFont &f, const ShapeTable *s)
void tst_QTextScriptEngine::devanagari()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Devanagari).contains("Raghindi")) {
QFont f("Raghindi");
@@ -233,7 +254,7 @@ void tst_QTextScriptEngine::devanagari()
++s;
}
} else {
- QSKIP("couln't find Raghindi", SkipAll);
+ QSKIP("couldn't find Raghindi", SkipAll);
}
}
@@ -296,6 +317,10 @@ void tst_QTextScriptEngine::devanagari()
void tst_QTextScriptEngine::bengali()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Bengali).contains("Akaash")) {
QFont f("Akaash");
@@ -403,7 +428,7 @@ void tst_QTextScriptEngine::bengali()
++s;
}
} else {
- QSKIP("couln't find Akaash", SkipAll);
+ QSKIP("couldn't find Akaash", SkipAll);
}
}
{
@@ -508,7 +533,7 @@ void tst_QTextScriptEngine::bengali()
++s;
}
} else {
- QSKIP("couln't find Mukti", SkipAll);
+ QSKIP("couldn't find Mukti", SkipAll);
}
}
{
@@ -536,7 +561,7 @@ void tst_QTextScriptEngine::bengali()
++s;
}
} else {
- QSKIP("couln't find Likhan", SkipAll);
+ QSKIP("couldn't find Likhan", SkipAll);
}
}
#else
@@ -547,6 +572,10 @@ void tst_QTextScriptEngine::bengali()
void tst_QTextScriptEngine::gurmukhi()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Gurmukhi).contains("Lohit Punjabi")) {
QFont f("Lohit Punjabi");
@@ -563,7 +592,7 @@ void tst_QTextScriptEngine::gurmukhi()
++s;
}
} else {
- QSKIP("couln't find Lohit Punjabi", SkipAll);
+ QSKIP("couldn't find Lohit Punjabi", SkipAll);
}
}
#endif
@@ -572,6 +601,10 @@ void tst_QTextScriptEngine::gurmukhi()
void tst_QTextScriptEngine::oriya()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Oriya).contains("utkal")) {
QFont f("utkal");
@@ -600,7 +633,7 @@ void tst_QTextScriptEngine::oriya()
++s;
}
} else {
- QSKIP("couln't find utkal", SkipAll);
+ QSKIP("couldn't find utkal", SkipAll);
}
}
#else
@@ -612,6 +645,10 @@ void tst_QTextScriptEngine::oriya()
void tst_QTextScriptEngine::tamil()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Tamil).contains("AkrutiTml1")) {
QFont f("AkrutiTml1");
@@ -677,7 +714,7 @@ void tst_QTextScriptEngine::tamil()
++s;
}
} else {
- QSKIP("couln't find AkrutiTml1", SkipAll);
+ QSKIP("couldn't find AkrutiTml1", SkipAll);
}
}
#else
@@ -689,6 +726,10 @@ void tst_QTextScriptEngine::tamil()
void tst_QTextScriptEngine::telugu()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Telugu).contains("Pothana2000")) {
QFont f("Pothana2000");
@@ -725,7 +766,7 @@ void tst_QTextScriptEngine::telugu()
++s;
}
} else {
- QSKIP("couln't find Pothana2000", SkipAll);
+ QSKIP("couldn't find Pothana2000", SkipAll);
}
}
#else
@@ -772,7 +813,7 @@ void tst_QTextScriptEngine::kannada()
++s;
}
} else {
- QSKIP("couln't find Sampige", SkipAll);
+ QSKIP("couldn't find Sampige", SkipAll);
}
}
{
@@ -803,7 +844,7 @@ void tst_QTextScriptEngine::kannada()
++s;
}
} else {
- QSKIP("couln't find Tunga", SkipAll);
+ QSKIP("couldn't find Tunga", SkipAll);
}
}
#else
@@ -816,6 +857,10 @@ void tst_QTextScriptEngine::kannada()
void tst_QTextScriptEngine::malayalam()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Malayalam).contains("AkrutiMal2")) {
QFont f("AkrutiMal2");
@@ -864,7 +909,7 @@ void tst_QTextScriptEngine::malayalam()
++s;
}
} else {
- QSKIP("couln't find AkrutiMal2", SkipAll);
+ QSKIP("couldn't find AkrutiMal2", SkipAll);
}
}
{
@@ -892,7 +937,7 @@ void tst_QTextScriptEngine::malayalam()
++s;
}
} else {
- QSKIP("couln't find Rachana", SkipAll);
+ QSKIP("couldn't find Rachana", SkipAll);
}
}
@@ -904,6 +949,10 @@ void tst_QTextScriptEngine::malayalam()
void tst_QTextScriptEngine::sinhala()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Sinhala).contains("Malithi Web")) {
QFont f("Malithi Web");
@@ -930,7 +979,7 @@ void tst_QTextScriptEngine::sinhala()
++s;
}
} else {
- QSKIP("couln't find Malithi Web", SkipAll);
+ QSKIP("couldn't find Malithi Web", SkipAll);
}
}
#else
@@ -942,6 +991,10 @@ void tst_QTextScriptEngine::sinhala()
void tst_QTextScriptEngine::khmer()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Khmer).contains("Khmer OS")) {
QFont f("Khmer OS");
@@ -974,7 +1027,7 @@ void tst_QTextScriptEngine::khmer()
++s;
}
} else {
- QSKIP("couln't find Khmer OS", SkipAll);
+ QSKIP("couldn't find Khmer OS", SkipAll);
}
}
#else
@@ -985,6 +1038,10 @@ void tst_QTextScriptEngine::khmer()
void tst_QTextScriptEngine::linearB()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Any).contains("Penuturesu")) {
QFont f("Penuturesu");
@@ -1001,7 +1058,7 @@ void tst_QTextScriptEngine::linearB()
++s;
}
} else {
- QSKIP("couln't find Penuturesu", SkipAll);
+ QSKIP("couldn't find Penuturesu", SkipAll);
}
}
#else
@@ -1060,6 +1117,10 @@ static bool decomposedShaping( const QFont &f, const QChar &ch)
void tst_QTextScriptEngine::greek()
{
#if defined(Q_WS_X11)
+ if (!haveTestFonts) {
+ QSKIP("Test fonts are not available", SkipAll);
+ }
+
{
if (QFontDatabase().families(QFontDatabase::Any).contains("DejaVu Sans")) {
QFont f("DejaVu Sans");
@@ -1075,7 +1136,7 @@ void tst_QTextScriptEngine::greek()
QVERIFY( decomposedShaping(f, QChar(uc)) );
}
} else {
- QSKIP("couln't find DejaVu Sans", SkipAll);
+ QSKIP("couldn't find DejaVu Sans", SkipAll);
}
}
@@ -1111,7 +1172,7 @@ void tst_QTextScriptEngine::greek()
++s;
}
} else {
- QSKIP("couln't find SBL_grk", SkipAll);
+ QSKIP("couldn't find SBL_grk", SkipAll);
}
}
#else
diff --git a/tests/auto/qwaitcondition/tst_qwaitcondition.cpp b/tests/auto/qwaitcondition/tst_qwaitcondition.cpp
index c677d17fbe..6545df9189 100644
--- a/tests/auto/qwaitcondition/tst_qwaitcondition.cpp
+++ b/tests/auto/qwaitcondition/tst_qwaitcondition.cpp
@@ -491,7 +491,7 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (thread[y].wait(exited > 0 ? 3 : 1000)) {
+ if (thread[y].wait(exited > 0 ? 10 : 1000)) {
thread_exited[y] = TRUE;
++exited;
}
@@ -535,7 +535,7 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (rwthread[y].wait(exited > 0 ? 3 : 1000)) {
+ if (rwthread[y].wait(exited > 0 ? 10 : 1000)) {
thread_exited[y] = TRUE;
++exited;
}
@@ -587,7 +587,7 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (thread[y].wait(exited > 0 ? 3 : 1000)) {
+ if (thread[y].wait(exited > 0 ? 10 : 1000)) {
thread_exited[y] = TRUE;
++exited;
}
@@ -633,7 +633,7 @@ void tst_QWaitCondition::wakeOne()
for (int y = 0; y < ThreadCount; ++y) {
if (thread_exited[y])
continue;
- if (rwthread[y].wait(exited > 0 ? 3 : 1000)) {
+ if (rwthread[y].wait(exited > 0 ? 10 : 1000)) {
thread_exited[y] = TRUE;
++exited;
}
diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
index 05a15750c1..05e184d0c2 100644
--- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
+++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
@@ -151,7 +151,6 @@ void tst_QMutex::noThread_data()
QTest::addColumn<int>("t");
QTest::newRow("noLock") << 1;
- QTest::newRow("QMutexInline") << 2;
QTest::newRow("QMutex") << 3;
QTest::newRow("QMutexLocker") << 4;
}
@@ -172,16 +171,6 @@ void tst_QMutex::noThread()
}
}
break;
- case 2:
- QBENCHMARK {
- count = 0;
- for (int i = 0; i < N; i++) {
- mtx.lockInline();
- count++;
- mtx.unlockInline();
- }
- }
- break;
case 3:
QBENCHMARK {
count = 0;
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index cde4ddd833..e980755305 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -221,6 +221,12 @@ Configure::Configure(int& argc, char** argv)
createpackage_bat.close();
}
+ QFile configtests(buildPath + "/bin/qtmodule-configtests");
+ if (configtests.open(QFile::WriteOnly)) {
+ QTextStream stream(&configtests);
+ stream << "#!/usr/bin/perl -w" << endl
+ << "require \"" << sourcePath + "/bin/qtmodule-configtests\";" << endl;
+ }
// For Windows CE and shadow builds we need to copy these to the
// build directory.
QFile::copy(sourcePath + "/bin/setcepaths.bat" , buildPath + "/bin/setcepaths.bat");