diff options
Diffstat (limited to 'tests')
146 files changed, 5488 insertions, 6770 deletions
diff --git a/tests/auto/android/runtests.pl b/tests/auto/android/runtests.pl index 7bb6833859..55e1a224d8 100755 --- a/tests/auto/android/runtests.pl +++ b/tests/auto/android/runtests.pl @@ -79,6 +79,7 @@ GetOptions('h|help' => \$help , 'ant=s' => \$ant_tool , 'strip=s' => \$strip_tool , 'readelf=s' => \$readelf_tool + , 'testcase=s' => \$testcase ) or pod2usage(2); pod2usage(1) if $help; pod2usage(-verbose => 2) if $man; @@ -232,6 +233,7 @@ if ($deploy_qt) print ("cp -L $_ $temp_dir/lib\n"); system("cp -L $_ $temp_dir/lib"); } + system("cp -L $android_ndk_dir/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/libgnustl_shared.so $temp_dir/lib"); system("cp -a plugins $temp_dir"); system("cp -a imports $temp_dir"); system("cp -a qml $temp_dir"); @@ -252,7 +254,14 @@ print "Building $tests_dir \n"; system("make distclean") if ($make_clean); system("$qmake_path CONFIG-=QTDIR_build -r") == 0 or die "Can't run qmake\n"; #exec qmake system("make -j$jobs") == 0 or warn "Can't build all tests\n"; #exec make -my $testsFiles=`find . -name libtst_*.so`; # only tests + +my $testsFiles = ""; +if ($testcase) { + $testsFiles=`find . -name libtst_$testcase.so`; # only tests +} else { + $testsFiles=`find . -name libtst_*.so`; # only tests +} + foreach (split("\n",$testsFiles)) { chomp; #remove white spaces diff --git a/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java b/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java index 6242f55488..ed190fdc1b 100644 --- a/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java +++ b/tests/auto/android/src/org/qtproject/qt5/android/QtActivity.java @@ -62,9 +62,9 @@ public class QtActivity extends Activity { QtNative.loadQtLibraries(libs); // start application - final String envPaths = "NECESSITAS_API_LEVEL=2\tHOME=" + getDir("files", MODE_WORLD_WRITEABLE).getAbsolutePath() + - "\tTMPDIR=" + getDir("files", MODE_WORLD_WRITEABLE).getAbsolutePath() + - "\tCACHE_PATH=" + getDir("files", MODE_WORLD_WRITEABLE).getAbsolutePath(); + final String envPaths = "NECESSITAS_API_LEVEL=2\tHOME=" + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE).getAbsolutePath() + + "\tTMPDIR=" + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE).getAbsolutePath() + + "\tCACHE_PATH=" + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE).getAbsolutePath(); if (environment != null && environment.length() > 0) environment = envPaths + "\t" + environment; else @@ -102,6 +102,7 @@ public class QtActivity extends Activity { } if (getIntent().getExtras().containsKey("lib_name")) { mainLib = getIntent().getExtras().getString("lib_name"); + libraryList.add(mainLib); int slash = mainLib.lastIndexOf("/"); if (slash >= 0) { nativeLibDir = mainLib.substring(0, slash+1); @@ -120,6 +121,7 @@ public class QtActivity extends Activity { // TODO Auto-generated catch block e.printStackTrace(); } + finish(); System.exit(0); } String[] libs = new String[libraryList.size()]; @@ -136,7 +138,7 @@ public class QtActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getDir("files", MODE_WORLD_WRITEABLE); + getDir("files", MODE_WORLD_WRITEABLE | MODE_WORLD_READABLE); requestWindowFeature(Window.FEATURE_NO_TITLE); m_quitApp = true; QtNative.setMainActivity(this); diff --git a/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java b/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java index d9995e3178..a61543d31a 100644 --- a/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java +++ b/tests/auto/android/src/org/qtproject/qt5/android/QtNative.java @@ -164,7 +164,8 @@ public class QtNative extends Application m_displayMetricsDesktopWidthPixels, m_displayMetricsDesktopHeightPixels, m_displayMetricsXDpi, - m_displayMetricsYDpi); + m_displayMetricsYDpi, + 1.0); startQtApplication(f.getAbsolutePath()+"\t"+params, environment); m_started = true; } @@ -183,7 +184,7 @@ public class QtNative extends Application synchronized (m_mainActivityMutex) { if (m_started) { - setDisplayMetrics(screenWidthPixels, screenHeightPixels, desktopWidthPixels, desktopHeightPixels, XDpi, YDpi); + setDisplayMetrics(screenWidthPixels, screenHeightPixels, desktopWidthPixels, desktopHeightPixels, XDpi, YDpi, 1.0); } else { m_displayMetricsScreenWidthPixels = screenWidthPixels; m_displayMetricsScreenHeightPixels = screenHeightPixels; @@ -379,8 +380,12 @@ public class QtNative extends Application // screen methods public static native void setDisplayMetrics(int screenWidthPixels, - int screenHeightPixels, int desktopWidthPixels, - int desktopHeightPixels, double XDpi, double YDpi); + int screenHeightPixels, + int desktopWidthPixels, + int desktopHeightPixels, + double XDpi, + double YDpi, + double scaledDensity); public static native void handleOrientationChanged(int newOrientation); // screen methods diff --git a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp index 1f57e38b44..4fcc46efab 100644 --- a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp +++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp @@ -361,7 +361,7 @@ void tst_QIpAddress::parseIp6() #endif Ip6 result; - bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()); + bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()) == 0; QVERIFY(ok); QCOMPARE(result, expected); } @@ -441,7 +441,7 @@ void tst_QIpAddress::invalidParseIp6() #endif Ip6 result; - bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()); + bool ok = QIPAddressUtils::parseIp6(result.u8, address.constBegin(), address.constEnd()) == 0; QVERIFY(!ok); } diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index f94c8eac4f..501dde1ba5 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -166,7 +166,7 @@ void tst_qstandardpaths::testCustomLocations() void tst_qstandardpaths::enableTestMode() { QVERIFY(!QStandardPaths::isTestModeEnabled()); - QStandardPaths::enableTestMode(true); + QStandardPaths::setTestModeEnabled(true); QVERIFY(QStandardPaths::isTestModeEnabled()); #ifdef Q_XDG_PLATFORM @@ -204,7 +204,7 @@ void tst_qstandardpaths::enableTestMode() // On Windows, what should "Program Files" become, in test mode? //testLocations.insert(QStandardPaths::ApplicationsLocation, QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); - QStandardPaths::enableTestMode(false); + QStandardPaths::setTestModeEnabled(false); for (LocationHash::const_iterator it = testLocations.constBegin(); it != testLocations.constEnd(); ++it) QVERIFY2(QStandardPaths::writableLocation(it.key()) != it.value(), qPrintable(it.value())); diff --git a/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp index 40621957ce..db2a5b53fd 100644 --- a/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp +++ b/tests/auto/corelib/io/qtextstream/readAllStdinProcess/main.cpp @@ -40,13 +40,11 @@ ****************************************************************************/ -#include <QtCore/QCoreApplication> #include <QtCore/QTextStream> -#include <QtCore/QDebug> +#include <stdio.h> -int main(int argc, char **argv) +int main(int, char**) { - QCoreApplication a(argc, argv); - qDebug() << QTextStream(stdin).readAll(); + fprintf(stderr, "%s\n", QTextStream(stdin).readAll().toLatin1().constData()); return 0; } diff --git a/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp b/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp index e36a2aeda8..cb4e75c6a2 100644 --- a/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp +++ b/tests/auto/corelib/io/qtextstream/stdinProcess/main.cpp @@ -40,17 +40,16 @@ ****************************************************************************/ -#include <QtCore/QCoreApplication> #include <QtCore/QTextStream> +#include <stdio.h> -int main(int argc, char **argv) +int main(int, char**) { - QCoreApplication a(argc, argv); QTextStream qin(stdin); if (!qin.atEnd()) { - int a, b, c; - qin >> a >> b >> c; - qDebug("%d %d %d", a, b, c); + int a, b, c; + qin >> a >> b >> c; + fprintf(stderr, "%d %d %d\n", a, b, c); } return 0; } diff --git a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp index 56c07f1590..c19e80bff3 100644 --- a/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/io/qtextstream/tst_qtextstream.cpp @@ -1425,8 +1425,7 @@ void tst_QTextStream::readAllFromStdin() stdinProcess.closeWriteChannel(); QVERIFY(stdinProcess.waitForFinished(5000)); - QChar quoteChar('"'); - QCOMPARE(stream.readAll(), QString::fromLatin1("%1hello world%2 \n").arg(quoteChar).arg(quoteChar)); + QCOMPARE(stream.readAll(), QString::fromLatin1("hello world\n")); } // ------------------------------------------------------------------------------ diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 2a506ef8e2..2817e6d22c 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -111,6 +111,8 @@ private slots: void percentEncoding(); void swap(); void symmetry(); + void ipvfuture_data(); + void ipvfuture(); void ipv6_data(); void ipv6(); void ipv6_2_data(); @@ -160,6 +162,8 @@ private slots: void binaryData(); void fromUserInput_data(); void fromUserInput(); + void fileName_data(); + void fileName(); void isEmptyForEncodedUrl(); void toEncodedNotUsingUninitializedPath(); void emptyAuthorityRemovesExistingAuthority(); @@ -291,6 +295,8 @@ void tst_QUrl::comparison() QVERIFY(url1 == url2); QVERIFY(!(url1 < url2)); QVERIFY(!(url2 < url1)); + QVERIFY(url1.matches(url2, QUrl::None)); + QVERIFY(url1.matches(url2, QUrl::StripTrailingSlash)); // 6.2.2 Syntax-based Normalization QUrl url3 = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D"); @@ -298,6 +304,20 @@ void tst_QUrl::comparison() QEXPECT_FAIL("", "Normalization not implemented, will probably not be implemented like this", Continue); QCOMPARE(url3, url4); + QUrl url3bis = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D/"); + QUrl url3bisNoSlash = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D"); + QUrl url4bis = QUrl::fromEncoded("example://a/.//b/../b/c//%7Bfoo%7D/"); + QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments), url3bis); + QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments | QUrl::StripTrailingSlash), url3bisNoSlash); + QVERIFY(url3bis.matches(url4bis, QUrl::NormalizePathSegments)); + QVERIFY(!url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments)); + QVERIFY(url3bisNoSlash.matches(url4bis, QUrl::NormalizePathSegments | QUrl::StripTrailingSlash)); + + QUrl url4EncodedDots = QUrl("example://a/.//b/%2E%2E%2F/b/c/"); + QCOMPARE(QString::fromLatin1(url4EncodedDots.toEncoded()), QString::fromLatin1("example://a/.//b/..%2F/b/c/")); + QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/")); + QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a/b/..%2F/b/c/")); + // 6.2.2.1 Make sure hexdecimal characters in percent encoding are // treated case-insensitively QUrl url5; @@ -312,6 +332,59 @@ void tst_QUrl::comparison() url8.setEncodedQuery("a=c"); QVERIFY(url7 != url8); QVERIFY(url7 < url8); + + // Trailing slash difference + QUrl url9("http://qt-project.org/path/"); + QUrl url9NoSlash("http://qt-project.org/path"); + QVERIFY(!(url9 == url9NoSlash)); + QVERIFY(!url9.matches(url9NoSlash, QUrl::None)); + QVERIFY(url9.matches(url9NoSlash, QUrl::StripTrailingSlash)); + + // RemoveFilename + QUrl url10("http://qt-project.org/file"); + QUrl url10bis("http://qt-project.org/otherfile"); + QVERIFY(!(url10 == url10bis)); + QVERIFY(!url10.matches(url10bis, QUrl::None)); + QVERIFY(!url10.matches(url10bis, QUrl::StripTrailingSlash)); + QVERIFY(url10.matches(url10bis, QUrl::RemoveFilename)); + + // RemoveAuthority + QUrl authUrl1("x://host/a/b"); + QUrl authUrl2("x://host/a/"); + QUrl authUrl3("x:/a/b"); + QVERIFY(authUrl1.matches(authUrl2, QUrl::RemoveFilename)); + QCOMPARE(authUrl1.adjusted(QUrl::RemoveAuthority), authUrl3.adjusted(QUrl::RemoveAuthority)); + QVERIFY(authUrl1.matches(authUrl3, QUrl::RemoveAuthority)); + QCOMPARE(authUrl2.adjusted(QUrl::RemoveAuthority | QUrl::RemoveFilename), authUrl3.adjusted(QUrl::RemoveAuthority | QUrl::RemoveFilename)); + QVERIFY(authUrl2.matches(authUrl3, QUrl::RemoveAuthority | QUrl::RemoveFilename)); + QVERIFY(authUrl3.matches(authUrl2, QUrl::RemoveAuthority | QUrl::RemoveFilename)); + + QUrl hostUrl1("file:/foo"); + QUrl hostUrl2("file:///foo"); + QVERIFY(hostUrl1 == hostUrl2); + QVERIFY(hostUrl1.matches(hostUrl2, QUrl::None)); + QVERIFY(hostUrl1.matches(hostUrl2, QUrl::RemoveAuthority)); + + // RemovePassword + QUrl passUrl1("http://user:pass@host/"); + QUrl passUrl2("http://user:PASS@host/"); + QVERIFY(!(passUrl1 == passUrl2)); + QVERIFY(passUrl1 != passUrl2); + QVERIFY(!passUrl1.matches(passUrl2, QUrl::None)); + QVERIFY(passUrl1.matches(passUrl2, QUrl::RemovePassword)); + + // RemoveQuery, RemoveFragment + QUrl queryFragUrl1("http://host/file?query#fragment"); + QUrl queryFragUrl2("http://host/file?q2#f2"); + QUrl queryFragUrl3("http://host/file"); + QVERIFY(!(queryFragUrl1 == queryFragUrl2)); + QVERIFY(queryFragUrl1 != queryFragUrl2); + QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::None)); + QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveQuery)); + QVERIFY(!queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveFragment)); + QVERIFY(queryFragUrl1.matches(queryFragUrl2, QUrl::RemoveQuery | QUrl::RemoveFragment)); + QVERIFY(queryFragUrl1.matches(queryFragUrl3, QUrl::RemoveQuery | QUrl::RemoveFragment)); + QVERIFY(queryFragUrl3.matches(queryFragUrl1, QUrl::RemoveQuery | QUrl::RemoveFragment)); } void tst_QUrl::comparison2_data() @@ -685,8 +758,8 @@ void tst_QUrl::setUrl() QVERIFY(url.isValid()); QCOMPARE(url.scheme(), QString("data")); QCOMPARE(url.host(), QString()); - QCOMPARE(url.path(), QString("text/javascript,d5 = 'five\\u0027s';")); - QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20=%20'five%5Cu0027s';"); + QCOMPARE(url.path(), QString("text/javascript,d5 %3D 'five\\u0027s'%3B")); + QCOMPARE(url.encodedPath().constData(), "text/javascript,d5%20%3D%20'five%5Cu0027s'%3B"); } { @@ -946,8 +1019,12 @@ void tst_QUrl::toString() QFETCH(uint, options); QFETCH(QString, string); + QUrl::FormattingOptions opt(options); + QUrl url(urlString); - QCOMPARE(url.toString(QUrl::FormattingOptions(options)), string); + QCOMPARE(url.toString(opt), string); + + QCOMPARE(url.adjusted(opt).toString(), string); } void tst_QUrl::toAndFromStringList_data() @@ -1498,17 +1575,17 @@ void tst_QUrl::relative() void tst_QUrl::percentEncoding_data() { + // This test is limited. It's superseded by componentEncodings below QTest::addColumn<QString>("original"); QTest::addColumn<QByteArray>("encoded"); QTest::newRow("test_01") << QString::fromLatin1("sdfsdf") << QByteArray("sdfsdf"); QTest::newRow("test_02") << QString::fromUtf8("æss") << QByteArray("%C3%A6ss"); - // not unreserved or reserved - QTest::newRow("test_03") << QString::fromLatin1("{}") << QByteArray("%7B%7D"); } void tst_QUrl::percentEncoding() { + // This test is limited. It's superseded by componentEncodings below QFETCH(QString, original); QFETCH(QByteArray, encoded); @@ -1583,21 +1660,83 @@ void tst_QUrl::symmetry() { QString urlString = QString::fromLatin1("http://desktop:33326/upnp/{32f525a6-6f31-426e-91ca-01c2e6c2c57e}"); + QString encodedUrlString = QString("http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D"); QUrl urlPreviewList(urlString); - QCOMPARE(urlPreviewList.toString(), urlString); + QCOMPARE(urlPreviewList.toString(), encodedUrlString); QByteArray b = urlPreviewList.toEncoded(); - QCOMPARE(b.constData(), "http://desktop:33326/upnp/%7B32f525a6-6f31-426e-91ca-01c2e6c2c57e%7D"); - QCOMPARE(QUrl::fromEncoded(b).toString(), urlString); - QCOMPARE(QUrl(b).toString(), urlString); + QCOMPARE(b.constData(), encodedUrlString.toLatin1().constData()); + QCOMPARE(QUrl::fromEncoded(b).toString(), encodedUrlString); + QCOMPARE(QUrl(b).toString(), encodedUrlString); } { QString urlString = QString::fromLatin1("http://desktop:53423/deviceDescription?uuid={7977c17b-00bf-4af9-894e-fed28573c3a9}"); + QString encodedUrlString = QString("http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D"); QUrl urlPreviewList(urlString); - QCOMPARE(urlPreviewList.toString(), urlString); + QCOMPARE(urlPreviewList.toString(), encodedUrlString); QByteArray b = urlPreviewList.toEncoded(); - QCOMPARE(b.constData(), "http://desktop:53423/deviceDescription?uuid=%7B7977c17b-00bf-4af9-894e-fed28573c3a9%7D"); - QCOMPARE(QUrl::fromEncoded(b).toString(), urlString); - QCOMPARE(QUrl(b).toString(), urlString); + QCOMPARE(b.constData(), encodedUrlString.toLatin1().constData()); + QCOMPARE(QUrl::fromEncoded(b).toString(), encodedUrlString); + QCOMPARE(QUrl(b).toString(), encodedUrlString); + } +} + +void tst_QUrl::ipvfuture_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<bool>("isValid"); + QTest::addColumn<QString>("output"); + + // No one uses IPvFuture yet, so we have no clue what it might contain + // We're just testing that it can hold what the RFC says it should hold: + // IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) + QTest::newRow("missing-version-dot") << "x://[v]" << false; + QTest::newRow("missing-version") << "x://[v.]" << false; + QTest::newRow("missing-version-2") << "x://[v.1234]" << false; + QTest::newRow("missing-dot") << "x://[v7]" << false; + QTest::newRow("missing-dot-2") << "x://[v71234]" << false; + QTest::newRow("missing-data") << "x://[v7.]" << false; + QTest::newRow("non-hex-version") << "x://[vz.1234]" << false; + + QTest::newRow("digit-ver") << "x://[v7.1]" << true << "x://[v7.1]"; + QTest::newRow("lowercase-hex-ver") << "x://[va.1]" << true << "x://[vA.1]"; + QTest::newRow("lowercase-hex-ver") << "x://[vA.1]" << true << "x://[vA.1]"; + + QTest::newRow("data-digits") << "x://[v7.1234]" << true << "x://[v7.1234]"; + QTest::newRow("data-unreserved") << "x://[v7.hello~-WORLD_.com]" << true << "x://[v7.hello~-WORLD_.com]"; + QTest::newRow("data-sub-delims-colon") << "x://[v7.!$&'()*+,;=:]" << true << "x://[v7.!$&'()*+,;=:]"; + + // we're using the tolerant parser + QTest::newRow("data-encoded-digits") << "x://[v7.%31%32%33%34]" << true << "x://[v7.1234]"; + QTest::newRow("data-encoded-unreserved") << "x://[v7.%7E%2D%54%5f%2E]" << true << "x://[v7.~-T_.]"; + QTest::newRow("data-encoded-sub-delims-colon") << "x://[v7.%21%24%26%27%28%29%2A%2B%2C%3B%3D%3A]" << true << "x://[v7.!$&'()*+,;=:]"; + + // should we test "[%76%37%2ex]" -> "[v7.x]" ? + + QTest::newRow("data-invalid-space") << "x://[v7.%20]" << false; + QTest::newRow("data-invalid-control") << "x://[v7.\x7f]" << false; + QTest::newRow("data-invalid-other-1") << "x://[v7.{1234}]" << false; + QTest::newRow("data-invalid-other-2") << "x://[v7.<hello>]" << false; + QTest::newRow("data-invalid-unicode") << "x://[v7.æøå]" << false; + QTest::newRow("data-invalid-percent") << "x://[v7.%]" << false; + QTest::newRow("data-invalid-percent-percent") << "x://[v7.%25]" << false; +} + +void tst_QUrl::ipvfuture() +{ + QFETCH(QString, input); + QFETCH(bool, isValid); + + QUrl url(input); + if (isValid) { + QVERIFY2(url.isValid(), qPrintable(url.errorString())); + + QFETCH(QString, output); + QCOMPARE(url.toString(), output); + + QUrl url2(output); + QCOMPARE(url2, url); + } else { + QVERIFY(!url.isValid()); } } @@ -1641,6 +1780,9 @@ void tst_QUrl::ipv6_data() QTest::newRow("case :,") << QString::fromLatin1("//[:,]") << false << ""; QTest::newRow("case ::bla") << QString::fromLatin1("//[::bla]") << false << ""; QTest::newRow("case v4-mapped") << "//[0:0:0:0:0:ffff:7f00:1]" << true << "//[::ffff:127.0.0.1]"; + + QTest::newRow("encoded-digit") << "//[::%31]" << true << "//[::1]"; + QTest::newRow("encoded-colon") << "//[%3A%3A]" << true << "//[::]"; } void tst_QUrl::ipv6() @@ -1932,9 +2074,14 @@ void tst_QUrl::strictParser_data() QTest::newRow("invalid-regname") << "http://bad<hostname>" << "Invalid hostname (contains invalid characters)"; QTest::newRow("invalid-regname-2") << "http://b%61d" << "Invalid hostname (contains invalid characters)"; QTest::newRow("invalid-ipv6") << "http://[:::]" << "Invalid IPv6 address"; + QTest::newRow("invalid-ipv6-char1") << "http://[::g]" << "Invalid IPv6 address (character 'g' not permitted)"; + QTest::newRow("invalid-ipv6-char2") << "http://[z::]" << "Invalid IPv6 address (character 'z' not permitted)"; QTest::newRow("invalid-ipvfuture-1") << "http://[v7]" << "Invalid IPvFuture address"; QTest::newRow("invalid-ipvfuture-2") << "http://[v7.]" << "Invalid IPvFuture address"; QTest::newRow("invalid-ipvfuture-3") << "http://[v789]" << "Invalid IPvFuture address"; + QTest::newRow("invalid-ipvfuture-char1") << "http://[v7.^]" << "Invalid IPvFuture address"; + QTest::newRow("invalid-encoded-ipv6") << "x://[%3a%3a%31]" << "Invalid IPv6 address"; + QTest::newRow("invalid-encoded-ipvfuture") << "x://[v7.%7E%2D%54%5f%2E]" << "Invalid IPvFuture address"; QTest::newRow("unbalanced-brackets") << "http://[ff02::1" << "Expected ']' to match '[' in hostname"; // invalid hostnames happen in TolerantMode too @@ -2035,35 +2182,22 @@ void tst_QUrl::tolerantParser() url.setUrl("http://foo.bar/[image][1].jpg"); QVERIFY(url.isValid()); QVERIFY(!url.toString().isEmpty()); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); - QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg")); + QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg")); QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg")); - url.setUrl("[].jpg"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg")); - QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg")); - QCOMPARE(url.toString(), QString("[].jpg")); - - url.setUrl("/some/[path]/[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D")); - QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D")); - QCOMPARE(url.toString(), QString("/some/[path]/[]")); + url.setUrl("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"); + QVERIFY(url.isValid()); + QVERIFY(!url.toString().isEmpty()); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); url.setUrl("//[::56:56:56:56:56:56:56]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]")); QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]")); QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]")); - url.setUrl("//[::56:56:56:56:56:56:56]#[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); - QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]#%5B%5D")); - QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]#[]")); - - url.setUrl("//[::56:56:56:56:56:56:56]?[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]")); - QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]?[]")); - QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]?[]")); - // invoke the tolerant parser's error correction url.setUrl("%hello.com/f%"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%25hello.com/f%25")); @@ -2076,38 +2210,24 @@ void tst_QUrl::tolerantParser() url.setEncodedUrl("http://foo.bar/[image][1].jpg"); QVERIFY(url.isValid()); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); - QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/[image][1].jpg")); + QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/[image][1].jpg")); QCOMPARE(url.toString(), QString("http://foo.bar/[image][1].jpg")); - url.setEncodedUrl("[].jpg"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("%5B%5D.jpg")); - QCOMPARE(url.toEncoded(), QByteArray("%5B%5D.jpg")); - QCOMPARE(url.toString(), QString("[].jpg")); - - url.setEncodedUrl("/some/[path]/[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("/some/%5Bpath%5D/%5B%5D")); - QCOMPARE(url.toEncoded(), QByteArray("/some/%5Bpath%5D/%5B%5D")); - QCOMPARE(url.toString(), QString("/some/[path]/[]")); + url.setEncodedUrl("http://foo.bar/%5Bimage%5D%5B1%5D.jpg"); + QVERIFY(url.isValid()); + QCOMPARE(url.toString(QUrl::FullyEncoded), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toEncoded(), QByteArray("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); + QCOMPARE(url.toString(), QString("http://foo.bar/%5Bimage%5D%5B1%5D.jpg")); url.setEncodedUrl("//[::56:56:56:56:56:56:56]"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]")); QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]")); - url.setEncodedUrl("//[::56:56:56:56:56:56:56]#[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]#%5B%5D")); - QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]#%5B%5D")); - QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]#[]")); - - url.setEncodedUrl("//[::56:56:56:56:56:56:56]?[]"); - QCOMPARE(url.toString(QUrl::FullyEncoded), QString("//[0:56:56:56:56:56:56:56]?[]")); - QCOMPARE(url.toEncoded(), QByteArray("//[0:56:56:56:56:56:56:56]?[]")); - QCOMPARE(url.toString(), QString("//[0:56:56:56:56:56:56:56]?[]")); - url.setEncodedUrl("data:text/css,div%20{%20border-right:%20solid;%20}"); QCOMPARE(url.toString(QUrl::FullyEncoded), QString("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); QCOMPARE(url.toEncoded(), QByteArray("data:text/css,div%20%7B%20border-right:%20solid;%20%7D")); - QCOMPARE(url.toString(), QString("data:text/css,div { border-right: solid; }")); + QCOMPARE(url.toString(), QString("data:text/css,div %7B border-right: solid; %7D")); } { @@ -2386,7 +2506,7 @@ void tst_QUrl::setEncodedFragment_data() QTest::newRow("basic test") << BA("http://www.kde.org") << BA("abc") << BA("http://www.kde.org#abc"); QTest::newRow("initial url has fragment") << BA("http://www.kde.org#old") << BA("new") << BA("http://www.kde.org#new"); QTest::newRow("encoded fragment") << BA("http://www.kde.org") << BA("a%20c") << BA("http://www.kde.org#a%20c"); - QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a#b"); + QTest::newRow("with #") << BA("http://www.kde.org") << BA("a#b") << BA("http://www.kde.org#a%23b"); // toString uses "a#b" QTest::newRow("unicode") << BA("http://www.kde.org") << BA("\xc3\xa9") << BA("http://www.kde.org#%C3%A9"); QTest::newRow("binary") << BA("http://www.kde.org") << BA("\x00\xc0\x80", 3) << BA("http://www.kde.org#%00%C0%80"); } @@ -2427,23 +2547,37 @@ void tst_QUrl::fromEncoded() void tst_QUrl::stripTrailingSlash_data() { QTest::addColumn<QString>("url"); - QTest::addColumn<QString>("expected"); + QTest::addColumn<QString>("expectedStrip"); // toString(Strip) + QTest::addColumn<QString>("expectedDir"); // toString(RemoveFilename) + QTest::addColumn<QString>("expectedDirStrip"); // toString(RemoveFilename|Strip) - QTest::newRow("ftp no slash") << "ftp://ftp.de.kde.org/dir" << "ftp://ftp.de.kde.org/dir"; - QTest::newRow("ftp slash") << "ftp://ftp.de.kde.org/dir/" << "ftp://ftp.de.kde.org/dir"; - QTest::newRow("file slash") << "file:///dir/" << "file:///dir"; - QTest::newRow("file no slash") << "file:///dir/" << "file:///dir"; - QTest::newRow("file root") << "file:///" << "file:///"; - QTest::newRow("no path") << "remote://" << "remote://"; + QTest::newRow("subdir no slash") << "ftp://kde.org/dir/subdir" << "ftp://kde.org/dir/subdir" << "ftp://kde.org/dir/" << "ftp://kde.org/dir"; + QTest::newRow("ftp no slash") << "ftp://kde.org/dir" << "ftp://kde.org/dir" << "ftp://kde.org/" << "ftp://kde.org/"; + QTest::newRow("ftp slash") << "ftp://kde.org/dir/" << "ftp://kde.org/dir" << "ftp://kde.org/dir/" << "ftp://kde.org/dir"; + QTest::newRow("ftp_two_slashes") << "ftp://kde.org/dir//" << "ftp://kde.org/dir" << "ftp://kde.org/dir//" << "ftp://kde.org/dir"; + QTest::newRow("file slash") << "file:///dir/" << "file:///dir" << "file:///dir/" << "file:///dir"; + QTest::newRow("file no slash") << "file:///dir" << "file:///dir" << "file:///" << "file:///"; + QTest::newRow("file root") << "file:///" << "file:///" << "file:///" << "file:///"; + QTest::newRow("file_root_manyslashes") << "file://///" << "file:///" << "file://///" << "file:///"; + QTest::newRow("no path") << "remote://" << "remote://" << "remote://" << "remote://"; } void tst_QUrl::stripTrailingSlash() { QFETCH(QString, url); - QFETCH(QString, expected); + QFETCH(QString, expectedStrip); + QFETCH(QString, expectedDir); + QFETCH(QString, expectedDirStrip); QUrl u(url); - QCOMPARE(u.toString(QUrl::StripTrailingSlash), expected); + QCOMPARE(u.toString(QUrl::StripTrailingSlash), expectedStrip); + QCOMPARE(u.toString(QUrl::RemoveFilename), expectedDir); + QCOMPARE(u.toString(QUrl::RemoveFilename | QUrl::StripTrailingSlash), expectedDirStrip); + + // Same thing, using QUrl::adjusted() + QCOMPARE(u.adjusted(QUrl::StripTrailingSlash).toString(), expectedStrip); + QCOMPARE(u.adjusted(QUrl::RemoveFilename).toString(), expectedDir); + QCOMPARE(u.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash).toString(), expectedDirStrip); } void tst_QUrl::hosts_data() @@ -2729,6 +2863,43 @@ void tst_QUrl::fromUserInput() QCOMPARE(url, guessUrlFromString); } +void tst_QUrl::fileName_data() +{ + QTest::addColumn<QString>("urlStr"); + QTest::addColumn<QString>("expectedDirPath"); + QTest::addColumn<QString>("expectedPrettyDecodedFileName"); + QTest::addColumn<QString>("expectedFullyDecodedFileName"); + + QTest::newRow("fromDocu") << "http://qt-project.org/support/file.html" + << "/support/" << "file.html" << "file.html"; + QTest::newRow("absoluteFile") << "file:///temp/tmp.txt" + << "/temp/" << "tmp.txt" << "tmp.txt"; + QTest::newRow("absoluteDir") << "file:///temp/" + << "/temp/" << QString() << QString(); + QTest::newRow("absoluteInRoot") << "file:///temp" + << "/" << "temp" << "temp"; + QTest::newRow("relative") << "temp/tmp.txt" + << "temp/" << "tmp.txt" << "tmp.txt"; + QTest::newRow("relativeNoSlash") << "tmp.txt" + << QString() << "tmp.txt" << "tmp.txt"; + QTest::newRow("encoded") << "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)" + << "/specials/" << "Print To File (PDF%252FAcrobat)" << "Print To File (PDF%2FAcrobat)"; +} + +void tst_QUrl::fileName() +{ + QFETCH(QString, urlStr); + QFETCH(QString, expectedDirPath); + QFETCH(QString, expectedPrettyDecodedFileName); + QFETCH(QString, expectedFullyDecodedFileName); + + QUrl url(urlStr); + QVERIFY(url.isValid()); + QCOMPARE(url.adjusted(QUrl::RemoveFilename).path(), expectedDirPath); + QCOMPARE(url.fileName(QUrl::PrettyDecoded), expectedPrettyDecodedFileName); + QCOMPARE(url.fileName(QUrl::FullyDecoded), expectedFullyDecodedFileName); +} + // This is a regression test for a previously fixed bug where isEmpty didn't // work for an encoded URL that was yet to be decoded. The test checks that // isEmpty works for an encoded URL both after and before decoding. @@ -2866,7 +3037,8 @@ void tst_QUrl::effectiveTLDs() { QFETCH(QUrl, domain); QFETCH(QString, TLD); - QCOMPARE(domain.topLevelDomain(), TLD); + QCOMPARE(domain.topLevelDomain(QUrl::PrettyDecoded), TLD); + QCOMPARE(domain.topLevelDomain(QUrl::FullyDecoded), TLD); } void tst_QUrl::lowercasesScheme() @@ -2950,19 +3122,25 @@ void tst_QUrl::componentEncodings_data() // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" // / "*" / "+" / "," / ";" / "=" - // like the unreserved, these are decoded everywhere - // don't test in query because they might remain encoded - QTest::newRow("decoded-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c#%3b%3d") + // these are always left alone + QTest::newRow("decoded-subdelims") << QUrl("x://!$&:'()@host/*+,?$=(+)#;=") << int(QUrl::FullyEncoded) << "!$&" << "'()" << "!$&:'()" << "host" << "!$&:'()@host" - << "/*+," << "" << ";=" - << "x://!$&:'()@host/*+,#;="; + << "/*+," << "$=(+)" << ";=" + << "x://!$&:'()@host/*+,?$=(+)#;="; + QTest::newRow("encoded-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c?%26=%26&%3d=%3d#%3b%3d") + << MostDecoded + << "%21%24%26" << "%27%28%29" << "%21%24%26:%27%28%29" + << "host" << "%21%24%26:%27%28%29@host" + << "/%2A%2B%2C" << "%26=%26&%3D=%3D" << "%3B%3D" + << "x://%21%24%26:%27%28%29@host/%2A%2B%2C?%26=%26&%3D=%3D#%3B%3D"; // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" // these are the separators between fields - // they must appear encoded in certain positions, no exceptions - // in other positions, they can appear decoded, so they always do + // they must appear encoded in certain positions in the full URL, no exceptions + // when in those positions, they appear decoded in the isolated parts + // in other positions and the other delimiters are always left untransformed // 1) test the delimiters that must appear encoded // (if they were decoded, they'd would change the URL parsing) QTest::newRow("encoded-gendelims-changing") << QUrl("x://%5b%3a%2f%3f%23%40%5d:%5b%2f%3f%23%40%5d@host/%2f%3f%23?%23") @@ -2972,32 +3150,21 @@ void tst_QUrl::componentEncodings_data() << "/%2F?#" << "#" << "" << "x://%5B%3A%2F%3F%23%40%5D:%5B%2F%3F%23%40%5D@host/%2F%3F%23?%23"; - // 2) test the delimiters that may appear decoded and would not change the meaning - // and test that %2f is *not* decoded to a slash in the path - // don't test the query because in this mode it doesn't transform anything - QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://:%3a@host/%2f%3a%40#%23%3a%2f%3f%40") + // 2) test that the other delimiters remain decoded + QTest::newRow("decoded-gendelims-unchanging") << QUrl("x://::@host/:@/[]?:/?@[]?#:/?@[]") << int(QUrl::FullyEncoded) << "" << ":" << "::" << "host" << "::@host" - << "/%2F:@" << "" << "#:/?@" - << "x://::@host/%2F:@##:/?@"; - - // 3) test "[" and "]". Even though they are not ambiguous in the path, query or fragment - // the RFC does not allow them to appear there decoded. QUrl adheres strictly in FullyEncoded mode - QTest::newRow("encoded-square-brackets") << QUrl("x:/[]#[]") - << int(QUrl::FullyEncoded) - << "" << "" << "" - << "" << "" - << "/%5B%5D" << "" << "%5B%5D" - << "x:/%5B%5D#%5B%5D"; - - // 4) like above, but now decode them, which is allowed - QTest::newRow("decoded-square-brackets") << QUrl("x:/%5B%5D#%5B%5D") - << MostDecoded - << "" << "" << "" - << "" << "" - << "/[]" << "" << "[]" - << "x:/[]#[]"; + << "/:@/[]" << ":/?@[]?" << ":/?@[]" + << "x://::@host/:@/[]?:/?@[]?#:/?@[]"; + + // 3) and test that the same encoded sequences remain encoded + QTest::newRow("encoded-gendelims-unchanging") << QUrl("x://:%3A@host/%3A%40%5B%5D?%3A%2F%3F%40%5B%5D#%23%3A%2F%3F%40%5B%5D") + << MostDecoded + << "" << "%3A" << ":%3A" + << "host" << ":%3A@host" + << "/%3A%40%5B%5D" << "%3A%2F%3F%40%5B%5D" << "%23%3A%2F%3F%40%5B%5D" + << "x://:%3A@host/%3A%40%5B%5D?%3A%2F%3F%40%5B%5D#%23%3A%2F%3F%40%5B%5D"; // test the query // since QUrl doesn't know what chars the user wants to use for the pair and value delimiters, @@ -3051,23 +3218,13 @@ void tst_QUrl::componentEncodings_data() << QString::fromUtf8("é ") << QString::fromUtf8("x:// é:é @smørbrød.example.no/é ? é#é "); - // the pretty form re-encodes the subdelims (except in the query, where they are left alone) - QTest::newRow("pretty-subdelims") << QUrl("x://%21%24%26:%27%28%29@host/%2a%2b%2c?%26=%26&%3d=%3d#%3b%3d") - << int(QUrl::PrettyDecoded) - << "!$&" << "'()" << "!$&:'()" - << "host" << "!$&:'()@host" - << "/*+," << "%26=%26&%3D=%3D" << ";=" - << "x://!$&:'()@host/*+,?%26=%26&%3D=%3D#;="; - - // the pretty form decodes all unambiguous gen-delims - // (except in query, where they are left alone) - QTest::newRow("pretty-gendelims") << QUrl("x://%5b%3a%40%2f%5d:%5b%3a%40%2f%5d@host" - "/%3a%40%5b%3f%23%5d?[?%3f%23]%5b:%3a@%40%5d#%23") + // the pretty form decodes all unambiguous gen-delims in the individual parts + QTest::newRow("pretty-gendelims") << QUrl("x://%5b%3a%40%2f%3f%23%5d:%5b%40%2f%3f%23%5d@host/%3f%23?%23") << int(QUrl::PrettyDecoded) - << "[:@/]" << "[:@/]" << "[%3A@/]:[:@/]" - << "host" << "%5B%3A%40/%5D:%5B:%40/%5D@host" - << "/:@[?#]" << "[?%3F#]%5B:%3A@%40%5D" << "#" - << "x://%5B%3A%40%2F%5D:%5B:%40%2F%5D@host/:@[%3F%23]?[?%3F%23]%5B:%3A@%40%5D##"; + << "[:@/?#]" << "[@/?#]" << "[%3A@/?#]:[@/?#]" + << "host" << "%5B%3A%40/?#%5D:%5B%40/?#%5D@host" + << "/?#" << "#" << "" + << "x://%5B%3A%40%2F%3F%23%5D:%5B%40%2F%3F%23%5D@host/%3F%23?%23"; // the pretty form keeps the other characters decoded everywhere // except when rebuilding the full URL, when we only allow "{}" to remain decoded @@ -3076,8 +3233,8 @@ void tst_QUrl::componentEncodings_data() << "\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}:\"<>^\\{|}" << "host" << "\"<>^\\{|}:\"<>^\\{|}@host" << "/\"<>^\\{|}" << "\"<>^\\{|}" << "\"<>^\\{|}" - << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C{%7C}" - "?%22%3C%3E%5E%5C{%7C}#%22%3C%3E%5E%5C%7B%7C%7D"; + << "x://%22%3C%3E%5E%5C%7B%7C%7D:%22%3C%3E%5E%5C%7B%7C%7D@host/%22%3C%3E%5E%5C%7B%7C%7D" + "?%22%3C%3E%5E%5C%7B%7C%7D#%22%3C%3E%5E%5C%7B%7C%7D"; } void tst_QUrl::componentEncodings() @@ -3346,9 +3503,6 @@ void tst_QUrl::setComponents_data() QTest::newRow("invalid-scheme-encode") << QUrl("http://example.com") << int(Scheme) << "http%61" << Decoded << false << PrettyDecoded << "" << ""; - QTest::newRow("userinfo-encode") << QUrl("http://example.com") - << int(UserInfo) << "h%61llo:world@" << Decoded << true - << PrettyDecoded << "h%2561llo:world@" << "http://h%2561llo:world%40@example.com"; QTest::newRow("username-encode") << QUrl("http://example.com") << int(UserName) << "h%61llo:world" << Decoded << true << PrettyDecoded << "h%2561llo:world" << "http://h%2561llo%3Aworld@example.com"; @@ -3359,9 +3513,6 @@ void tst_QUrl::setComponents_data() QTest::newRow("invalid-host-encode") << QUrl("http://example.com") << int(Host) << "ex%61mple.com" << Decoded << false << PrettyDecoded << "" << ""; - QTest::newRow("invalid-authority-encode") << QUrl("http://example.com") - << int(Authority) << "ex%61mple.com" << Decoded << false - << PrettyDecoded << "" << ""; QTest::newRow("path-encode") << QUrl("http://example.com/foo") << int(Path) << "/bar%23" << Decoded << true << PrettyDecoded << "/bar%2523" << "http://example.com/bar%2523"; @@ -3371,11 +3522,7 @@ void tst_QUrl::setComponents_data() QTest::newRow("fragment-encode") << QUrl("http://example.com/foo#z") << int(Fragment) << "bar%23" << Decoded << true << PrettyDecoded << "bar%2523" << "http://example.com/foo#bar%2523"; - // force decoding; note how the userinfo becomes ambiguous - QTest::newRow("userinfo-decode") << QUrl("http://example.com") - << int(UserInfo) << "hello%3Aworld:}}>b9o%25kR(" << Tolerant << true - << FullyDecoded << "hello:world:}}>b9o%kR(" - << "http://hello%3Aworld:%7D%7D%3Eb9o%25kR(@example.com"; + // force decoding QTest::newRow("username-decode") << QUrl("http://example.com") << int(UserName) << "hello%3Aworld%25" << Tolerant << true << FullyDecoded << "hello:world%" << "http://hello%3Aworld%25@example.com"; diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 2014045171..05d5f94e3d 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -824,12 +824,20 @@ void tst_QUrlInternal::correctEncodedMistakes() QFETCH(QString, expected); // prepend some data to be sure that it remains there - QString output = QTest::currentDataTag(); - expected.prepend(output); + QString dataTag = QTest::currentDataTag(); + QString output = dataTag; if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), 0)) output += input; - QCOMPARE(output, expected); + QCOMPARE(output, dataTag + expected); + + // now try the full decode mode + output = dataTag; + QString expected2 = QUrl::fromPercentEncoding(expected.toLatin1()); + + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyDecoded)) + output += input; + QCOMPARE(output, dataTag + expected2); } static void addUtf8Data(const char *name, const char *data) @@ -1027,6 +1035,15 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8() if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded)) output += input; QCOMPARE(output, QTest::currentDataTag() + input); + + // verify for security reasons that all bad UTF-8 data got replaced by QChar::ReplacementCharacter + output = QTest::currentDataTag(); + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded)) + output += input; + for (int i = strlen(QTest::currentDataTag()); i < output.length(); ++i) { + QVERIFY2(output.at(i).unicode() < 0x80 || output.at(i) == QChar::ReplacementCharacter, + qPrintable(QString("Character at i == %1 was U+%2").arg(i).arg(output.at(i).unicode(), 4, 16, QLatin1Char('0')))); + } } void tst_QUrlInternal::recodeByteArray_data() diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 94e6e1129e..9111c59408 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -45,6 +45,7 @@ #include "qjsonobject.h" #include "qjsonvalue.h" #include "qjsondocument.h" +#include <limits> #define INVALID_UNICODE "\357\277\277" // "\uffff" #define UNICODE_DJE "\320\202" // Character from the Serbian Cyrillic alphabet @@ -97,6 +98,8 @@ private Q_SLOTS: void toVariantList(); void toJson(); + void toJsonSillyNumericValues(); + void toJsonLargeNumericValues(); void fromJson(); void fromJsonErrors(); void fromBinary(); @@ -1201,6 +1204,89 @@ void tst_QtJson::toJson() } } +void tst_QtJson::toJsonSillyNumericValues() +{ + QJsonObject object; + QJsonArray array; + array.append(QJsonValue(std::numeric_limits<double>::infinity())); // encode to: null + array.append(QJsonValue(-std::numeric_limits<double>::infinity())); // encode to: null + array.append(QJsonValue(std::numeric_limits<double>::quiet_NaN())); // encode to: null + object.insert("Array", array); + + QByteArray json = QJsonDocument(object).toJson(); + + QByteArray expected = + "{\n" + " \"Array\": [\n" + " null,\n" + " null,\n" + " null\n" + " ]\n" + "}\n"; + + QCOMPARE(json, expected); + + QJsonDocument doc; + doc.setObject(object); + json = doc.toJson(); + QCOMPARE(json, expected); +} + +void tst_QtJson::toJsonLargeNumericValues() +{ + QJsonObject object; + QJsonArray array; + array.append(QJsonValue(1.234567)); // actual precision bug in Qt 5.0.0 + array.append(QJsonValue(1.7976931348623157e+308)); // JS Number.MAX_VALUE + array.append(QJsonValue(5e-324)); // JS Number.MIN_VALUE + array.append(QJsonValue(std::numeric_limits<double>::min())); + array.append(QJsonValue(std::numeric_limits<double>::max())); + array.append(QJsonValue(std::numeric_limits<double>::epsilon())); + array.append(QJsonValue(std::numeric_limits<double>::denorm_min())); + array.append(QJsonValue(0.0)); + array.append(QJsonValue(-std::numeric_limits<double>::min())); + array.append(QJsonValue(-std::numeric_limits<double>::max())); + array.append(QJsonValue(-std::numeric_limits<double>::epsilon())); + array.append(QJsonValue(-std::numeric_limits<double>::denorm_min())); + array.append(QJsonValue(-0.0)); + array.append(QJsonValue(9007199254740992LL)); // JS Number max integer + array.append(QJsonValue(-9007199254740992LL)); // JS Number min integer + object.insert("Array", array); + + QByteArray json = QJsonDocument(object).toJson(); + + QByteArray expected = + "{\n" + " \"Array\": [\n" + " 1.234567,\n" + " 1.7976931348623157e+308,\n" + // ((4.9406564584124654e-324 == 5e-324) == true) + // I can only think JavaScript has a special formatter to + // emit this value for this IEEE754 bit pattern. + " 4.9406564584124654e-324,\n" + " 2.2250738585072014e-308,\n" + " 1.7976931348623157e+308,\n" + " 2.2204460492503131e-16,\n" + " 4.9406564584124654e-324,\n" + " 0,\n" + " -2.2250738585072014e-308,\n" + " -1.7976931348623157e+308,\n" + " -2.2204460492503131e-16,\n" + " -4.9406564584124654e-324,\n" + " 0,\n" + " 9007199254740992,\n" + " -9007199254740992\n" + " ]\n" + "}\n"; + + QCOMPARE(json, expected); + + QJsonDocument doc; + doc.setObject(object); + json = doc.toJson(); + QCOMPARE(json, expected); +} + void tst_QtJson::fromJson() { { diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp index df374ffc23..c6d04e64db 100644 --- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp @@ -195,11 +195,11 @@ protected: void tst_QEventLoop::processEvents() { - QSignalSpy spy1(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock())); - QSignalSpy spy2(QAbstractEventDispatcher::instance(), SIGNAL(awake())); + QSignalSpy aboutToBlockSpy(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock())); + QSignalSpy awakeSpy(QAbstractEventDispatcher::instance(), SIGNAL(awake())); - QVERIFY(spy1.isValid()); - QVERIFY(spy2.isValid()); + QVERIFY(aboutToBlockSpy.isValid()); + QVERIFY(awakeSpy.isValid()); QEventLoop eventLoop; @@ -208,8 +208,8 @@ void tst_QEventLoop::processEvents() // process posted events, QEventLoop::processEvents() should return // true QVERIFY(eventLoop.processEvents()); - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 1); + QCOMPARE(aboutToBlockSpy.count(), 0); + QCOMPARE(awakeSpy.count(), 1); // allow any session manager to complete its handshake, so that // there are no pending events left. @@ -222,28 +222,28 @@ void tst_QEventLoop::processEvents() // no events to process, QEventLoop::processEvents() should return // false - spy1.clear(); - spy2.clear(); + aboutToBlockSpy.clear(); + awakeSpy.clear(); QVERIFY(!eventLoop.processEvents()); - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 1); + QCOMPARE(aboutToBlockSpy.count(), 0); + QCOMPARE(awakeSpy.count(), 1); // make sure the test doesn't block forever int timerId = startTimer(100); // wait for more events to process, QEventLoop::processEvents() // should return true - spy1.clear(); - spy2.clear(); + aboutToBlockSpy.clear(); + awakeSpy.clear(); QVERIFY(eventLoop.processEvents(QEventLoop::WaitForMoreEvents)); // Verify that the eventloop has blocked and woken up. Some eventloops // may block and wake up multiple times. - QVERIFY(spy1.count() > 0); - QVERIFY(spy2.count() > 0); + QVERIFY(aboutToBlockSpy.count() > 0); + QVERIFY(awakeSpy.count() > 0); // We should get one awake for each aboutToBlock, plus one awake when // processEvents is entered. - QVERIFY(spy2.count() >= spy1.count()); + QVERIFY(awakeSpy.count() >= aboutToBlockSpy.count()); killTimer(timerId); } diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro index 5009fedc4f..23a8e6d23a 100644 --- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro +++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro @@ -1,6 +1,7 @@ CONFIG += testcase parallel_test TARGET = tst_qmetatype QT = core testlib +INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qmetatype.cpp TESTDATA=./typeFlags.bin DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 77ea39da53..47900204e7 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -43,6 +43,8 @@ #include <QtCore> #include <QtTest/QtTest> +#include "tst_qvariant_common.h" + #ifdef Q_OS_LINUX # include <pthread.h> #endif @@ -111,6 +113,11 @@ private slots: void metaObject(); void constexprMetaTypeIds(); void constRefs(); + void convertCustomType_data(); + void convertCustomType(); + void compareCustomType_data(); + void compareCustomType(); + void customDebugStream(); }; struct Foo { int i; }; @@ -1302,15 +1309,20 @@ Q_DECLARE_METATYPE(MyObjectPtr) void tst_QMetaType::automaticTemplateRegistration() { - { - QList<int> intList; - intList << 42; - QVERIFY(QVariant::fromValue(intList).value<QList<int> >().first() == 42); - QVector<QList<int> > vectorList; - vectorList << intList; - QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<int> > >().first().first() == 42); +#define TEST_SEQUENTIAL_CONTAINER(CONTAINER, VALUE_TYPE) \ + { \ + CONTAINER<VALUE_TYPE> innerContainer; \ + innerContainer.push_back(42); \ + QVERIFY(*QVariant::fromValue(innerContainer).value<CONTAINER<VALUE_TYPE> >().begin() == 42); \ + QVector<CONTAINER<VALUE_TYPE> > outerContainer; \ + outerContainer << innerContainer; \ + QVERIFY(*QVariant::fromValue(outerContainer).value<QVector<CONTAINER<VALUE_TYPE> > >().first().begin() == 42); \ } + TEST_SEQUENTIAL_CONTAINER(QList, int) + TEST_SEQUENTIAL_CONTAINER(std::vector, int) + TEST_SEQUENTIAL_CONTAINER(std::list, int) + { QList<QByteArray> bytearrayList; bytearrayList << QByteArray("foo"); @@ -1323,14 +1335,9 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(::qMetaTypeId<QVariantList>(), (int)QMetaType::QVariantList); QCOMPARE(::qMetaTypeId<QList<QVariant> >(), (int)QMetaType::QVariantList); - { - QList<QVariant> variantList; - variantList << 42; - QVERIFY(QVariant::fromValue(variantList).value<QList<QVariant> >().first() == 42); - QVector<QList<QVariant> > vectorList; - vectorList << variantList; - QVERIFY(QVariant::fromValue(vectorList).value<QVector<QList<QVariant> > >().first().first() == 42); - } + TEST_SEQUENTIAL_CONTAINER(QList, QVariant) + TEST_SEQUENTIAL_CONTAINER(std::vector, QVariant) + TEST_SEQUENTIAL_CONTAINER(std::list, QVariant) { QList<QSharedPointer<QObject> > sharedPointerList; @@ -1395,6 +1402,31 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(QVariant::fromValue(variantMap).value<QVariantMap>().value(QStringLiteral("4")), QVariant(2)); } { + typedef std::map<int, int> IntIntMap; + IntIntMap intIntMap; + intIntMap[4] = 2; + QCOMPARE(QVariant::fromValue(intIntMap).value<IntIntMap>()[4], 2); + } + { + typedef std::map<int, uint> StdIntUIntMap; + StdIntUIntMap intUIntMap; + intUIntMap[4] = 2; + QCOMPARE(QVariant::fromValue(intUIntMap).value<StdIntUIntMap>()[4], (uint)2); + } + { + typedef std::map<int, CustomObject*> StdMapIntCustomObject ; + StdMapIntCustomObject intComparableMap; + CustomObject *o = 0; + intComparableMap[4] = o; + QCOMPARE(QVariant::fromValue(intComparableMap).value<StdMapIntCustomObject >()[4], o); + } + { + typedef std::map<QString, QVariant> StdMapStringVariant; + StdMapStringVariant variantMap; + variantMap[QStringLiteral("4")] = 2; + QCOMPARE(QVariant::fromValue(variantMap).value<StdMapStringVariant>()[QStringLiteral("4")], QVariant(2)); + } + { typedef QPair<int, int> IntIntPair; IntIntPair intIntPair = qMakePair(4, 2); QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().first, 4); @@ -1412,6 +1444,25 @@ void tst_QMetaType::automaticTemplateRegistration() QCOMPARE(QVariant::fromValue(intComparablePair).value<IntComparablePair>().second, m); } { + typedef std::pair<int, int> IntIntPair; + IntIntPair intIntPair = std::make_pair(4, 2); + QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().first, 4); + QCOMPARE(QVariant::fromValue(intIntPair).value<IntIntPair>().second, 2); + } + { + typedef std::pair<int, uint> StdIntUIntPair; + StdIntUIntPair intUIntPair = std::make_pair<int, uint>(4, 2); + QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().first, 4); + QCOMPARE(QVariant::fromValue(intUIntPair).value<StdIntUIntPair>().second, (uint)2); + } + { + typedef std::pair<int, CustomQObject*> StdIntComparablePair; + CustomQObject* o = 0; + StdIntComparablePair intComparablePair = std::make_pair(4, o); + QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().first, 4); + QCOMPARE(QVariant::fromValue(intComparablePair).value<StdIntComparablePair>().second, o); + } + { typedef QHash<int, UnregisteredType> IntUnregisteredTypeHash; QVERIFY(qRegisterMetaType<IntUnregisteredTypeHash>("IntUnregisteredTypeHash") > 0); } @@ -1446,17 +1497,14 @@ void tst_QMetaType::automaticTemplateRegistration() F(uint, __VA_ARGS__) \ F(qlonglong, __VA_ARGS__) \ F(qulonglong, __VA_ARGS__) \ - F(double, __VA_ARGS__) \ F(long, __VA_ARGS__) \ F(short, __VA_ARGS__) \ F(char, __VA_ARGS__) \ F(ulong, __VA_ARGS__) \ F(ushort, __VA_ARGS__) \ F(uchar, __VA_ARGS__) \ - F(float, __VA_ARGS__) \ F(QObject*, __VA_ARGS__) \ - F(QString, __VA_ARGS__) \ - F(CustomMovable, __VA_ARGS__) + F(QString, __VA_ARGS__) #define CREATE_AND_VERIFY_CONTAINER(CONTAINER, ...) \ @@ -1774,6 +1822,366 @@ void tst_QMetaType::constRefs() #endif } +struct CustomConvertibleType +{ + explicit CustomConvertibleType(const QVariant &foo = QVariant()) : m_foo(foo) {} + virtual ~CustomConvertibleType() {} + QString toString() const { return m_foo.toString(); } + operator QPoint() const { return QPoint(12, 34); } + template<typename To> + To convert() const { return s_value.value<To>();} + template<typename To> + To convertOk(bool *ok) const { *ok = s_ok; return s_value.value<To>();} + + QVariant m_foo; + static QVariant s_value; + static bool s_ok; +}; + +bool operator<(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) +{ return lhs.m_foo < rhs.m_foo; } +bool operator==(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) +{ return lhs.m_foo == rhs.m_foo; } +bool operator!=(const CustomConvertibleType &lhs, const CustomConvertibleType &rhs) +{ return !operator==(lhs, rhs); } + +QVariant CustomConvertibleType::s_value; +bool CustomConvertibleType::s_ok = true; + +struct CustomConvertibleType2 +{ + // implicit + CustomConvertibleType2(const CustomConvertibleType &t = CustomConvertibleType()) + : m_foo(t.m_foo) {} + virtual ~CustomConvertibleType2() {} + + QVariant m_foo; +}; + +struct CustomDebugStreamableType +{ + QString toString() const { return "test"; } +}; + +QDebug operator<<(QDebug dbg, const CustomDebugStreamableType&) +{ + return dbg << "string-content"; +} + +bool operator==(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) +{ return lhs.m_foo == rhs.m_foo; } +bool operator!=(const CustomConvertibleType2 &lhs, const CustomConvertibleType2 &rhs) +{ return !operator==(lhs, rhs); } + +Q_DECLARE_METATYPE(CustomConvertibleType); +Q_DECLARE_METATYPE(CustomConvertibleType2); +Q_DECLARE_METATYPE(CustomDebugStreamableType); + +template<typename T, typename U> +U convert(const T &t) +{ + return t; +} + +template<typename From> +struct ConvertFunctor +{ + CustomConvertibleType operator()(const From& f) const + { + return CustomConvertibleType(QVariant::fromValue(f)); + } +}; + +template<typename From, typename To> +bool hasRegisteredConverterFunction() +{ + return QMetaType::hasRegisteredConverterFunction<From, To>(); +} + +template<typename From, typename To> +void testCustomTypeNotYetConvertible() +{ + QVERIFY((!hasRegisteredConverterFunction<From, To>())); + QVERIFY((!QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<To>()))); +} + +template<typename From, typename To> +void testCustomTypeConvertible() +{ + QVERIFY((hasRegisteredConverterFunction<From, To>())); + QVERIFY((QVariant::fromValue<From>(From()).canConvert(qMetaTypeId<To>()))); +} + +void customTypeNotYetConvertible() +{ + testCustomTypeNotYetConvertible<CustomConvertibleType, QString>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, bool>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, int>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, double>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, float>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QRect>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QRectF>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QPoint>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QPointF>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QSize>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QSizeF>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QLine>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QLineF>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, QChar>(); + testCustomTypeNotYetConvertible<QString, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<bool, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<int, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<double, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<float, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QRect, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QRectF, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QPoint, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QPointF, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QSize, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QSizeF, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QLine, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QLineF, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<QChar, CustomConvertibleType>(); + testCustomTypeNotYetConvertible<CustomConvertibleType, CustomConvertibleType2>(); +} + +void registerCustomTypeConversions() +{ + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QString>(&CustomConvertibleType::convertOk<QString>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, bool>(&CustomConvertibleType::convert<bool>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, int>(&CustomConvertibleType::convertOk<int>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, double>(&CustomConvertibleType::convert<double>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, float>(&CustomConvertibleType::convertOk<float>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRect>(&CustomConvertibleType::convert<QRect>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QRectF>(&CustomConvertibleType::convertOk<QRectF>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPoint>(convert<CustomConvertibleType,QPoint>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QPointF>(&CustomConvertibleType::convertOk<QPointF>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSize>(&CustomConvertibleType::convert<QSize>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QSizeF>(&CustomConvertibleType::convertOk<QSizeF>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLine>(&CustomConvertibleType::convert<QLine>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QLineF>(&CustomConvertibleType::convertOk<QLineF>))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, QChar>(&CustomConvertibleType::convert<QChar>))); + QVERIFY((QMetaType::registerConverter<QString, CustomConvertibleType>(ConvertFunctor<QString>()))); + QVERIFY((QMetaType::registerConverter<bool, CustomConvertibleType>(ConvertFunctor<bool>()))); + QVERIFY((QMetaType::registerConverter<int, CustomConvertibleType>(ConvertFunctor<int>()))); + QVERIFY((QMetaType::registerConverter<double, CustomConvertibleType>(ConvertFunctor<double>()))); + QVERIFY((QMetaType::registerConverter<float, CustomConvertibleType>(ConvertFunctor<float>()))); + QVERIFY((QMetaType::registerConverter<QRect, CustomConvertibleType>(ConvertFunctor<QRect>()))); + QVERIFY((QMetaType::registerConverter<QRectF, CustomConvertibleType>(ConvertFunctor<QRectF>()))); + QVERIFY((QMetaType::registerConverter<QPoint, CustomConvertibleType>(ConvertFunctor<QPoint>()))); + QVERIFY((QMetaType::registerConverter<QPointF, CustomConvertibleType>(ConvertFunctor<QPointF>()))); + QVERIFY((QMetaType::registerConverter<QSize, CustomConvertibleType>(ConvertFunctor<QSize>()))); + QVERIFY((QMetaType::registerConverter<QSizeF, CustomConvertibleType>(ConvertFunctor<QSizeF>()))); + QVERIFY((QMetaType::registerConverter<QLine, CustomConvertibleType>(ConvertFunctor<QLine>()))); + QVERIFY((QMetaType::registerConverter<QLineF, CustomConvertibleType>(ConvertFunctor<QLineF>()))); + QVERIFY((QMetaType::registerConverter<QChar, CustomConvertibleType>(ConvertFunctor<QChar>()))); + QVERIFY((QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>())); + QTest::ignoreMessage(QtWarningMsg, "Type conversion already registered from type CustomConvertibleType to type CustomConvertibleType2"); + QVERIFY((!QMetaType::registerConverter<CustomConvertibleType, CustomConvertibleType2>())); +} + +void tst_QMetaType::convertCustomType_data() +{ + customTypeNotYetConvertible(); + registerCustomTypeConversions(); + + QTest::addColumn<bool>("ok"); + QTest::addColumn<QString>("testQString"); + QTest::addColumn<bool>("testBool"); + QTest::addColumn<int>("testInt"); + QTest::addColumn<double>("testDouble"); + QTest::addColumn<float>("testFloat"); + QTest::addColumn<QRect>("testQRect"); + QTest::addColumn<QRectF>("testQRectF"); + QTest::addColumn<QPoint>("testQPoint"); + QTest::addColumn<QPointF>("testQPointF"); + QTest::addColumn<QSize>("testQSize"); + QTest::addColumn<QSizeF>("testQSizeF"); + QTest::addColumn<QLine>("testQLine"); + QTest::addColumn<QLineF>("testQLineF"); + QTest::addColumn<QChar>("testQChar"); + QTest::addColumn<CustomConvertibleType>("testCustom"); + + QTest::newRow("default") << true + << QString::fromLatin1("string") << true << 15 + << double(3.14) << float(3.6) << QRect(1, 2, 3, 4) + << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34) + << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8) + << QLine(3, 9, 29, 4) << QLineF(38.9, 28.9, 102.3, 0.0) + << QChar('Q') << CustomConvertibleType(QString::fromLatin1("test")); + QTest::newRow("not ok") << false + << QString::fromLatin1("string") << true << 15 + << double(3.14) << float(3.6) << QRect(1, 2, 3, 4) + << QRectF(1.4, 1.9, 10.9, 40.2) << QPoint(12, 34) + << QPointF(9.2, 2.7) << QSize(4, 9) << QSizeF(3.3, 9.8) + << QLine(3, 9, 29, 4) << QLineF() + << QChar('Q') << CustomConvertibleType(42); +} + +void tst_QMetaType::convertCustomType() +{ + QFETCH(bool, ok); + CustomConvertibleType::s_ok = ok; + + CustomConvertibleType t; + QVariant v = QVariant::fromValue(t); + QFETCH(QString, testQString); + CustomConvertibleType::s_value = testQString; + QCOMPARE(v.toString(), ok ? testQString : QString()); + QCOMPARE(v.value<QString>(), ok ? testQString : QString()); + QVERIFY(CustomConvertibleType::s_value.canConvert<CustomConvertibleType>()); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toString()), testQString); + + QFETCH(bool, testBool); + CustomConvertibleType::s_value = testBool; + QCOMPARE(v.toBool(), testBool); + QCOMPARE(v.value<bool>(), testBool); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toBool()), testBool); + + QFETCH(int, testInt); + CustomConvertibleType::s_value = testInt; + QCOMPARE(v.toInt(), ok ? testInt : 0); + QCOMPARE(v.value<int>(), ok ? testInt : 0); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toInt()), testInt); + + QFETCH(double, testDouble); + CustomConvertibleType::s_value = testDouble; + QCOMPARE(v.toDouble(), testDouble); + QCOMPARE(v.value<double>(), testDouble); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toDouble()), testDouble); + + QFETCH(float, testFloat); + CustomConvertibleType::s_value = testFloat; + QCOMPARE(v.toFloat(), ok ? testFloat : 0.0); + QCOMPARE(v.value<float>(), ok ? testFloat : 0.0); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toFloat()), testFloat); + + QFETCH(QRect, testQRect); + CustomConvertibleType::s_value = testQRect; + QCOMPARE(v.toRect(), testQRect); + QCOMPARE(v.value<QRect>(), testQRect); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRect()), testQRect); + + QFETCH(QRectF, testQRectF); + CustomConvertibleType::s_value = testQRectF; + QCOMPARE(v.toRectF(), ok ? testQRectF : QRectF()); + QCOMPARE(v.value<QRectF>(), ok ? testQRectF : QRectF()); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toRectF()), testQRectF); + + QFETCH(QPoint, testQPoint); + CustomConvertibleType::s_value = testQPoint; + QCOMPARE(v.toPoint(), testQPoint); + QCOMPARE(v.value<QPoint>(), testQPoint); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPoint()), testQPoint); + + QFETCH(QPointF, testQPointF); + CustomConvertibleType::s_value = testQPointF; + QCOMPARE(v.toPointF(), ok ? testQPointF : QPointF()); + QCOMPARE(v.value<QPointF>(), ok ? testQPointF : QPointF()); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toPointF()), testQPointF); + + QFETCH(QSize, testQSize); + CustomConvertibleType::s_value = testQSize; + QCOMPARE(v.toSize(), testQSize); + QCOMPARE(v.value<QSize>(), testQSize); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSize()), testQSize); + + QFETCH(QSizeF, testQSizeF); + CustomConvertibleType::s_value = testQSizeF; + QCOMPARE(v.toSizeF(), ok ? testQSizeF : QSizeF()); + QCOMPARE(v.value<QSizeF>(), ok ? testQSizeF : QSizeF()); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toSizeF()), testQSizeF); + + QFETCH(QLine, testQLine); + CustomConvertibleType::s_value = testQLine; + QCOMPARE(v.toLine(), testQLine); + QCOMPARE(v.value<QLine>(), testQLine); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLine()), testQLine); + + QFETCH(QLineF, testQLineF); + CustomConvertibleType::s_value = testQLineF; + QCOMPARE(v.toLineF(), ok ? testQLineF : QLineF()); + QCOMPARE(v.value<QLineF>(), ok ? testQLineF : QLineF()); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toLineF()), testQLineF); + + QFETCH(QChar, testQChar); + CustomConvertibleType::s_value = testQChar; + QCOMPARE(v.toChar(), testQChar); + QCOMPARE((CustomConvertibleType::s_value.value<CustomConvertibleType>().m_foo.toChar()), testQChar); + + QFETCH(CustomConvertibleType, testCustom); + v = QVariant::fromValue(testCustom); + QVERIFY(v.canConvert(::qMetaTypeId<CustomConvertibleType2>())); + QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo); +} + +void tst_QMetaType::compareCustomType_data() +{ + QMetaType::registerComparators<CustomConvertibleType>(); + + QTest::addColumn<QVariantList>("unsorted"); + QTest::addColumn<QVariantList>("sorted"); + + QTest::newRow("int") << (QVariantList() << 37 << 458 << 1 << 243 << -4 << 383) + << (QVariantList() << -4 << 1 << 37 << 243 << 383 << 458); + + QTest::newRow("dobule") << (QVariantList() << 4934.93 << 0.0 << 302.39 << -39.0) + << (QVariantList() << -39.0 << 0.0 << 302.39 << 4934.93); + + QTest::newRow("QString") << (QVariantList() << "Hello" << "World" << "this" << "is" << "a" << "test") + << (QVariantList() << "a" << "Hello" << "is" << "test" << "this" << "World"); + + QTest::newRow("QTime") << (QVariantList() << QTime(14, 39) << QTime(0, 0) << QTime(18, 18) << QTime(9, 27)) + << (QVariantList() << QTime(0, 0) << QTime(9, 27) << QTime(14, 39) << QTime(18, 18)); + + QTest::newRow("QDate") << (QVariantList() << QDate(2013, 3, 23) << QDate(1900, 12, 1) << QDate(2001, 2, 2) << QDate(1982, 12, 16)) + << (QVariantList() << QDate(1900, 12, 1) << QDate(1982, 12, 16) << QDate(2001, 2, 2) << QDate(2013, 3, 23)); + + QTest::newRow("mixed") << (QVariantList() << "Hello" << "World" << QChar('a') << 38 << QChar('z') << -39 << 4.6) + << (QVariantList() << -39 << 4.6 << 38 << QChar('a') << "Hello" << "World" << QChar('z')); + + QTest::newRow("custom") << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(100)) << QVariant::fromValue(CustomConvertibleType(50))) + << (QVariantList() << QVariant::fromValue(CustomConvertibleType(1)) << QVariant::fromValue(CustomConvertibleType(50)) << QVariant::fromValue(CustomConvertibleType(100))); +} + +void tst_QMetaType::compareCustomType() +{ + QFETCH(QVariantList, unsorted); + QFETCH(QVariantList, sorted); + qSort(unsorted); + QCOMPARE(unsorted, sorted); +} + +struct MessageHandlerCustom : public MessageHandler +{ + MessageHandlerCustom(const int typeId) + : MessageHandler(typeId, handler) + {} + static void handler(QtMsgType, const QMessageLogContext &, const QString &msg) + { + QCOMPARE(msg.trimmed(), expectedMessage.trimmed()); + } + static QString expectedMessage; +}; + +QString MessageHandlerCustom::expectedMessage; + +void tst_QMetaType::customDebugStream() +{ + MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>()); + QVariant v1 = QVariant::fromValue(CustomDebugStreamableType()); + handler.expectedMessage = "QVariant(CustomDebugStreamableType, )"; + qDebug() << v1; + + QMetaType::registerConverter<CustomDebugStreamableType, QString>(&CustomDebugStreamableType::toString); + handler.expectedMessage = "QVariant(CustomDebugStreamableType, \"test\")"; + qDebug() << v1; + + QMetaType::registerDebugStreamOperator<CustomDebugStreamableType>(); + handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)"; + qDebug() << v1; +} + // Compile-time test, it should be possible to register function pointer types class Undefined; @@ -1781,11 +2189,15 @@ typedef Undefined (*UndefinedFunction0)(); typedef Undefined (*UndefinedFunction1)(Undefined); typedef Undefined (*UndefinedFunction2)(Undefined, Undefined); typedef Undefined (*UndefinedFunction3)(Undefined, Undefined, Undefined); +typedef Undefined (*UndefinedFunction4)(Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined, Undefined); Q_DECLARE_METATYPE(UndefinedFunction0); Q_DECLARE_METATYPE(UndefinedFunction1); Q_DECLARE_METATYPE(UndefinedFunction2); Q_DECLARE_METATYPE(UndefinedFunction3); +#ifdef Q_COMPILER_VARIADIC_TEMPLATES +Q_DECLARE_METATYPE(UndefinedFunction4); +#endif QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 1cdf39018b..8d1ea3b510 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -146,6 +146,7 @@ private slots: void connectFunctorOverloads(); void disconnectDoesNotLeakFunctor(); void connectBase(); + void qmlConnect(); }; struct QObjectCreatedOnShutdown @@ -5879,6 +5880,56 @@ void tst_QObject::connectBase() QCOMPARE( r1.count_slot3, 1 ); } +struct QmlReceiver : public QtPrivate::QSlotObjectBase +{ + int callCount; + void *magic; + + QmlReceiver() + : QtPrivate::QSlotObjectBase(&impl) + , callCount(0) + , magic(0) + {} + + static void impl(int which, QSlotObjectBase *this_, QObject *, void **metaArgs, bool *ret) + { + switch (which) { + case Destroy: delete static_cast<QmlReceiver*>(this_); return; + case Call: static_cast<QmlReceiver*>(this_)->callCount++; return; + case Compare: *ret = static_cast<QmlReceiver*>(this_)->magic == metaArgs[0]; return; + case NumOperations: break; + } + } +}; + +void tst_QObject::qmlConnect() +{ +#ifdef QT_BUILD_INTERNAL + SenderObject sender; + QmlReceiver *receiver = new QmlReceiver; + receiver->magic = receiver; + receiver->ref(); + + QVERIFY(QObjectPrivate::connect(&sender, sender.metaObject()->indexOfSignal("signal1()"), + receiver, Qt::AutoConnection)); + + QCOMPARE(receiver->callCount, 0); + sender.emitSignal1(); + QCOMPARE(receiver->callCount, 1); + + void *a[] = { + receiver + }; + QVERIFY(QObjectPrivate::disconnect(&sender, sender.metaObject()->indexOfSignal("signal1()"), reinterpret_cast<void**>(&a))); + + sender.emitSignal1(); + QCOMPARE(receiver->callCount, 1); + + receiver->destroyIfLastRef(); +#else + QSKIP("Needs QT_BUILD_INTERNAL"); +#endif +} QTEST_MAIN(tst_QObject) #include "tst_qobject.moc" diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 4d862f4fc5..dab40db0ec 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -242,6 +242,9 @@ private slots: void saveNewBuiltinWithOldStream(); void implicitConstruction(); + + void iterateContainerElements(); + void pairElements(); private: void dataStream_data(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version); @@ -990,8 +993,8 @@ void tst_QVariant::toString_data() QTest::newRow( "float" ) << QVariant( 123.456f ) << QString( "123.456" ); QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" ); QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" ); - QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" ); - QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" ); + QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" ); + QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56.000" ); QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) << QString( "123456789012" ); QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello"); @@ -3392,5 +3395,312 @@ void tst_QVariant::saveNewBuiltinWithOldStream() QCOMPARE(int(data.constData()[3]), 0); } +template<typename Container, typename Value_Type = typename Container::value_type> +struct ContainerAPI +{ + static void insert(Container &container, typename Container::value_type value) + { + container.push_back(value); + } + + static bool compare(const QVariant &variant, typename Container::value_type value) + { + return variant.value<typename Container::value_type>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<typename Container> +struct ContainerAPI<Container, QVariant> +{ + static void insert(Container &container, int value) + { + container.push_back(QVariant::fromValue(value)); + } + + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<typename Container> +struct ContainerAPI<Container, QString> +{ + static void insert(Container &container, int value) + { + container.push_back(QString::number(value)); + } + + static bool compare(const QVariant &variant, QString value) + { + return variant.value<QString>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +// We have no built-in defines to check the stdlib features. +// #define TEST_FORWARD_LIST + +#ifdef TEST_FORWARD_LIST +#include <forward_list> +Q_DECLARE_METATYPE(std::forward_list<int>) +Q_DECLARE_METATYPE(std::forward_list<QVariant>) +Q_DECLARE_METATYPE(std::forward_list<QString>) + +template<typename Value_Type> +struct ContainerAPI<std::forward_list<Value_Type> > +{ + static void insert(std::forward_list<Value_Type> &container, Value_Type value) + { + container.push_front(value); + } + static bool compare(const QVariant &variant, Value_Type value) + { + return variant.value<Value_Type>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<> +struct ContainerAPI<std::forward_list<QVariant> > +{ + static void insert(std::forward_list<QVariant> &container, int value) + { + container.push_front(QVariant::fromValue(value)); + } + + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; + +template<> +struct ContainerAPI<std::forward_list<QString> > +{ + static void insert(std::forward_list<QString> &container, int value) + { + container.push_front(QString::number(value)); + } + static bool compare(const QVariant &variant, QString value) + { + return variant.value<QString>() == value; + } + static bool compare(QVariant variant, const QVariant &value) + { + return variant == value; + } +}; +#endif + +template<typename Container> +struct KeyGetter +{ + static const typename Container::key_type & get(const typename Container::const_iterator &it) + { + return it.key(); + } + static const typename Container::mapped_type & value(const typename Container::const_iterator &it) + { + return it.value(); + } +}; + +template<typename T, typename U> +struct KeyGetter<std::map<T, U> > +{ + static const T & get(const typename std::map<T, U>::const_iterator &it) + { + return it->first; + } + static const U & value(const typename std::map<T, U>::const_iterator &it) + { + return it->second; + } +}; + + +// We have no built-in defines to check the stdlib features. +// #define TEST_UNORDERED_MAP + +#ifdef TEST_UNORDERED_MAP +#include <unordered_map> +typedef std::unordered_map<int, bool> StdUnorderedMap_int_bool; +Q_DECLARE_METATYPE(StdUnorderedMap_int_bool) + +template<typename T, typename U> +struct KeyGetter<std::unordered_map<T, U> > +{ + static const T & get(const typename std::unordered_map<T, U>::const_iterator &it) + { + return it->first; + } + static const U & value(const typename std::unordered_map<T, U>::const_iterator &it) + { + return it->second; + } +}; +#endif + +void tst_QVariant::iterateContainerElements() +{ +#ifdef Q_COMPILER_RANGE_FOR + +#define TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) \ + numSeen = 0; \ + containerIter = intList.begin(); \ + for (QVariant v : listIter) { \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, *containerIter)); \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, varList.at(numSeen))); \ + ++containerIter; \ + ++numSeen; \ + } \ + QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); + +#else + +#define TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) + +#endif + +#define TEST_SEQUENTIAL_ITERATION(CONTAINER, VALUE_TYPE) \ + { \ + int numSeen = 0; \ + CONTAINER<VALUE_TYPE > intList; \ + ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 1); \ + ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 2); \ + ContainerAPI<CONTAINER<VALUE_TYPE > >::insert(intList, 3); \ + \ + QVariant listVariant = QVariant::fromValue(intList); \ + QVERIFY(listVariant.canConvert<QVariantList>()); \ + QVariantList varList = listVariant.value<QVariantList>(); \ + QCOMPARE(varList.size(), (int)std::distance(intList.begin(), intList.end())); \ + QSequentialIterable listIter = listVariant.value<QSequentialIterable>(); \ + QCOMPARE(varList.size(), listIter.size()); \ + \ + CONTAINER<VALUE_TYPE >::iterator containerIter = intList.begin(); \ + const CONTAINER<VALUE_TYPE >::iterator containerEnd = intList.end(); \ + for (int i = 0; i < listIter.size(); ++i, ++containerIter, ++numSeen) \ + { \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(listIter.at(i), *containerIter)); \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(listIter.at(i), varList.at(i))); \ + } \ + QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ + QCOMPARE(containerIter, containerEnd); \ + \ + containerIter = intList.begin(); \ + numSeen = 0; \ + Q_FOREACH (const QVariant &v, listIter) { \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, *containerIter)); \ + QVERIFY(ContainerAPI<CONTAINER<VALUE_TYPE > >::compare(v, varList.at(numSeen))); \ + ++containerIter; \ + ++numSeen; \ + } \ + QCOMPARE(numSeen, (int)std::distance(intList.begin(), intList.end())); \ + TEST_RANGE_FOR(CONTAINER, VALUE_TYPE) \ + } + + TEST_SEQUENTIAL_ITERATION(QVector, int) + TEST_SEQUENTIAL_ITERATION(QVector, QVariant) + TEST_SEQUENTIAL_ITERATION(QVector, QString) + TEST_SEQUENTIAL_ITERATION(QQueue, int) + TEST_SEQUENTIAL_ITERATION(QQueue, QVariant) + TEST_SEQUENTIAL_ITERATION(QQueue, QString) + TEST_SEQUENTIAL_ITERATION(QList, int) + TEST_SEQUENTIAL_ITERATION(QList, QVariant) + TEST_SEQUENTIAL_ITERATION(QList, QString) + TEST_SEQUENTIAL_ITERATION(QStack, int) + TEST_SEQUENTIAL_ITERATION(QStack, QVariant) + TEST_SEQUENTIAL_ITERATION(QStack, QString) + TEST_SEQUENTIAL_ITERATION(std::vector, int) + TEST_SEQUENTIAL_ITERATION(std::vector, QVariant) + TEST_SEQUENTIAL_ITERATION(std::vector, QString) + TEST_SEQUENTIAL_ITERATION(std::list, int) + TEST_SEQUENTIAL_ITERATION(std::list, QVariant) + TEST_SEQUENTIAL_ITERATION(std::list, QString) + +#ifdef TEST_FORWARD_LIST + qRegisterSequentialConverter<std::forward_list<int> >(); + qRegisterSequentialConverter<std::forward_list<QVariant> >(); + qRegisterSequentialConverter<std::forward_list<QString> >(); + TEST_SEQUENTIAL_ITERATION(std::forward_list, int) + TEST_SEQUENTIAL_ITERATION(std::forward_list, QVariant) + TEST_SEQUENTIAL_ITERATION(std::forward_list, QString) +#endif + +#define TEST_ASSOCIATIVE_ITERATION(CONTAINER, KEY_TYPE, MAPPED_TYPE) \ + { \ + int numSeen = 0; \ + CONTAINER<KEY_TYPE, MAPPED_TYPE> mapping; \ + mapping[5] = true; \ + mapping[15] = false; \ + \ + QVariant mappingVariant = QVariant::fromValue(mapping); \ + QVariantMap varMap = mappingVariant.value<QVariantMap>(); \ + QVariantMap varHash = mappingVariant.value<QVariantMap>(); \ + QAssociativeIterable mappingIter = mappingVariant.value<QAssociativeIterable>(); \ + \ + CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerIter = mapping.begin(); \ + const CONTAINER<KEY_TYPE, MAPPED_TYPE>::const_iterator containerEnd = mapping.end(); \ + for ( ; containerIter != containerEnd; ++containerIter, ++numSeen) \ + { \ + MAPPED_TYPE expected = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::value(containerIter); \ + KEY_TYPE key = KeyGetter<CONTAINER<KEY_TYPE, MAPPED_TYPE> >::get(containerIter); \ + MAPPED_TYPE actual = mappingIter.value(key).value<MAPPED_TYPE >(); \ + QCOMPARE(varMap.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ + QCOMPARE(varHash.value(QString::number(key)).value<MAPPED_TYPE>(), expected); \ + QCOMPARE(actual, expected); \ + } \ + QCOMPARE(numSeen, (int)std::distance(mapping.begin(), mapping.end())); \ + QCOMPARE(containerIter, containerEnd); \ + \ + } + + TEST_ASSOCIATIVE_ITERATION(QHash, int, bool) + TEST_ASSOCIATIVE_ITERATION(QMap, int, bool) + TEST_ASSOCIATIVE_ITERATION(std::map, int, bool) +#ifdef TEST_UNORDERED_MAP + qRegisterAssociativeConverter<StdUnorderedMap_int_bool>(); + TEST_ASSOCIATIVE_ITERATION(std::unordered_map, int, bool) +#endif +} + +void tst_QVariant::pairElements() +{ + typedef QPair<QVariant, QVariant> QVariantPair; + +#define TEST_PAIR_ELEMENT_ACCESS(PAIR, T1, T2, VALUE1, VALUE2) \ + { \ + PAIR<T1, T2> p(VALUE1, VALUE2); \ + QVariant v = QVariant::fromValue(p); \ + \ + QVERIFY(v.canConvert<QVariantPair>()); \ + QVariantPair pi = v.value<QVariantPair>(); \ + QCOMPARE(pi.first, QVariant::fromValue(VALUE1)); \ + QCOMPARE(pi.second, QVariant::fromValue(VALUE2)); \ + } + + TEST_PAIR_ELEMENT_ACCESS(QPair, int, int, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(std::pair, int, int, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(QPair, QString, QString, QStringLiteral("one"), QStringLiteral("two")) + TEST_PAIR_ELEMENT_ACCESS(std::pair, QString, QString, QStringLiteral("one"), QStringLiteral("two")) + TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, QVariant, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, QVariant, 4, 5) + TEST_PAIR_ELEMENT_ACCESS(QPair, QVariant, int, 41, 15) + TEST_PAIR_ELEMENT_ACCESS(std::pair, QVariant, int, 34, 65) + TEST_PAIR_ELEMENT_ACCESS(QPair, int, QVariant, 24, 25) + TEST_PAIR_ELEMENT_ACCESS(std::pair, int, QVariant, 44, 15) +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc" diff --git a/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp b/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp new file mode 100644 index 0000000000..d5c933e3af --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/fakeplugin.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Intel Corporation +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qplugin.h> + +#if QT_POINTER_SIZE == 8 +QT_PLUGIN_METADATA_SECTION void *const pluginSection = (void*)(0xc0ffeec0ffeeL); +#else +QT_PLUGIN_METADATA_SECTION void *const pluginSection = (void*)0xc0ffee; +#endif +QT_PLUGIN_METADATA_SECTION const char message[] = "QTMETADATA"; diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl b/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl new file mode 100755 index 0000000000..ec0dd980a9 --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/generate-bad.pl @@ -0,0 +1,209 @@ +#!/usr/bin/perl +############################################################################# +## +## Copyright (C) 2013 Intel Corporation. +## Contact: http://www.qt-project.org/legal +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and Digia. For licensing terms and +## conditions see http://qt.digia.com/licensing. For further information +## use the contact form at http://qt.digia.com/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, 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, Digia gives you certain additional +## rights. These rights are described in the Digia 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. +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +use strict; +use constant FAT_MAGIC => 0xcafebabe; +use constant MH_MAGIC => 0xfeedface; +use constant MH_MAGIC_64 => 0xfeedfacf; +use constant CPU_TYPE_X86 => 7; +use constant CPU_TYPE_X86_64 => CPU_TYPE_X86 | 0x01000000; +use constant CPU_SUBTYPE_I386_ALL => 3; +use constant MH_DYLIB => 6; +use constant LC_SEGMENT => 1; +use constant LC_SEGMENT_64 => 0x19; + +my $good = pack("(L7 L2 Z16 L8 Z16 Z16 L9 . L)>", + MH_MAGIC, CPU_TYPE_X86, CPU_SUBTYPE_I386_ALL, MH_DYLIB, # 0-3 + 1, # 4: ncmds + 4 * (37 - 6), # 5: sizeofcmds + 0, # 6: flags + + LC_SEGMENT, # 7: cmd + 4 * (37 - 6), # 8: cmdsize + '__TEXT', # 9-12: segname + 0, # 13: vmaddr + 0x1000, # 14: vmsize + 0, # 15: fileoff + 0x204, # 16: filesize + 7, # 17: maxprot (rwx) + 5, # 18: initprot (r-x) + 1, # 19: nsects + 0, # 20: flags + + 'qtmetadata', # 21-24: sectname + '__TEXT', # 25-28: segname + 0x200, # 29: addr + 4, # 30: size + 0x200, # 31: offset + 2, # 32: align (2^2) + 0, # 33: reloff + 0, # 34: nreloc + 0, # 35: flags + 0, # 36: reserved1 + 0, # 37: reserved2 + + 0x200, + 0xc0ffee # data +); + +my $good64 = pack("(L8 L2 Z16 Q4 L4 Z16 Z16 Q2 L8 . Q)>", + MH_MAGIC_64, CPU_TYPE_X86_64, CPU_SUBTYPE_I386_ALL, MH_DYLIB, # 0-3 + 1, # 4: ncmds + 4 * (45 - 7), # 5: sizeofcmds + 0, # 6: flags + 0, # 7: reserved + + LC_SEGMENT_64, # 8: cmd + 4 * (45 - 7), # 9: cmdsize + '__TEXT', # 10-13: segname + 0, # 14-15: vmaddr + 0x1000, # 16-17: vmsize + 0, # 18-19: fileoff + 0x208, # 20-21: filesize + 7, # 22: maxprot (rwx) + 5, # 23: initprot (r-x) + 1, # 24: nsects + 0, # 25: flags + + 'qtmetadata', # 26-29: sectname + '__TEXT', # 30-33: segname + 0x200, # 34-35: addr + 4, # 36-37: size + 0x200, # 38: offset + 3, # 39: align (2^3) + 0, # 40: reloff + 0, # 41: nreloc + 0, # 42: flags + 0, # 43: reserved1 + 0, # 44: reserved2 + 0, # 45: reserved3 + + 0x200, + 0xc0ffeec0ffee # data +); + +my $fat = pack("L>*", + FAT_MAGIC, # 1: magic + 2, # 2: nfat_arch + + CPU_TYPE_X86, # 3: cputype + CPU_SUBTYPE_I386_ALL, # 4: cpusubtype + 0x1000, # 5: offset + 0x1000, # 6: size + 12, # 7: align (2^12) + + CPU_TYPE_X86_64, # 8: cputype + CPU_SUBTYPE_I386_ALL, # 9: cpusubtype + 0x2000, # 10: offset + 0x1000, # 11: size + 12, # 12: align (2^12) +); + +my $buffer; + +our $badcount = 1; +sub generate($) { + open OUT, ">", "bad$badcount.dylib" or die("Could not open file bad$badcount.dylib: $!\n"); + binmode OUT; + print OUT $_[0]; + close OUT; + ++$badcount; +} + +# Bad file 1-2 +# Except that the cmdsize fields are null +$buffer = $good; +vec($buffer, 5, 32) = 0; +generate $buffer; + +$buffer = $good; +vec($buffer, 8, 32) = 0; +generate $buffer; + +# Bad file 3-4: same as above but 64-bit +$buffer = $good64; +vec($buffer, 5, 32) = 0; +generate $buffer; + +$buffer = $good64; +vec($buffer, 9, 32) = 0; +generate $buffer; + +# Bad file 5-8: same as 1-4, but set cmdsize to bigger than file +$buffer = $good; +vec($buffer, 5, 32) = 0x1000; +generate $buffer; + +$buffer = $good; +vec($buffer, 8, 32) = 0x1000; +generate $buffer; + +$buffer = $good64; +vec($buffer, 5, 32) = 0x1000; +generate $buffer; + +$buffer = $good64; +vec($buffer, 9, 32) = 0x1000; +generate $buffer; + +# Bad file 9-10: overflow size+offset +$buffer = $good; +vec($buffer, 30, 32) = 0xffffffe0; +generate $buffer; + +$buffer = $good64; +vec($buffer, 36, 32) = 0xffffffff; +vec($buffer, 37, 32) = 0xffffffe0; +generate $buffer; + +# Bad file 11: FAT binary with just the header +generate $fat; + +# Bad file 12: FAT binary where the Mach contents don't match the FAT directory +$buffer = pack("a4096 a4096 a4096", $fat, $good64, $good); +generate $buffer; + +# Bad file 13: FAT binary with overflowing size +$buffer = pack("a4096 a4096 a4096", $fat, $good, $good64); +vec($buffer, 5, 32) = 0xfffffffe0; +vec($buffer, 10, 32) = 0xfffffffe0; +generate $buffer; diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro new file mode 100644 index 0000000000..7acddc22ce --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro @@ -0,0 +1,56 @@ +TEMPLATE = aux +OTHER_FILES += \ + ppcconverter.pl \ + generate-bad.pl + +i386.target = good.i386.dylib +i386.commands = $(CXX) $(CXXFLAGS) -shared -arch i386 -o $@ -I$$[QT_INSTALL_HEADERS/get] $< +i386.depends += $$PWD/../fakeplugin.cpp +x86_64.target = good.x86_64.dylib +x86_64.commands = $(CXX) $(CXXFLAGS) -shared -arch x86_64 -o $@ -I$$[QT_INSTALL_HEADERS/get] $< +x86_64.depends += $$PWD/../fakeplugin.cpp + +# Current Mac OS X toolchains have no compiler for PPC anymore +# So we fake it by converting an x86-64 binary to (little-endian!) PPC64 +ppc64.target = good.ppc64.dylib +ppc64.commands = $$PWD/ppcconverter.pl $< $@ +ppc64.depends = x86_64 $$PWD/ppcconverter.pl + +# Generate a fat binary with three architectures +fat_all.target = good.fat.all.dylib +fat_all.commands = lipo -create -output $@ \ + -arch ppc64 $$ppc64.target \ + -arch i386 $$i386.target \ + -arch x86_64 $$x86_64.target +fat_all.depends += i386 x86_64 ppc64 + +fat_no_i386.target = good.fat.no-i386.dylib +fat_no_i386.commands = lipo -create -output $@ -arch x86_64 $$x86_64.target -arch ppc64 $$ppc64.target +fat_no_i386.depends += x86_64 ppc64 + +fat_no_x86_64.target = good.fat.no-x86_64.dylib +fat_no_x86_64.commands = lipo -create -output $@ -arch i386 $$i386.target -arch ppc64 $$ppc64.target +fat_no_x86_64.depends += i386 ppc64 + +fat_stub_i386.target = good.fat.stub-i386.dylib +fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 $$ppc64.target -arch_blank i386 +fat_stub_i386.depends += x86_64 ppc64 + +fat_stub_x86_64.target = good.fat.stub-x86_64.dylib +fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 $$ppc64.target -arch_blank x86_64 +fat_stub_x86_64.depends += i386 ppc64 + +bad.commands = $$PWD/generate-bad.pl +bad.depends += $$PWD/generate-bad.pl + +MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \ + fat_stub_i386 fat_stub_x86_64 bad +all.depends += $$MYTARGETS +QMAKE_EXTRA_TARGETS += $$MYTARGETS all + +QMAKE_CLEAN += $$i386.target $$x86_64.target $$ppc64.target $$fat_all.target \ + $$fat_no_i386.target $$fat_no_x86_64.target \ + $$fat_stub_i386.target $$fat_stub_x86_64.target \ + "bad*.dylib" + + diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl b/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl new file mode 100755 index 0000000000..86943161b7 --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/ppcconverter.pl @@ -0,0 +1,112 @@ +#!/usr/bin/perl +############################################################################# +## +## Copyright (C) 2013 Intel Corporation. +## Contact: http://www.qt-project.org/legal +## +## This file is the build configuration utility of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and Digia. For licensing terms and +## conditions see http://qt.digia.com/licensing. For further information +## use the contact form at http://qt.digia.com/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, 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, Digia gives you certain additional +## rights. These rights are described in the Digia 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. +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +# Changes the Mach-O file type header to PowerPC. +# +# The header is (from mach-o/loader.h): +# struct mach_header { +# uint32_t magic; /* mach magic number identifier */ +# cpu_type_t cputype; /* cpu specifier */ +# cpu_subtype_t cpusubtype; /* machine specifier */ +# uint32_t filetype; /* type of file */ +# uint32_t ncmds; /* number of load commands */ +# uint32_t sizeofcmds; /* the size of all the load commands */ +# uint32_t flags; /* flags */ +# }; +# +# The 64-bit header is identical in the first three fields, except for a different +# magic number. We will not touch the magic number, we'll just reset the cputype +# field to the PowerPC type and the subtype field to zero. +# +# We will not change the file's endianness. That means we might create a little-endian +# PowerPC binary, which could not be run in real life. +# +# We will also not change the 64-bit ABI flag, which is found in the cputype's high +# byte. That means we'll create a PPC64 binary if fed a 64-bit input. +# +use strict; +use constant MH_MAGIC => 0xfeedface; +use constant MH_CIGAM => 0xcefaedfe; +use constant MH_MAGIC_64 => 0xfeedfacf; +use constant MH_CIGAM_64 => 0xcffaedfe; +use constant CPU_TYPE_POWERPC => 18; +use constant CPU_SUBTYPE_POWERPC_ALL => 0; + +my $infile = shift @ARGV or die("Missing input filename"); +my $outfile = shift @ARGV or die("Missing output filename"); + +open IN, "<$infile" or die("Can't open $infile for reading: $!\n"); +open OUT, ">$outfile" or die("Can't open $outfile for writing: $!\n"); + +binmode IN; +binmode OUT; + +# Read the first 12 bytes, which includes the interesting fields of the header +my $buffer; +read(IN, $buffer, 12); + +my $magic = vec($buffer, 0, 32); +if ($magic == MH_MAGIC || $magic == MH_MAGIC_64) { + # Big endian + # The low byte of cputype is at offset 7 + vec($buffer, 7, 8) = CPU_TYPE_POWERPC; +} elsif ($magic == MH_CIGAM || $magic == MH_CIGAM_64) { + # Little endian + # The low byte of cpytype is at offset 4 + vec($buffer, 4, 8) = CPU_TYPE_POWERPC; +} else { + $magic = ''; + $magic .= sprintf("%02X ", $_) for unpack("CCCC", $buffer); + die("Invalid input. Unknown magic $magic\n"); +} +vec($buffer, 2, 32) = CPU_SUBTYPE_POWERPC_ALL; + +print OUT $buffer; + +# Copy the rest +while (!eof(IN)) { + read(IN, $buffer, 4096) and + print OUT $buffer or + die("Problem copying: $!\n"); +} +close(IN); +close(OUT); diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro index 0cba19887e..8d117793bf 100644 --- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro +++ b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro @@ -5,6 +5,7 @@ SUBDIRS = lib \ theplugin \ tst !win32: !mac: SUBDIRS += almostplugin +macx-*: SUBDIRS += machtest TARGET = tst_qpluginloader # no special install rule for subdir diff --git a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro index a7a9661a54..3894c90ae3 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro +++ b/tests/auto/corelib/plugin/qpluginloader/tst/tst.pro @@ -2,7 +2,8 @@ CONFIG += testcase CONFIG += parallel_test TARGET = ../tst_qpluginloader QT = core testlib -SOURCES = ../tst_qpluginloader.cpp +contains(QT_CONFIG, private_tests): QT += core-private +SOURCES = ../tst_qpluginloader.cpp ../fakeplugin.cpp HEADERS = ../theplugin/plugininterface.h CONFIG -= app_bundle @@ -14,5 +15,5 @@ win32 { } } -TESTDATA += ../elftest +TESTDATA += ../elftest ../machtest DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index cef4f53101..351e3a23e0 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -44,6 +44,10 @@ #include <qpluginloader.h> #include "theplugin/plugininterface.h" +#if defined(QT_BUILD_INTERNAL) && defined(Q_OF_MACH_O) +# include <QtCore/private/qmachparser_p.h> +#endif + // Helper macros to let us know if some suffixes are valid #define bundle_VALID false #define dylib_VALID false @@ -118,6 +122,8 @@ private slots: void deleteinstanceOnUnload(); void loadDebugObj(); void loadCorruptElf(); + void loadMachO_data(); + void loadMachO(); #if defined (Q_OS_UNIX) void loadGarbage(); #endif @@ -311,6 +317,78 @@ void tst_QPluginLoader::loadCorruptElf() #endif } +void tst_QPluginLoader::loadMachO_data() +{ +#ifdef Q_OF_MACH_O + QTest::addColumn<int>("parseResult"); + + QTest::newRow("/dev/null") << int(QMachOParser::NotSuitable); + QTest::newRow("elftest/debugobj.so") << int(QMachOParser::NotSuitable); + QTest::newRow("tst_qpluginloader.cpp") << int(QMachOParser::NotSuitable); + QTest::newRow("tst_qpluginloader") << int(QMachOParser::NotSuitable); + +# ifdef Q_PROCESSOR_X86_64 + QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::QtMetaDataSection); + QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::NotSuitable); + QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::NotSuitable); + QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::QtMetaDataSection); +# elif defined(Q_PROCESSOR_X86_32) + QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::QtMetaDataSection); + QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::NotSuitable); + QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::NotSuitable); + QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::QtMetaDataSection); +# endif +# ifndef Q_PROCESSOR_POWER_64 + QTest::newRow("machtest/good.ppc64.dylib") << int(QMachOParser::NotSuitable); +# endif + + QTest::newRow("machtest/good.fat.all.dylib") << int(QMachOParser::QtMetaDataSection); + QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << int(QMachOParser::NotSuitable); + QTest::newRow("machtest/good.fat.stub-i386.dylib") << int(QMachOParser::NotSuitable); + + QDir d(QFINDTESTDATA("machtest")); + QStringList badlist = d.entryList(QStringList() << "bad*.dylib"); + foreach (const QString &bad, badlist) + QTest::newRow(qPrintable("machtest/" + bad)) << int(QMachOParser::NotSuitable); +#endif +} + +void tst_QPluginLoader::loadMachO() +{ +#ifdef Q_OF_MACH_O + QFile f(QFINDTESTDATA(QTest::currentDataTag())); + QVERIFY(f.open(QIODevice::ReadOnly)); + QByteArray data = f.readAll(); + + long pos; + ulong len; + QString errorString; + int r = QMachOParser::parse(data.constData(), data.size(), f.fileName(), &errorString, &pos, &len); + + QFETCH(int, parseResult); + QCOMPARE(r, parseResult); + + if (r == QMachOParser::NotSuitable) + return; + + QVERIFY(pos > 0); + QVERIFY(len >= sizeof(void*)); + QVERIFY(pos + long(len) < data.size()); + QCOMPARE(pos & (sizeof(void*) - 1), 0UL); + + void *value = *(void**)(data.constData() + pos); + QCOMPARE(value, sizeof(void*) > 4 ? (void*)(0xc0ffeec0ffeeL) : (void*)0xc0ffee); + + // now that we know it's valid, let's try to make it invalid + ulong offeredlen = pos; + do { + --offeredlen; + r = QMachOParser::parse(data.constData(), offeredlen, f.fileName(), &errorString, &pos, &len); + QVERIFY2(r == QMachOParser::NotSuitable, qPrintable(QString("Failed at size 0x%1").arg(offeredlen, 0, 16))); + } while (offeredlen); +#endif +} + #if defined (Q_OS_UNIX) void tst_QPluginLoader::loadGarbage() { diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 3c0e132a0a..fb34afb880 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -214,22 +214,22 @@ void tst_QThreadPool::waitcomplete() QCOMPARE(testFunctionCount, runs); } -volatile bool ran; +QAtomicInt ran; // bool class TestTask : public QRunnable { public: void run() { - ran = true; + ran.store(true); } }; void tst_QThreadPool::runTask() { QThreadPool manager; - ran = false; + ran.store(false); manager.start(new TestTask()); - QTRY_VERIFY(ran); + QTRY_VERIFY(ran.load()); } /* @@ -237,19 +237,19 @@ void tst_QThreadPool::runTask() */ void tst_QThreadPool::singleton() { - ran = false; + ran.store(false); QThreadPool::globalInstance()->start(new TestTask()); - QTRY_VERIFY(ran); + QTRY_VERIFY(ran.load()); } -int *value = 0; +QAtomicInt *value = 0; class IntAccessor : public QRunnable { public: void run() { for (int i = 0; i < 100; ++i) { - ++(*value); + value->ref(); QTest::qSleep(1); } } @@ -261,7 +261,7 @@ public: */ void tst_QThreadPool::destruction() { - value = new int; + value = new QAtomicInt; QThreadPool *threadManager = new QThreadPool(); threadManager->start(new IntAccessor()); threadManager->start(new IntAccessor()); @@ -681,8 +681,8 @@ void tst_QThreadPool::tryStart() } QMutex mutex; -int activeThreads = 0; -int peakActiveThreads = 0; +QAtomicInt activeThreads; +QAtomicInt peakActiveThreads; void tst_QThreadPool::tryStartPeakThreadCount() { class CounterTask : public QRunnable @@ -694,14 +694,14 @@ void tst_QThreadPool::tryStartPeakThreadCount() { { QMutexLocker lock(&mutex); - ++activeThreads; - peakActiveThreads = qMax(peakActiveThreads, activeThreads); + activeThreads.ref(); + peakActiveThreads.store(qMax(peakActiveThreads.load(), activeThreads.load())); } QTest::qWait(100); { QMutexLocker lock(&mutex); - --activeThreads; + activeThreads.deref(); } } }; @@ -713,13 +713,13 @@ void tst_QThreadPool::tryStartPeakThreadCount() if (threadPool.tryStart(&task) == false) QTest::qWait(10); } - QCOMPARE(peakActiveThreads, QThread::idealThreadCount()); + QCOMPARE(peakActiveThreads.load(), QThread::idealThreadCount()); for (int i = 0; i < 20; ++i) { if (threadPool.tryStart(&task) == false) QTest::qWait(10); } - QCOMPARE(peakActiveThreads, QThread::idealThreadCount()); + QCOMPARE(peakActiveThreads.load(), QThread::idealThreadCount()); } void tst_QThreadPool::tryStartCount() diff --git a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp index 72bf5c58ca..c18ba4d05c 100644 --- a/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/corelib/tools/qalgorithms/tst_qalgorithms.cpp @@ -78,10 +78,22 @@ private slots: void qCountContainer() const; void binaryFindOnLargeContainer() const; -#if Q_TEST_PERFORMANCE + void popCount08_data() { popCount_data_impl(sizeof(quint8 )); } + void popCount16_data() { popCount_data_impl(sizeof(quint16)); } + void popCount32_data() { popCount_data_impl(sizeof(quint32)); } + void popCount64_data() { popCount_data_impl(sizeof(quint64)); } + void popCount08() { popCount_impl<quint8 >(); } + void popCount16() { popCount_impl<quint16>(); } + void popCount32() { popCount_impl<quint32>(); } + void popCount64() { popCount_impl<quint64>(); } + private: +#if Q_TEST_PERFORMANCE void performance(); #endif + void popCount_data_impl(size_t sizeof_T_Int); + template <typename T_Int> + void popCount_impl(); }; class TestInt @@ -1007,6 +1019,72 @@ void tst_QAlgorithms::binaryFindOnLargeContainer() const QCOMPARE(foundIt.pos(), 1073987655); } +// alternative implementation of qPopulationCount for comparison: +static const uint bitsSetInNibble[] = { + 0, 1, 1, 2, 1, 2, 2, 3, + 1, 2, 2, 3, 2, 3, 3, 4, +}; +Q_STATIC_ASSERT(sizeof bitsSetInNibble / sizeof *bitsSetInNibble == 16); + +static Q_DECL_CONSTEXPR uint bitsSetInByte(quint8 byte) +{ + return bitsSetInNibble[byte & 0xF] + bitsSetInNibble[byte >> 4]; +} +static Q_DECL_CONSTEXPR uint bitsSetInShort(quint16 word) +{ + return bitsSetInByte(word & 0xFF) + bitsSetInByte(word >> 8); +} +static Q_DECL_CONSTEXPR uint bitsSetInInt(quint32 word) +{ + return bitsSetInShort(word & 0xFFFF) + bitsSetInShort(word >> 16); +} +static Q_DECL_CONSTEXPR uint bitsSetInInt64(quint64 word) +{ + return bitsSetInInt(word & 0xFFFFFFFF) + bitsSetInInt(word >> 32); +} + + +void tst_QAlgorithms::popCount_data_impl(size_t sizeof_T_Int) +{ + using namespace QTest; + addColumn<quint64>("input"); + addColumn<uint>("expected"); + + for (uint i = 0; i < UCHAR_MAX; ++i) { + const uchar byte = static_cast<uchar>(i); + const uint bits = bitsSetInByte(byte); + const quint64 value = static_cast<quint64>(byte); + const quint64 input = value << ((i % sizeof_T_Int) * 8U); + newRow(qPrintable(QString().sprintf("0x%016llx", input))) << input << bits; + } + + // and some random ones: + if (sizeof_T_Int >= 8) + for (size_t i = 0; i < 1000; ++i) { + const quint64 input = quint64(qrand()) << 32 | quint32(qrand()); + newRow(qPrintable(QString().sprintf("0x%016llx", input))) << input << bitsSetInInt64(input); + } + else if (sizeof_T_Int >= 2) + for (size_t i = 0; i < 1000 ; ++i) { + const quint32 input = qrand(); + if (sizeof_T_Int >= 4) + newRow(qPrintable(QString().sprintf("0x%08x", input))) << quint64(input) << bitsSetInInt(input); + else + newRow(qPrintable(QString().sprintf("0x%04x", quint16(input & 0xFFFF)))) << quint64(input & 0xFFFF) << bitsSetInShort(input & 0xFFFF); + } +} + +template <typename T_Int> +void tst_QAlgorithms::popCount_impl() +{ + QFETCH(quint64, input); + QFETCH(uint, expected); + + const T_Int value = static_cast<T_Int>(input); + + QCOMPARE(qPopulationCount(value), expected); +} + QTEST_APPLESS_MAIN(tst_QAlgorithms) #include "tst_qalgorithms.moc" diff --git a/tests/auto/corelib/tools/qdate/tst_qdate.cpp b/tests/auto/corelib/tools/qdate/tst_qdate.cpp index 310528ba27..728a4244a1 100644 --- a/tests/auto/corelib/tools/qdate/tst_qdate.cpp +++ b/tests/auto/corelib/tools/qdate/tst_qdate.cpp @@ -944,6 +944,61 @@ void tst_QDate::fromStringDateFormat_data() QTest::newRow("iso2") << QDate(1999, 11, 14).toString(Qt::ISODate) << Qt::ISODate << QDate(1999, 11, 14); QTest::newRow("iso3") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1); QTest::newRow("iso3b") << QString("0999-01-01") << Qt::ISODate << QDate(999, 1, 1); + + // Test Qt::RFC2822Date format (RFC 2822). + QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDate(1987, 2, 13); + QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QDate(1970, 1, 1); + // No timezone + QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34") + << Qt::RFC2822Date << QDate(1970, 1, 1); + // No time specified + QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002") + << Qt::RFC2822Date << QDate(2002, 11, 1); + QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002") + << Qt::RFC2822Date << QDate(2002, 11, 1); + // Test invalid month, day, year + QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100") + << Qt::RFC2822Date << QDate(); + // Test invalid characters (should ignore invalid characters at end of string). + QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + << Qt::RFC2822Date << QDate(2012, 1, 1); + QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000") + << Qt::RFC2822Date << QDate(); + + // Test Qt::RFC2822Date format (RFC 850 and 1036). + QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100") + << Qt::RFC2822Date << QDate(1987, 2, 13); + // No timezone + QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970") + << Qt::RFC2822Date << QDate(1970, 1, 1); + // No time specified + QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002") + << Qt::RFC2822Date << QDate(2002, 11, 1); + // Test invalid characters (should ignore invalid characters at end of string). + QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") + << Qt::RFC2822Date << QDate(2012, 1, 1); + QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..") + << Qt::RFC2822Date << QDate(); + QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000") + << Qt::RFC2822Date << QDate(); + + QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << QDate(); } void tst_QDate::fromStringDateFormat() @@ -1072,6 +1127,7 @@ void tst_QDate::toStringDateFormat_data() QTest::newRow("data3") << QDate(1974,12,1) << Qt::ISODate << QString("1974-12-01"); QTest::newRow("year < 0") << QDate(-1,1,1) << Qt::ISODate << QString(); QTest::newRow("year > 9999") << QDate(-1,1,1) << Qt::ISODate << QString(); + QTest::newRow("RFC2822Date") << QDate(1974,12,1) << Qt::RFC2822Date << QString("01 Dec 1974"); } void tst_QDate::toStringDateFormat() diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 0ec3f64020..a0e55e9ae1 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -85,6 +85,8 @@ private slots: void fromMSecsSinceEpoch(); void toString_isoDate_data(); void toString_isoDate(); + void toString_rfcDate_data(); + void toString_rfcDate(); void toString_enumformat(); void toString_strformat_data(); void toString_strformat(); @@ -556,22 +558,25 @@ void tst_QDateTime::toString_isoDate_data() QTest::newRow("localtime") << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34)) - << QString("1978-11-09T13:28:34"); + << QString("1978-11-09T13:28:34.000"); QTest::newRow("UTC") << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC) - << QString("1978-11-09T13:28:34Z"); + << QString("1978-11-09T13:28:34.000Z"); QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34)); dt.setUtcOffset(19800); QTest::newRow("positive OffsetFromUTC") << dt - << QString("1978-11-09T13:28:34+05:30"); + << QString("1978-11-09T13:28:34.000+05:30"); dt.setUtcOffset(-7200); QTest::newRow("negative OffsetFromUTC") << dt - << QString("1978-11-09T13:28:34-02:00"); + << QString("1978-11-09T13:28:34.000-02:00"); QTest::newRow("invalid") << QDateTime(QDate(-1, 11, 9), QTime(13, 28, 34), Qt::UTC) << QString(); + QTest::newRow("999 milliseconds UTC") + << QDateTime(QDate(2000, 1, 1), QTime(13, 28, 34, 999), Qt::UTC) + << QString("2000-01-01T13:28:34.999Z"); } void tst_QDateTime::toString_isoDate() @@ -582,6 +587,44 @@ void tst_QDateTime::toString_isoDate() QCOMPARE(dt.toString(Qt::ISODate), formatted); } +void tst_QDateTime::toString_rfcDate_data() +{ + QTest::addColumn<QDateTime>("dt"); + QTest::addColumn<QString>("formatted"); + + if (europeanTimeZone) { + QTest::newRow("localtime") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34)) + << QString("09 Nov 1978 13:28:34 +0100"); + } + QTest::newRow("UTC") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC) + << QString("09 Nov 1978 13:28:34 +0000"); + QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34)); + dt.setUtcOffset(19800); + QTest::newRow("positive OffsetFromUTC") + << dt + << QString("09 Nov 1978 13:28:34 +0530"); + dt.setUtcOffset(-7200); + QTest::newRow("negative OffsetFromUTC") + << dt + << QString("09 Nov 1978 13:28:34 -0200"); + QTest::newRow("invalid") + << QDateTime(QDate(1978, 13, 9), QTime(13, 28, 34), Qt::UTC) + << QString(); + QTest::newRow("999 milliseconds UTC") + << QDateTime(QDate(2000, 1, 1), QTime(13, 28, 34, 999), Qt::UTC) + << QString("01 Jan 2000 13:28:34 +0000"); +} + +void tst_QDateTime::toString_rfcDate() +{ + QFETCH(QDateTime, dt); + QFETCH(QString, formatted); + + QCOMPARE(dt.toString(Qt::RFC2822Date), formatted); +} + void tst_QDateTime::toString_enumformat() { QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56)); @@ -591,7 +634,7 @@ void tst_QDateTime::toString_enumformat() QVERIFY(!str1.isEmpty()); // It's locale dependent everywhere QString str2 = dt1.toString(Qt::ISODate); - QCOMPARE(str2, QString("1995-05-20T12:34:56")); + QCOMPARE(str2, QString("1995-05-20T12:34:56.000")); QString str3 = dt1.toString(Qt::LocalDate); QVERIFY(!str3.isEmpty()); @@ -1611,6 +1654,8 @@ void tst_QDateTime::fromStringDateFormat_data() << Qt::TextDate << invalidDateTime(); QTest::newRow("text invalid gmt minute") << QString::fromLatin1("Thu 1. Jan 1970 00:00:00 GMT+000X") << Qt::TextDate << invalidDateTime(); + QTest::newRow("text second fraction") << QString::fromLatin1("Mon 6. May 2013 01:02:03.456") + << Qt::TextDate << QDateTime(QDate(2013, 5, 6), QTime(1, 2, 3, 456)); // Test Qt::ISODate format. QTest::newRow("ISO +01:00") << QString::fromLatin1("1987-02-13T13:24:51+01:00") @@ -1697,6 +1742,79 @@ void tst_QDateTime::fromStringDateFormat_data() QTest::newRow("ISO .99999 of a minute (comma)") << QString::fromLatin1("2012-01-01T08:00,99999") << Qt::ISODate << QDateTime(QDate(2012, 1, 1), QTime(8, 0, 59, 999), Qt::LocalTime); QTest::newRow("ISO empty") << QString::fromLatin1("") << Qt::ISODate << invalidDateTime(); + + // Test Qt::RFC2822Date format (RFC 2822). + QTest::newRow("RFC 2822 +0100") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("RFC 2822 with day +0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("RFC 2822 -0100") << QString::fromLatin1("13 Feb 1987 13:24:51 -0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); + QTest::newRow("RFC 2822 with day -0100") << QString::fromLatin1("Fri, 13 Feb 1987 13:24:51 -0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); + QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + QTest::newRow("RFC 2822 +0000") << QString::fromLatin1("01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + QTest::newRow("RFC 2822 with day +0000") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + // No timezone assume UTC + QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + // No time specified + QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002") + << Qt::RFC2822Date << invalidDateTime(); + // Test invalid month, day, year + QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100") + << Qt::RFC2822Date << invalidDateTime(); + // Test invalid characters (should ignore invalid characters at end of string). + QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC); + QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000") + << Qt::RFC2822Date << invalidDateTime(); + + // Test Qt::RFC2822Date format (RFC 850 and 1036). + QTest::newRow("RFC 850 and 1036 +0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(12, 24, 51), Qt::UTC); + QTest::newRow("RFC 850 and 1036 -0100") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 -0100") + << Qt::RFC2822Date << QDateTime(QDate(1987, 2, 13), QTime(14, 24, 51), Qt::UTC); + QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + QTest::newRow("RFC 850 and 1036 +0000") << QString::fromLatin1("Thu Jan 01 00:12:34 1970 +0000") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + // No timezone assume UTC + QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970") + << Qt::RFC2822Date << QDateTime(QDate(1970, 1, 1), QTime(0, 12, 34), Qt::UTC); + // No time specified + QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002") + << Qt::RFC2822Date << invalidDateTime(); + // Test invalid characters (should ignore invalid characters at end of string). + QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") + << Qt::RFC2822Date << QDateTime(QDate(2012, 1, 1), QTime(7, 0, 0, 0), Qt::UTC); + QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..") + << Qt::RFC2822Date << invalidDateTime(); + QTest::newRow("RFC 850 and 1036 invalid character 2 at front") << QString::fromLatin1("!!Sun Jan 01 08:00:00 2012 +0000") + << Qt::RFC2822Date << invalidDateTime(); + + QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidDateTime(); } void tst_QDateTime::fromStringDateFormat() diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp index fa747b3c18..3348b49110 100644 --- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp +++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp @@ -730,14 +730,16 @@ double static inline _fast_cbrt(double d) void tst_QEasingCurve::testCbrtDouble() { - const qreal errorBound = 0.0001; + const double errorBound = 0.0001; for (int i = 0; i < 100000; i++) { double d = double(i) / 1000.0; double t = _fast_cbrt(d); const double t_cubic = t * t * t; - t = t * (t_cubic + d + d) / (t_cubic + t_cubic + d); + const double f = t_cubic + t_cubic + d; + if (f != 0.0) + t = t * (t_cubic + d + d) / f; double expected = pow(d, 1.0/3.0); @@ -754,14 +756,16 @@ void tst_QEasingCurve::testCbrtDouble() void tst_QEasingCurve::testCbrtFloat() { - const qreal errorBound = 0.0005; + const float errorBound = 0.0005; - for (int i = 1; i < 100000; i++) { + for (int i = 0; i < 100000; i++) { float f = float(i) / 1000.0f; float t = _fast_cbrt(f); const float t_cubic = t * t * t; - t = t * (t_cubic + f + f) / (t_cubic + t_cubic + f); + const float fac = t_cubic + t_cubic + f; + if (fac != 0.0f) + t = t * (t_cubic + f + f) / fac; float expected = pow(f, float(1.0/3.0)); diff --git a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro index 5fa529e175..48a3b9ee9c 100644 --- a/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro +++ b/tests/auto/corelib/tools/qscopedpointer/qscopedpointer.pro @@ -1,4 +1,5 @@ CONFIG += testcase parallel_test +contains(QT_CONFIG, c++11):CONFIG += c++11 TARGET = tst_qscopedpointer QT = core testlib SOURCES = tst_qscopedpointer.cpp diff --git a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp index 66ea3e940c..cb0382eb66 100644 --- a/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp +++ b/tests/auto/corelib/tools/qscopedpointer/tst_qscopedpointer.cpp @@ -42,6 +42,8 @@ #include <QtTest/QtTest> #include <QtCore/QScopedPointer> +#include <utility> + /*! \class tst_QScopedPointer \internal @@ -73,6 +75,7 @@ private Q_SLOTS: void objectSize(); void comparison(); void array(); + void move(); // TODO instanciate on const object }; @@ -458,6 +461,158 @@ void tst_QScopedPointer::array() QCOMPARE(instCount, RefCounted::instanceCount.load()); } +#ifdef Q_COMPILER_RVALUE_REFS +struct CountedInteger +{ + CountedInteger(int i) : i(i) + { + ++instanceCount; + } + ~CountedInteger() + { + --instanceCount; + } + CountedInteger(const CountedInteger &c) + : i(c.i) + { + ++instanceCount; + } + + static int instanceCount; + int i; +}; + +int CountedInteger::instanceCount = 0; + +QScopedPointer<CountedInteger> returnScopedPointer(int i) +{ + return QScopedPointer<CountedInteger>(new CountedInteger(i)); +} +#endif + +void tst_QScopedPointer::move() +{ +#ifndef Q_COMPILER_RVALUE_REFS + QSKIP("This test requires rvalues refs"); +#else + QCOMPARE(CountedInteger::instanceCount, 0); + + { + QScopedPointer<CountedInteger> p = returnScopedPointer(42); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, 42); + QCOMPARE(CountedInteger::instanceCount, 1); + + QScopedPointer<CountedInteger> q = returnScopedPointer(51); + QVERIFY(!q.isNull()); + QCOMPARE(q->i, 51); + QCOMPARE(CountedInteger::instanceCount, 2); + + q = returnScopedPointer(123); + QVERIFY(!q.isNull()); + QCOMPARE(q->i, 123); + QCOMPARE(CountedInteger::instanceCount, 2); + + p = std::move(q); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, 123); + QVERIFY(q.isNull()); + QCOMPARE(CountedInteger::instanceCount, 1); + + p = std::move(q); + QVERIFY(p.isNull()); + QVERIFY(q.isNull()); + QCOMPARE(CountedInteger::instanceCount, 0); + } + + QCOMPARE(CountedInteger::instanceCount, 0); + + { + QScopedPointer<CountedInteger> p = returnScopedPointer(1024); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, 1024); + QCOMPARE(CountedInteger::instanceCount, 1); + + p.reset(); + QVERIFY(p.isNull()); + QCOMPARE(CountedInteger::instanceCount, 0); + + p = returnScopedPointer(1024); + const CountedInteger * const rawPtr = p.data(); + p = std::move(p); + // now p is in a "valid, but unspecified state". so the test must not crash. + // we do actually know that this move should've been a noop. + QVERIFY(!p.isNull()); + QCOMPARE(p.data(), rawPtr); + QCOMPARE(p->i, 1024); + QCOMPARE(CountedInteger::instanceCount, 1); + + p.reset(); + QVERIFY(p.isNull()); + QCOMPARE(CountedInteger::instanceCount, 0); + } + + QCOMPARE(CountedInteger::instanceCount, 0); + + { + QScopedPointer<CountedInteger> p = returnScopedPointer(-1); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, -1); + QCOMPARE(CountedInteger::instanceCount, 1); + } + + QCOMPARE(CountedInteger::instanceCount, 0); + + { + QScopedPointer<CountedInteger> p = returnScopedPointer(0); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, 0); + QCOMPARE(CountedInteger::instanceCount, 1); + + QScopedPointer<CountedInteger> q; + QVERIFY(q.isNull()); + + p = std::move(q); + QVERIFY(p.isNull()); + QVERIFY(q.isNull()); + QCOMPARE(CountedInteger::instanceCount, 0); + } + + QCOMPARE(CountedInteger::instanceCount, 0); + + { + QScopedPointer<CountedInteger> p; + QVERIFY(p.isNull()); + QCOMPARE(CountedInteger::instanceCount, 0); + + QScopedPointer<CountedInteger> q = returnScopedPointer(123); + QVERIFY(!q.isNull()); + QCOMPARE(q->i, 123); + QCOMPARE(CountedInteger::instanceCount, 1); + + p = std::move(q); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, 123); + QVERIFY(q.isNull()); + QCOMPARE(CountedInteger::instanceCount, 1); + } + + QCOMPARE(CountedInteger::instanceCount, 0); + + { + QScopedPointer<CountedInteger> p; + QVERIFY(p.isNull()); + QCOMPARE(CountedInteger::instanceCount, 0); + + p = returnScopedPointer(2001); + QVERIFY(!p.isNull()); + QCOMPARE(p->i, 2001); + QCOMPARE(CountedInteger::instanceCount, 1); + } + + QCOMPARE(CountedInteger::instanceCount, 0); +#endif +} QTEST_MAIN(tst_QScopedPointer) #include "tst_qscopedpointer.moc" diff --git a/tests/auto/corelib/tools/qtime/tst_qtime.cpp b/tests/auto/corelib/tools/qtime/tst_qtime.cpp index 97645ea7f6..675aeafc06 100644 --- a/tests/auto/corelib/tools/qtime/tst_qtime.cpp +++ b/tests/auto/corelib/tools/qtime/tst_qtime.cpp @@ -600,6 +600,59 @@ void tst_QTime::fromStringDateFormat_data() QTest::newRow("IsoDate - data2") << QString("19:03:54.998601") << Qt::ISODate << QTime(19, 3, 54, 999); QTest::newRow("IsoDate - data3") << QString("19:03:54.999601") << Qt::ISODate << QTime(19, 3, 54, 999); QTest::newRow("IsoDate - minute fraction midnight") << QString("24:00,0") << Qt::ISODate << QTime(0, 0, 0, 0); + + // Test Qt::RFC2822Date format (RFC 2822). + QTest::newRow("RFC 2822") << QString::fromLatin1("13 Feb 1987 13:24:51 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); + QTest::newRow("RFC 2822 with day") << QString::fromLatin1("Thu, 01 Jan 1970 00:12:34 +0000") + << Qt::RFC2822Date << QTime(0, 12, 34); + // No timezone + QTest::newRow("RFC 2822 no timezone") << QString::fromLatin1("01 Jan 1970 00:12:34") + << Qt::RFC2822Date << QTime(0, 12, 34); + // No time specified + QTest::newRow("RFC 2822 date only") << QString::fromLatin1("01 Nov 2002") + << Qt::RFC2822Date << invalidTime(); + QTest::newRow("RFC 2822 with day date only") << QString::fromLatin1("Fri, 01 Nov 2002") + << Qt::RFC2822Date << invalidTime(); + // Test invalid month, day, year + QTest::newRow("RFC 2822 invalid month name") << QString::fromLatin1("13 Fev 1987 13:24:51 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); + QTest::newRow("RFC 2822 invalid day") << QString::fromLatin1("36 Fev 1987 13:24:51 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); + QTest::newRow("RFC 2822 invalid year") << QString::fromLatin1("13 Fev 0000 13:24:51 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); + // Test invalid characters (should ignore invalid characters at end of string). + QTest::newRow("RFC 2822 invalid character at end") << QString::fromLatin1("01 Jan 2012 08:00:00 +0100!") + << Qt::RFC2822Date << QTime(8, 0, 0); + QTest::newRow("RFC 2822 invalid character at front") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000") + << Qt::RFC2822Date << invalidTime(); + QTest::newRow("RFC 2822 invalid character both ends") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000!") + << Qt::RFC2822Date << invalidTime(); + QTest::newRow("RFC 2822 invalid character at front, 2 at back") << QString::fromLatin1("!01 Jan 2012 08:00:00 +0000..") + << Qt::RFC2822Date << invalidTime(); + QTest::newRow("RFC 2822 invalid character 2 at front") << QString::fromLatin1("!!01 Jan 2012 08:00:00 +0000") + << Qt::RFC2822Date << invalidTime(); + + // Test Qt::RFC2822Date format (RFC 850 and 1036). + QTest::newRow("RFC 850 and 1036") << QString::fromLatin1("Fri Feb 13 13:24:51 1987 +0100") + << Qt::RFC2822Date << QTime(13, 24, 51); + // No timezone + QTest::newRow("RFC 850 and 1036 no timezone") << QString::fromLatin1("Thu Jan 01 00:12:34 1970") + << Qt::RFC2822Date << QTime(0, 12, 34); + // No time specified + QTest::newRow("RFC 850 and 1036 date only") << QString::fromLatin1("Fri Nov 01 2002") + << Qt::RFC2822Date << invalidTime(); + // Test invalid characters (should ignore invalid characters at end of string). + QTest::newRow("RFC 850 and 1036 invalid character at end") << QString::fromLatin1("Sun Jan 01 08:00:00 2012 +0100!") + << Qt::RFC2822Date << QTime(8, 0, 0); + QTest::newRow("RFC 850 and 1036 invalid character at front") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000") + << Qt::RFC2822Date << invalidTime(); + QTest::newRow("RFC 850 and 1036 invalid character both ends") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000!") + << Qt::RFC2822Date << invalidTime(); + QTest::newRow("RFC 850 and 1036 invalid character at front, 2 at back") << QString::fromLatin1("!Sun Jan 01 08:00:00 2012 +0000..") + << Qt::RFC2822Date << invalidTime(); + + QTest::newRow("RFC empty") << QString::fromLatin1("") << Qt::RFC2822Date << invalidTime(); } void tst_QTime::fromStringDateFormat() @@ -614,25 +667,28 @@ void tst_QTime::fromStringDateFormat() void tst_QTime::toStringDateFormat_data() { - // Since we can't define an element of Qt::DateFormat, str1 will be the string - // in TextDate format, and str2 will be the time in ISODate format. - - QTest::addColumn<QTime>("t"); - QTest::addColumn<QString>("str1"); - QTest::addColumn<QString>("str2"); - - QTest::newRow( "data0" ) << QTime(0,0,0,0) << QString("00:00:00") << QString("00:00:00"); - QTest::newRow( "data1" ) << QTime(10,12,34,0) << QString("10:12:34") << QString("10:12:34"); + QTest::addColumn<QTime>("time"); + QTest::addColumn<Qt::DateFormat>("format"); + QTest::addColumn<QString>("expected"); + + QTest::newRow("00:00:00.000") << QTime(0, 0, 0, 0) << Qt::TextDate << QString("00:00:00.000"); + QTest::newRow("ISO 00:00:00.000") << QTime(0, 0, 0, 0) << Qt::ISODate << QString("00:00:00.000"); + QTest::newRow("Text 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::TextDate << QString("10:12:34.000"); + QTest::newRow("ISO 10:12:34.000") << QTime(10, 12, 34, 0) << Qt::ISODate << QString("10:12:34.000"); + QTest::newRow("Text 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::TextDate << QString("10:12:34.001"); + QTest::newRow("ISO 10:12:34.001") << QTime(10, 12, 34, 001) << Qt::ISODate << QString("10:12:34.001"); + QTest::newRow("Text 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::TextDate << QString("10:12:34.999"); + QTest::newRow("ISO 10:12:34.999") << QTime(10, 12, 34, 999) << Qt::ISODate << QString("10:12:34.999"); + QTest::newRow("RFC2822Date") << QTime(10, 12, 34, 999) << Qt::RFC2822Date << QString("10:12:34"); } void tst_QTime::toStringDateFormat() { - QFETCH( QTime, t ); - QFETCH( QString, str1 ); - QFETCH( QString, str2 ); + QFETCH(QTime, time); + QFETCH(Qt::DateFormat, format); + QFETCH(QString, expected); - QCOMPARE( str1, t.toString( Qt::TextDate ) ); - QCOMPARE( str2, t.toString( Qt::ISODate ) ); + QCOMPARE(time.toString(format), expected); } void tst_QTime::toStringFormat_data() diff --git a/tests/auto/dbus/qdbusabstractinterface/interface.h b/tests/auto/dbus/qdbusabstractinterface/interface.h index 5db59b19eb..ecf732ce2d 100644 --- a/tests/auto/dbus/qdbusabstractinterface/interface.h +++ b/tests/auto/dbus/qdbusabstractinterface/interface.h @@ -43,6 +43,7 @@ #define INTERFACE_H #include <QtCore/QObject> +#include <QtCore/QHash> #include <QtDBus/QDBusArgument> struct RegisteredType @@ -103,7 +104,7 @@ public slots: Q_SCRIPTABLE void voidMethod() {} Q_SCRIPTABLE int sleepMethod(int); Q_SCRIPTABLE QString stringMethod() { return "Hello, world"; } - Q_SCRIPTABLE RegisteredType complexMethod() { return RegisteredType("Hello, world"); } + Q_SCRIPTABLE RegisteredType complexMethod(const QVariantHash &vars) { return RegisteredType(vars.value("arg1").toString()); } Q_SCRIPTABLE QString multiOutMethod(int &value) { value = 42; return "Hello, world"; } signals: diff --git a/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml index 845e7be5b4..ad61351cb2 100644 --- a/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml +++ b/tests/auto/dbus/qdbusabstractinterface/org.qtproject.QtDBus.Pinger.xml @@ -8,7 +8,7 @@ </property> <signal name="voidSignal"/> <signal name="stringSignal"> - <arg type="s"/> + <arg type="s" name="string-data"/> </signal> <signal name="complexSignal"> <arg name="" type="(s)"/> @@ -23,6 +23,8 @@ <arg type="s" direction="out"/> </method> <method name="complexMethod"> + <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QHash<QString,QVariant>"/> + <arg type='a{sv}' name='platform_data' direction='in'/> <arg type="(s)" direction="out"/> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RegisteredType"/> </method> diff --git a/tests/auto/dbus/qdbusabstractinterface/pinger.h b/tests/auto/dbus/qdbusabstractinterface/pinger.h deleted file mode 100644 index 6bed72c203..0000000000 --- a/tests/auto/dbus/qdbusabstractinterface/pinger.h +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtDBus module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - * This file was generated by qdbusxml2cpp version 0.7 - * Command line was: qdbusxml2cpp -i interface.h -p pinger org.qtproject.QtDBus.Pinger.xml - * - * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - * - * This is an auto-generated file. - * Do not edit! All changes made to it will be lost. - */ - -#ifndef PINGER_H_1246463415 -#define PINGER_H_1246463415 - -#include <QtCore/QObject> -#include <QtCore/QByteArray> -#include <QtCore/QList> -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVariant> -#include <QtDBus/QtDBus> -#include "interface.h" - -/* - * Proxy class for interface org.qtproject.QtDBus.Pinger - */ -class ComTrolltechQtDBusPingerInterface: public QDBusAbstractInterface -{ - Q_OBJECT -public: - static inline const char *staticInterfaceName() - { return "org.qtproject.QtDBus.Pinger"; } - -public: - ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); - - ~ComTrolltechQtDBusPingerInterface(); - - Q_PROPERTY(RegisteredType complexProp READ complexProp WRITE setComplexProp) - inline RegisteredType complexProp() const - { return qvariant_cast< RegisteredType >(property("complexProp")); } - inline void setComplexProp(RegisteredType value) - { setProperty("complexProp", QVariant::fromValue(value)); } - - Q_PROPERTY(QString stringProp READ stringProp WRITE setStringProp) - inline QString stringProp() const - { return qvariant_cast< QString >(property("stringProp")); } - inline void setStringProp(const QString &value) - { setProperty("stringProp", QVariant::fromValue(value)); } - - Q_PROPERTY(QDBusVariant variantProp READ variantProp WRITE setVariantProp) - inline QDBusVariant variantProp() const - { return qvariant_cast< QDBusVariant >(property("variantProp")); } - inline void setVariantProp(const QDBusVariant &value) - { setProperty("variantProp", QVariant::fromValue(value)); } - -public Q_SLOTS: // METHODS - inline QDBusPendingReply<RegisteredType> complexMethod() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("complexMethod"), argumentList); - } - - inline QDBusPendingReply<QString, int> multiOutMethod() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("multiOutMethod"), argumentList); - } - inline QDBusReply<QString> multiOutMethod(int &out1) - { - QList<QVariant> argumentList; - QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("multiOutMethod"), argumentList); - if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 2) { - out1 = qdbus_cast<int>(reply.arguments().at(1)); - } - return reply; - } - - inline QDBusPendingReply<int> sleepMethod(int in0) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(in0); - return asyncCallWithArgumentList(QLatin1String("sleepMethod"), argumentList); - } - - inline QDBusPendingReply<QString> stringMethod() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("stringMethod"), argumentList); - } - - inline QDBusPendingReply<> voidMethod() - { - QList<QVariant> argumentList; - return asyncCallWithArgumentList(QLatin1String("voidMethod"), argumentList); - } - -Q_SIGNALS: // SIGNALS - void complexSignal(RegisteredType in0); - void stringSignal(const QString &in0); - void voidSignal(); -}; - -namespace com { - namespace trolltech { - namespace QtDBus { - typedef ::ComTrolltechQtDBusPingerInterface Pinger; - } - } -} -#endif diff --git a/tests/auto/dbus/qdbusabstractinterface/test/test.pro b/tests/auto/dbus/qdbusabstractinterface/test/test.pro index 363d5fdf9c..66744b9252 100644 --- a/tests/auto/dbus/qdbusabstractinterface/test/test.pro +++ b/tests/auto/dbus/qdbusabstractinterface/test/test.pro @@ -2,13 +2,11 @@ CONFIG += testcase SOURCES += ../tst_qdbusabstractinterface.cpp ../interface.cpp HEADERS += ../interface.h -# These are generated sources -# To regenerate, see the command-line at the top of the files -SOURCES += ../pinger.cpp -HEADERS += ../pinger.h - TARGET = ../tst_qdbusabstractinterface QT = core testlib QT += dbus DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 + +DBUS_INTERFACES = ../org.qtproject.QtDBus.Pinger.xml +QDBUSXML2CPP_INTERFACE_HEADER_FLAGS += -i ../interface.h diff --git a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp index 5f3cf539e9..91e69fcdb7 100644 --- a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp +++ b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp @@ -47,13 +47,13 @@ #include <QtDBus> #include "interface.h" -#include "pinger.h" +#include "pinger_interface.h" static const char serviceName[] = "org.qtproject.autotests.qpinger"; static const char objectPath[] = "/org/qtproject/qpinger"; static const char *interfaceName = serviceName; -typedef QSharedPointer<com::trolltech::QtDBus::Pinger> Pinger; +typedef QSharedPointer<org::qtproject::QtDBus::Pinger> Pinger; class tst_QDBusAbstractInterface: public QObject { @@ -67,7 +67,7 @@ class tst_QDBusAbstractInterface: public QObject return Pinger(); if (service.isEmpty() && !service.isNull()) service = con.baseService(); - return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); + return Pinger(new org::qtproject::QtDBus::Pinger(service, path, con)); } Pinger getPingerPeer(const QString &path = "/", const QString &service = "") @@ -75,7 +75,7 @@ class tst_QDBusAbstractInterface: public QObject QDBusConnection con = QDBusConnection("peer"); if (!con.isConnected()) return Pinger(); - return Pinger(new com::trolltech::QtDBus::Pinger(service, path, con)); + return Pinger(new org::qtproject::QtDBus::Pinger(service, path, con)); } void resetServer() @@ -308,14 +308,22 @@ void tst_QDBusAbstractInterface::makeStringCall() QCOMPARE(r.value(), targetObj.stringMethod()); } +static QHash<QString, QVariant> complexMethodArgs() +{ + QHash<QString, QVariant> args; + args.insert("arg1", "Hello world"); + args.insert("arg2", 12345); + return args; +} + void tst_QDBusAbstractInterface::makeComplexCall() { Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); - QDBusReply<RegisteredType> r = p->complexMethod(); + QDBusReply<RegisteredType> r = p->complexMethod(complexMethodArgs()); QVERIFY(r.isValid()); - QCOMPARE(r.value(), targetObj.complexMethod()); + QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs())); } void tst_QDBusAbstractInterface::makeMultiOutCall() @@ -356,9 +364,9 @@ void tst_QDBusAbstractInterface::makeComplexCallPeer() Pinger p = getPingerPeer(); QVERIFY2(p, "Not connected to D-Bus"); - QDBusReply<RegisteredType> r = p->complexMethod(); + QDBusReply<RegisteredType> r = p->complexMethod(complexMethodArgs()); QVERIFY(r.isValid()); - QCOMPARE(r.value(), targetObj.complexMethod()); + QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs())); } void tst_QDBusAbstractInterface::makeMultiOutCallPeer() @@ -401,10 +409,10 @@ void tst_QDBusAbstractInterface::makeAsyncComplexCall() Pinger p = getPinger(); QVERIFY2(p, "Not connected to D-Bus"); - QDBusPendingReply<RegisteredType> r = p->complexMethod(); + QDBusPendingReply<RegisteredType> r = p->complexMethod(complexMethodArgs()); r.waitForFinished(); QVERIFY(r.isValid()); - QCOMPARE(r.value(), targetObj.complexMethod()); + QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs())); } void tst_QDBusAbstractInterface::makeAsyncMultiOutCall() @@ -449,10 +457,10 @@ void tst_QDBusAbstractInterface::makeAsyncComplexCallPeer() Pinger p = getPingerPeer(); QVERIFY2(p, "Not connected to D-Bus"); - QDBusPendingReply<RegisteredType> r = p->complexMethod(); + QDBusPendingReply<RegisteredType> r = p->complexMethod(complexMethodArgs()); r.waitForFinished(); QVERIFY(r.isValid()); - QCOMPARE(r.value(), targetObj.complexMethod()); + QCOMPARE(r.value(), targetObj.complexMethod(complexMethodArgs())); } void tst_QDBusAbstractInterface::makeAsyncMultiOutCallPeer() @@ -551,7 +559,7 @@ void tst_QDBusAbstractInterface::callWithTimeout() } // Now using generated code - com::trolltech::QtDBus::Pinger p(server_serviceName, server_objectPath, QDBusConnection::sessionBus()); + org::qtproject::QtDBus::Pinger p(server_serviceName, server_objectPath, QDBusConnection::sessionBus()); { // Call with no timeout QDBusReply<int> reply = p.sleepMethod(100); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 2cd5216c59..7fdb2f4cba 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -728,6 +728,24 @@ void tst_QImage::convertToFormat_data() << int(QImage::Format_RGB888) << 0xffffffffu; QTest::newRow("semiblack pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u << int(QImage::Format_RGB888) << 0xff000000u; + + QTest::newRow("red rgba8888 -> argb32") << int(QImage::Format_RGBA8888) << 0xffff0000 + << int(QImage::Format_ARGB32) << 0xffff0000; + QTest::newRow("green rgba8888 -> argb32") << int(QImage::Format_RGBA8888) << 0xff00ff00 + << int(QImage::Format_ARGB32) << 0xff00ff00; + QTest::newRow("blue rgba8888 -> argb32") << int(QImage::Format_RGBA8888) << 0xff0000ff + << int(QImage::Format_ARGB32) << 0xff0000ff; + + QTest::newRow("semired rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7fff0000u + << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u; + QTest::newRow("semigreen rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f00ff00u + << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u; + QTest::newRow("semiblue rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f0000ffu + << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu; + QTest::newRow("semiwhite rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7fffffffu + << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu; + QTest::newRow("semiblack rgba8888 -> argb pm") << int(QImage::Format_RGBA8888) << 0x7f000000u + << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u; } @@ -953,6 +971,10 @@ void tst_QImage::rotate_data() << QImage::Format_RGB888 << d; QTest::newRow(qPrintable(title.arg("Format_Indexed8"))) << QImage::Format_Indexed8 << d; + QTest::newRow(qPrintable(title.arg("Format_RGBX8888"))) + << QImage::Format_RGBX8888 << d; + QTest::newRow(qPrintable(title.arg("Format_RGBA8888_Premultiplied"))) + << QImage::Format_RGBA8888_Premultiplied << d; } } @@ -1161,6 +1183,21 @@ void tst_QImage::setPixel_data() << 0xff00ff00 << 0x00ff00u; QTest::newRow("RGB888 blue") << int(QImage::Format_RGB888) << 0xff0000ff << 0x0000ffu; +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + QTest::newRow("RGBA8888 red") << int(QImage::Format_RGBA8888) + << 0xffff0000u << 0xff0000ffu; + QTest::newRow("RGBA8888 green") << int(QImage::Format_RGBA8888) + << 0xff00ff00u << 0x00ff00ffu; + QTest::newRow("RGBA8888 blue") << int(QImage::Format_RGBA8888) + << 0xff0000ffu << 0x0000ffffu; +#else + QTest::newRow("RGBA8888 red") << int(QImage::Format_RGBA8888) + << 0xffff0000u << 0xff0000ffu; + QTest::newRow("RGBA8888 green") << int(QImage::Format_RGBA8888) + << 0xff00ff00u << 0xff00ff00u; + QTest::newRow("RGBA8888 blue") << int(QImage::Format_RGBA8888) + << 0xff0000ffu << 0xffff0000u; +#endif } void tst_QImage::setPixel() @@ -1184,6 +1221,9 @@ void tst_QImage::setPixel() case int(QImage::Format_RGB32): case int(QImage::Format_ARGB32): case int(QImage::Format_ARGB32_Premultiplied): + case int(QImage::Format_RGBX8888): + case int(QImage::Format_RGBA8888): + case int(QImage::Format_RGBA8888_Premultiplied): { for (int y = 0; y < h; ++y) { const quint32 *row = (const quint32*)(img.scanLine(y)); @@ -1901,6 +1941,8 @@ void tst_QImage::fillColor_data() "RGB888", "RGB444", "ARGB4444pm", + "RGBx8888", + "RGBA8888pm", 0 }; @@ -1917,7 +1959,9 @@ void tst_QImage::fillColor_data() QImage::Format_ARGB8555_Premultiplied, QImage::Format_RGB888, QImage::Format_RGB444, - QImage::Format_ARGB4444_Premultiplied + QImage::Format_ARGB4444_Premultiplied, + QImage::Format_RGBX8888, + QImage::Format_RGBA8888_Premultiplied, }; for (int i=0; names[i] != 0; ++i) { @@ -1935,6 +1979,7 @@ void tst_QImage::fillColor_data() QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << Qt::transparent << 0xff000000; QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << Qt::transparent << 0x00000000u; QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << Qt::transparent << 0x00000000u; + QTest::newRow("RGBA8888pm, transparent") << QImage::Format_RGBA8888_Premultiplied << Qt::transparent << 0x00000000u; } void tst_QImage::fillColor() @@ -2013,6 +2058,8 @@ void tst_QImage::rgbSwapped_data() QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied; QTest::newRow("Format_RGB888") << QImage::Format_RGB888; QTest::newRow("Format_RGB444") << QImage::Format_RGB444; + QTest::newRow("Format_RGBX8888") << QImage::Format_RGBX8888; + QTest::newRow("Format_RGBA8888_Premultiplied") << QImage::Format_RGBA8888_Premultiplied; } void tst_QImage::rgbSwapped() diff --git a/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro b/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro index c3113ed4b1..211be4c1c0 100644 --- a/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro +++ b/tests/auto/gui/kernel/qbackingstore/qbackingstore.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qbackingstore QT += core-private gui-private testlib diff --git a/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro b/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro index ff491c1e25..015cc782eb 100644 --- a/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro +++ b/tests/auto/gui/kernel/qinputmethod/qinputmethod.pro @@ -1,5 +1,4 @@ CONFIG += testcase -CONFIG += parallel_test TARGET = tst_qinputmethod SOURCES += tst_qinputmethod.cpp QT += core-private gui-private testlib diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 6fe7961545..1b1f5575b1 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -61,6 +61,8 @@ private slots: void name_data(); void name(); + void namehex_data(); + void namehex(); void setNamedColor(); void constructNamedColorWithSpace(); @@ -254,36 +256,75 @@ void tst_QColor::isValid() QVERIFY(color.isValid() == isValid); } +Q_DECLARE_METATYPE(QColor::NameFormat); + void tst_QColor::name_data() { QTest::addColumn<QColor>("color"); QTest::addColumn<QString>("name"); - - QTest::newRow("invalid") << QColor() << "#000000"; - QTest::newRow("global color black") << QColor(Qt::black) << "#000000"; - QTest::newRow("global color white") << QColor(Qt::white) << "#ffffff"; - QTest::newRow("global color darkGray") << QColor(Qt::darkGray) << "#808080"; - QTest::newRow("global color gray") << QColor(Qt::gray) << "#a0a0a4"; - QTest::newRow("global color lightGray") << QColor(Qt::lightGray) << "#c0c0c0"; - QTest::newRow("global color red") << QColor(Qt::red) << "#ff0000"; - QTest::newRow("global color green") << QColor(Qt::green) << "#00ff00"; - QTest::newRow("global color blue") << QColor(Qt::blue) << "#0000ff"; - QTest::newRow("global color cyan") << QColor(Qt::cyan) << "#00ffff"; - QTest::newRow("global color magenta") << QColor(Qt::magenta) << "#ff00ff"; - QTest::newRow("global color yellow") << QColor(Qt::yellow) << "#ffff00"; - QTest::newRow("global color darkRed") << QColor(Qt::darkRed) << "#800000"; - QTest::newRow("global color darkGreen") << QColor(Qt::darkGreen) << "#008000"; - QTest::newRow("global color darkBlue") << QColor(Qt::darkBlue) << "#000080"; - QTest::newRow("global color darkCyan") << QColor(Qt::darkCyan) << "#008080"; - QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << "#800080"; - QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << "#808000"; + QTest::addColumn<QColor::NameFormat>("nameFormat"); + + QTest::newRow("invalid") << QColor() << "#000000" << QColor::HexRgb; + QTest::newRow("global color black") << QColor(Qt::black) << "#000000" << QColor::HexRgb; + QTest::newRow("global color white") << QColor(Qt::white) << "#ffffff" << QColor::HexRgb; + QTest::newRow("global color darkGray") << QColor(Qt::darkGray) << "#808080" << QColor::HexRgb; + QTest::newRow("global color gray") << QColor(Qt::gray) << "#a0a0a4" << QColor::HexRgb; + QTest::newRow("global color lightGray") << QColor(Qt::lightGray) << "#c0c0c0" << QColor::HexRgb; + QTest::newRow("global color red") << QColor(Qt::red) << "#ff0000" << QColor::HexRgb; + QTest::newRow("global color green") << QColor(Qt::green) << "#00ff00" << QColor::HexRgb; + QTest::newRow("global color blue") << QColor(Qt::blue) << "#0000ff" << QColor::HexRgb; + QTest::newRow("global color cyan") << QColor(Qt::cyan) << "#00ffff" << QColor::HexRgb; + QTest::newRow("global color magenta") << QColor(Qt::magenta) << "#ff00ff" << QColor::HexRgb; + QTest::newRow("global color yellow") << QColor(Qt::yellow) << "#ffff00" << QColor::HexRgb; + QTest::newRow("global color darkRed") << QColor(Qt::darkRed) << "#800000" << QColor::HexRgb; + QTest::newRow("global color darkGreen") << QColor(Qt::darkGreen) << "#008000" << QColor::HexRgb; + QTest::newRow("global color darkBlue") << QColor(Qt::darkBlue) << "#000080" << QColor::HexRgb; + QTest::newRow("global color darkCyan") << QColor(Qt::darkCyan) << "#008080" << QColor::HexRgb; + QTest::newRow("global color darkMagenta") << QColor(Qt::darkMagenta) << "#800080" << QColor::HexRgb; + QTest::newRow("global color darkYellow") << QColor(Qt::darkYellow) << "#808000" << QColor::HexRgb; + QTest::newRow("transparent red") << QColor(255, 0, 0, 102) << "#66ff0000" << QColor::HexArgb; } void tst_QColor::name() { QFETCH(QColor, color); QFETCH(QString, name); - QCOMPARE(color.name(), name); + QFETCH(QColor::NameFormat, nameFormat); + QCOMPARE(color.name(nameFormat), name); +} + +void tst_QColor::namehex_data() +{ + QTest::addColumn<QString>("hexcolor"); + QTest::addColumn<QColor>("color"); + + QTest::newRow("global color black") << "#000000" << QColor(Qt::black); + QTest::newRow("global color white") << "#ffffff" << QColor(Qt::white); + QTest::newRow("global color darkGray") << "#808080" << QColor(Qt::darkGray); + QTest::newRow("global color gray") << "#a0a0a4" << QColor(Qt::gray); + QTest::newRow("global color lightGray") << "#c0c0c0" << QColor(Qt::lightGray); + QTest::newRow("global color red") << "#ff0000" << QColor(Qt::red); + QTest::newRow("global color green") << "#00ff00" << QColor(Qt::green); + QTest::newRow("global color blue") << "#0000ff" << QColor(Qt::blue); + QTest::newRow("global color cyan") << "#00ffff" << QColor(Qt::cyan); + QTest::newRow("global color magenta") << "#ff00ff" << QColor(Qt::magenta); + QTest::newRow("global color yellow") << "#ffff00" << QColor(Qt::yellow); + QTest::newRow("global color darkRed") << "#800000" << QColor(Qt::darkRed); + QTest::newRow("global color darkGreen") << "#008000" << QColor(Qt::darkGreen); + QTest::newRow("global color darkBlue") << "#000080" << QColor(Qt::darkBlue); + QTest::newRow("global color darkCyan") << "#008080" << QColor(Qt::darkCyan); + QTest::newRow("global color darkMagenta") << "#800080" << QColor(Qt::darkMagenta); + QTest::newRow("global color darkYellow") << "#808000" << QColor(Qt::darkYellow); + QTest::newRow("transparent red") << "#66ff0000" << QColor(255, 0, 0, 102); + QTest::newRow("invalid red") << "#gg0000" << QColor(); + QTest::newRow("invalid transparent") << "#gg00ff00" << QColor(); +} + +void tst_QColor::namehex() +{ + QFETCH(QString, hexcolor); + QFETCH(QColor, color); + QCOMPARE(QColor(hexcolor), color); } void tst_QColor::globalColors_data() diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 4f1213dff9..5a1ca855a1 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -122,10 +122,15 @@ private slots: void drawRect(); void drawRect2(); + void fillRect_data(); void fillRect(); + void fillRect2_data(); void fillRect2(); + void fillRect3_data() { fillRect2_data(); } void fillRect3(); + void fillRect4_data() { fillRect2_data(); } void fillRect4(); + void fillRectNonPremul(); void drawEllipse_data(); void drawEllipse(); @@ -1079,9 +1084,19 @@ void tst_QPainter::drawRect2() } } +void tst_QPainter::fillRect_data() +{ + QTest::addColumn<QImage::Format>("format"); + + QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied; +} + void tst_QPainter::fillRect() { - QImage image(100, 100, QImage::Format_ARGB32_Premultiplied); + QFETCH(QImage::Format, format); + + QImage image(100, 100, format); image.fill(QColor(0, 0, 0, 0).rgba()); QPainter p(&image); @@ -1103,17 +1118,29 @@ void tst_QPainter::fillRect() QRect(0, 0, 50, 100)); } +void tst_QPainter::fillRect2_data() +{ + QTest::addColumn<QImage::Format>("format"); + + QTest::newRow("argb32") << QImage::Format_ARGB32; + QTest::newRow("argb32pm") << QImage::Format_ARGB32_Premultiplied; + QTest::newRow("rgba8888") << QImage::Format_RGBA8888; + QTest::newRow("rgba8888pm") << QImage::Format_RGBA8888_Premultiplied; +} + void tst_QPainter::fillRect2() { + QFETCH(QImage::Format, format); + QRgb background = 0x0; - QImage img(1, 20, QImage::Format_ARGB32_Premultiplied); + QImage img(1, 20, format); img.fill(background); QPainter p(&img); QRectF rect(0, 1, 1.2, 18); - p.fillRect(rect, Qt::black); + p.fillRect(rect, Qt::yellow); p.end(); @@ -1122,11 +1149,14 @@ void tst_QPainter::fillRect2() QCOMPARE(img.pixel(0, 1), img.pixel(0, 2)); QCOMPARE(img.pixel(0, img.height() - 2), img.pixel(0, img.height() - 3)); + QCOMPARE(img.pixel(0, 1), QColor(Qt::yellow).rgba()); } void tst_QPainter::fillRect3() { - QImage img(1, 1, QImage::Format_ARGB32_Premultiplied); + QFETCH(QImage::Format, format); + + QImage img(1, 1, format); img.fill(QColor(Qt::black).rgba()); QPainter p(&img); @@ -1139,7 +1169,9 @@ void tst_QPainter::fillRect3() void tst_QPainter::fillRect4() { - QImage image(100, 1, QImage::Format_ARGB32_Premultiplied); + QFETCH(QImage::Format, format); + + QImage image(100, 1, format); image.fill(0x0); QImage expected = image; @@ -1157,6 +1189,24 @@ void tst_QPainter::fillRect4() QCOMPARE(image, expected); } +void tst_QPainter::fillRectNonPremul() +{ + QImage img1(1, 1, QImage::Format_ARGB32); + QImage img2(1, 1, QImage::Format_RGBA8888); + + QPainter p1(&img1); + QPainter p2(&img2); + + QRectF rect(0, 0, 1, 1); + p1.fillRect(rect, qRgba(31, 63, 127, 127)); + p2.fillRect(rect, qRgba(31, 63, 127, 127)); + + p1.end(); + p2.end(); + + QCOMPARE(img1.pixel(0, 0), img2.pixel(0,0)); +} + void tst_QPainter::drawPath_data() { QTest::addColumn<QPainterPath>("path"); @@ -2265,6 +2315,27 @@ void tst_QPainter::setOpacity_data() QTest::newRow("RGB444 on RGB444") << QImage::Format_RGB444 << QImage::Format_RGB444; + + QTest::newRow("RGBA8888P on RGBA8888P") << QImage::Format_RGBA8888_Premultiplied + << QImage::Format_RGBA8888_Premultiplied; + + QTest::newRow("RGBA8888 on RGBA8888") << QImage::Format_RGBA8888 + << QImage::Format_RGBA8888; + + QTest::newRow("RGBx8888 on RGBx8888") << QImage::Format_RGBX8888 + << QImage::Format_RGBX8888; + + QTest::newRow("RGBA8888P on ARGB32P") << QImage::Format_RGBA8888_Premultiplied + << QImage::Format_ARGB32_Premultiplied; + + QTest::newRow("RGBx8888 on ARGB32P") << QImage::Format_RGBX8888 + << QImage::Format_ARGB32_Premultiplied; + + QTest::newRow("ARGB32P on RGBA8888P") << QImage::Format_ARGB32_Premultiplied + << QImage::Format_RGBA8888_Premultiplied; + + QTest::newRow("RGB32 on RGBx8888") << QImage::Format_RGB32 + << QImage::Format_RGBX8888; } void tst_QPainter::setOpacity() diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index ca6c42c9bd..86e282fad2 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -344,8 +344,6 @@ void tst_QCssParser::term_data() val.variant = QVariant(QColor("#ffbb00")); QTest::newRow("hexcolor2") << true << "#fb0" << val; - QTest::newRow("hexcolor_failure") << false << "#cafebabe" << val; - val.type = QCss::Value::Uri; val.variant = QString("www.kde.org"); QTest::newRow("uri1") << true << "url(\"www.kde.org\")" << val; @@ -367,9 +365,6 @@ void tst_QCssParser::term() QFETCH(QString, css); QFETCH(QCss::Value, expectedValue); - if (strcmp(QTest::currentDataTag(), "hexcolor_failure") == 0) - QTest::ignoreMessage(QtWarningMsg, "QCssParser::parseHexColor: Unknown color name '#cafebabe'"); - QCss::Parser parser(css); QCss::Value val; QVERIFY(parser.testTerm()); diff --git a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro index 37868dcfde..6975c4088b 100644 --- a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro +++ b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro @@ -2,8 +2,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qfontdatabase SOURCES += tst_qfontdatabase.cpp -QT += testlib -!mac: QT += core-private gui-private +QT += testlib core-private gui-private wince* { additionalFiles.files = FreeMono.ttf diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index 9cf4082287..104d3465f2 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -44,6 +44,7 @@ #include <qfontdatabase.h> #include <qfontinfo.h> #include <qfontmetrics.h> +#include <qpa/qplatformfontdatabase.h> class tst_QFontDatabase : public QObject { @@ -252,11 +253,8 @@ void tst_QFontDatabase::addAppFont() return; #endif QCOMPARE(fontDbChangedSpy.count(), 1); -// addApplicationFont is supported on Mac, don't skip the test if it breaks. -#ifndef Q_OS_MAC if (id == -1) QSKIP("Skip the test since app fonts are not supported on this system"); -#endif const QStringList addedFamilies = QFontDatabase::applicationFontFamilies(id); QVERIFY(!addedFamilies.isEmpty()); @@ -271,16 +269,9 @@ void tst_QFontDatabase::addAppFont() QVERIFY(QFontDatabase::removeApplicationFont(id)); QCOMPARE(fontDbChangedSpy.count(), 2); -#ifdef Q_OS_MAC - QEXPECT_FAIL("font file", "QTBUG-23062", Continue); -#endif QCOMPARE(db.families(), oldFamilies); } -QT_BEGIN_NAMESPACE -Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias); -QT_END_NAMESPACE - void tst_QFontDatabase::aliases() { QFontDatabase db; @@ -290,7 +281,7 @@ void tst_QFontDatabase::aliases() QVERIFY(db.hasFamily(firstFont)); const QString alias = QStringLiteral("AliasToFirstFont") + firstFont; QVERIFY(!db.hasFamily(alias)); - qt_registerAliasToFontFamily(firstFont, alias); + QPlatformFontDatabase::registerAliasToFontFamily(firstFont, alias); QVERIFY(db.hasFamily(alias)); } diff --git a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp index 25301feee4..125eab2f8c 100644 --- a/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp +++ b/tests/auto/network/access/qnetworkaccessmanager/tst_qnetworkaccessmanager.cpp @@ -77,30 +77,43 @@ void tst_QNetworkAccessManager::networkAccessible() QSignalSpy spy(&manager, SIGNAL(networkAccessibleChanged(QNetworkAccessManager::NetworkAccessibility))); - QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::UnknownAccessibility); + // if there is no session, we cannot know in which state we are in + QNetworkAccessManager::NetworkAccessibility initialAccessibility = + manager.networkAccessible(); + QCOMPARE(manager.networkAccessible(), initialAccessibility); manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible); - QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(), - QNetworkAccessManager::NotAccessible); + int expectedCount = (initialAccessibility == QNetworkAccessManager::Accessible) ? 1 : 0; + QCOMPARE(spy.count(), expectedCount); + if (expectedCount > 0) + QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(), + QNetworkAccessManager::NotAccessible); QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::NotAccessible); manager.setNetworkAccessible(QNetworkAccessManager::Accessible); - QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(), - QNetworkAccessManager::UnknownAccessibility); - QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::UnknownAccessibility); + QCOMPARE(spy.count(), expectedCount); + if (expectedCount > 0) + QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(), + initialAccessibility); + QCOMPARE(manager.networkAccessible(), initialAccessibility); QNetworkConfigurationManager configManager; + bool sessionRequired = (configManager.capabilities() + & QNetworkConfigurationManager::NetworkSessionRequired); QNetworkConfiguration defaultConfig = configManager.defaultConfiguration(); if (defaultConfig.isValid()) { manager.setConfiguration(defaultConfig); - QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(), - QNetworkAccessManager::Accessible); + // the accessibility has not changed if no session is required + if (sessionRequired) { + QCOMPARE(spy.count(), 1); + QCOMPARE(spy.takeFirst().at(0).value<QNetworkAccessManager::NetworkAccessibility>(), + QNetworkAccessManager::Accessible); + } else { + QCOMPARE(spy.count(), 0); + } QCOMPARE(manager.networkAccessible(), QNetworkAccessManager::Accessible); manager.setNetworkAccessible(QNetworkAccessManager::NotAccessible); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index ce8293edbc..eb9ad81101 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -368,6 +368,8 @@ private Q_SLOTS: #ifdef QT_BUILD_INTERNAL void sslSessionSharing_data(); void sslSessionSharing(); + void sslSessionSharingFromPersistentSession_data(); + void sslSessionSharingFromPersistentSession(); #endif #endif @@ -5964,7 +5966,7 @@ void tst_QNetworkReply::sslSessionSharing() warmupRequest.setAttribute(QNetworkRequest::User, sessionSharingEnabled); // so we can read it from the slot if (! sessionSharingEnabled) { QSslConfiguration configuration(QSslConfiguration::defaultConfiguration()); - configuration.setSslOption(QSsl::SslOptionDisableSessionTickets, true); + configuration.setSslOption(QSsl::SslOptionDisableSessionSharing, true); warmupRequest.setSslConfiguration(configuration); } QNetworkReply *reply = manager.get(warmupRequest); @@ -6010,6 +6012,63 @@ void tst_QNetworkReply::sslSessionSharingHelperSlot() } } +void tst_QNetworkReply::sslSessionSharingFromPersistentSession_data() +{ + QTest::addColumn<bool>("sessionPersistenceEnabled"); + QTest::newRow("enabled") << true; + QTest::newRow("disabled") << false; +} + +void tst_QNetworkReply::sslSessionSharingFromPersistentSession() +{ + QString urlString("https://" + QtNetworkSettings::serverName()); + + // warm up SSL session cache to get a working session + QNetworkRequest warmupRequest(urlString); + QFETCH(bool, sessionPersistenceEnabled); + if (sessionPersistenceEnabled) { + QSslConfiguration warmupConfiguration(QSslConfiguration::defaultConfiguration()); + warmupConfiguration.setSslOption(QSsl::SslOptionDisableSessionPersistence, false); + warmupRequest.setSslConfiguration(warmupConfiguration); + } + QNetworkReply *warmupReply = manager.get(warmupRequest); + warmupReply->ignoreSslErrors(); + connect(warmupReply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(20); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(warmupReply->error(), QNetworkReply::NoError); + QByteArray sslSession = warmupReply->sslConfiguration().session(); + QCOMPARE(!sslSession.isEmpty(), sessionPersistenceEnabled); + + // test server sends a life time hint of 0, which is not common + // practice; however it is good enough because the default is -1 + int expectedSessionTicketLifeTimeHint = sessionPersistenceEnabled ? 0 : -1; + QCOMPARE(warmupReply->sslConfiguration().sessionTicketLifeTimeHint(), + expectedSessionTicketLifeTimeHint); + + warmupReply->deleteLater(); + + // now send another request with a new QNAM and the persisted session, + // to verify it can be resumed without any internal state + QNetworkRequest request(warmupRequest); + if (sessionPersistenceEnabled) { + QSslConfiguration configuration = request.sslConfiguration(); + configuration.setSession(sslSession); + request.setSslConfiguration(configuration); + } + QNetworkAccessManager newManager; + QNetworkReply *reply = newManager.get(request); + reply->ignoreSslErrors(); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(20); + QVERIFY(!QTestEventLoop::instance().timeout()); + QCOMPARE(reply->error(), QNetworkReply::NoError); + + bool sslSessionSharingWasUsedInReply = QSslConfigurationPrivate::peerSessionWasShared( + reply->sslConfiguration()); + QCOMPARE(sessionPersistenceEnabled, sslSessionSharingWasUsedInReply); +} + #endif // QT_BUILD_INTERNAL #endif // QT_NO_SSL diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp index 40f22d6d1e..f474f97f5d 100644 --- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp +++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp @@ -56,6 +56,10 @@ #include <sys/socket.h> #endif +#ifdef Q_OS_VXWORKS +#include <sockLib.h> +#endif + #include <stddef.h> #define PLATFORMSOCKETENGINE QNativeSocketEngine diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 2b9dfc5081..ee5c7e42d8 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -513,7 +513,7 @@ void tst_QTcpSocket::bind() { QFETCH_GLOBAL(bool, setProxy); if (setProxy) - QSKIP("QTBUG-22964"); + return; // QTBUG-22964 for proxies, QTBUG-29972 for QSKIP QFETCH(QString, stringAddr); QFETCH(bool, successExpected); QFETCH(QString, stringExpectedLocalAddress); diff --git a/tests/auto/other/exceptionsafety/.gitignore b/tests/auto/other/exceptionsafety/.gitignore deleted file mode 100644 index 9a854c4c26..0000000000 --- a/tests/auto/other/exceptionsafety/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_exceptionsafety diff --git a/tests/auto/other/exceptionsafety/exceptionsafety.pro b/tests/auto/other/exceptionsafety/exceptionsafety.pro deleted file mode 100644 index 3e9c996cd8..0000000000 --- a/tests/auto/other/exceptionsafety/exceptionsafety.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += testcase -TARGET = tst_exceptionsafety -SOURCES += tst_exceptionsafety.cpp -QT = core testlib -CONFIG += parallel_test insignificant_test -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp b/tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp deleted file mode 100644 index 94360adb0e..0000000000 --- a/tests/auto/other/exceptionsafety/tst_exceptionsafety.cpp +++ /dev/null @@ -1,846 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qplatformdefs.h" -#include <stdlib.h> - -void* internalMalloc(size_t bytes); -#define malloc internalMalloc -#include <QVarLengthArray> -#undef malloc - -#include <QtTest/QtTest> - -QT_USE_NAMESPACE - -class tst_ExceptionSafety: public QObject -{ - Q_OBJECT -private slots: -#ifdef QT_NO_EXCEPTIONS - void initTestCase(); -#else - void exceptionInSlot(); - void exceptionVector(); - void exceptionHash(); - void exceptionMap(); - void exceptionList(); - void exceptionLinkedList(); -// void exceptionEventLoop(); -// void exceptionSignalSlot(); - void exceptionOOMQVarLengthArray(); -#endif -}; - -#ifdef QT_NO_EXCEPTIONS -void tst_ExceptionSafety::initTestCase() -{ - QSKIP("This test requires exception support"); -} - -#else - -class Emitter : public QObject -{ - Q_OBJECT -public: - inline void emitTestSignal() { emit testSignal(); } -signals: - void testSignal(); -}; - -class ExceptionThrower : public QObject -{ - Q_OBJECT -public slots: - void thrower() { throw 5; } -}; - -class Receiver : public QObject -{ - Q_OBJECT -public: - Receiver() - : received(0) {} - int received; - -public slots: - void receiver() { ++received; } -}; - -enum ThrowType { ThrowNot = 0, ThrowAtCreate = 1, ThrowAtCopy = 2, ThrowLater = 3, ThrowAtComparison = 4 }; - -ThrowType throwType = ThrowNot; // global flag to indicate when an exception should be throw. Will be reset when the exception has been generated. - -int objCounter = 0; - -/*! Class that does not throw any exceptions. Used as baseclass for all the other ones. - */ -template <int T> -class FlexibleThrower -{ - public: - FlexibleThrower() : _value(-1) { - if( throwType == ThrowAtCreate ) { - throwType = ThrowNot; - throw ThrowAtCreate; - } - objCounter++; - } - - FlexibleThrower( short value ) : _value(value) { - if( throwType == ThrowAtCreate ) { - throwType = ThrowNot; - throw ThrowAtCreate; - } - objCounter++; - } - - FlexibleThrower(FlexibleThrower const& other ) { - // qDebug("cc"); - - if( throwType == ThrowAtCopy ) { - throwType = ThrowNot; - throw ThrowAtCopy; - - } else if( throwType == ThrowLater ) { - throwType = ThrowAtCopy; - } - - objCounter++; - _value = other.value(); - } - - ~FlexibleThrower() { objCounter--; } - - bool operator==(const FlexibleThrower<T> &t) const - { - // qDebug("vv == %d %d", value(), t.value()); - if( throwType == ThrowAtComparison ) { - throwType = ThrowNot; - throw ThrowAtComparison; - } - return value()==t.value(); - } - - bool operator<(const FlexibleThrower<T> &t) const - { - // qDebug("vv < %d %d", value(), t.value()); - if( throwType == ThrowAtComparison ) { - throwType = ThrowNot; - throw ThrowAtComparison; - } - return value()<t.value(); - } - - int value() const - { return (int)_value; } - - short _value; - char dummy[T]; -}; - -uint qHash(const FlexibleThrower<2>& t) -{ - // qDebug("ha"); - if( throwType == ThrowAtComparison ) { - throwType = ThrowNot; - throw ThrowAtComparison; - } - return (uint)t.value(); -} - -typedef FlexibleThrower<2> FlexibleThrowerSmall; -typedef QMap<FlexibleThrowerSmall,FlexibleThrowerSmall> MyMap; -typedef QHash<FlexibleThrowerSmall,FlexibleThrowerSmall> MyHash; - -// connect a signal to a slot that throws an exception -// run this through valgrind to make sure it doesn't corrupt -void tst_ExceptionSafety::exceptionInSlot() -{ - Emitter emitter; - ExceptionThrower thrower; - - connect(&emitter, SIGNAL(testSignal()), &thrower, SLOT(thrower())); - - try { - emitter.emitTestSignal(); - } catch (int i) { - QCOMPARE(i, 5); - } -} - -void tst_ExceptionSafety::exceptionList() -{ - const int intancesCount = objCounter; - { - int instances; - QList<FlexibleThrowerSmall> list; - QList<FlexibleThrowerSmall> list2; - QList<FlexibleThrowerSmall> list3; - - for( int i = 0; i<10; i++ ) - list.append( FlexibleThrowerSmall(i) ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list.append( FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list.prepend( FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(0).value(), 0 ); - QCOMPARE( list.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list.insert( 8, FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(7).value(), 7 ); - QCOMPARE( list.at(8).value(), 8 ); - QCOMPARE( list.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - FlexibleThrowerSmall t = list.takeAt( 6 ); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(6).value(), 6 ); - QCOMPARE( list.at(7).value(), 7 ); - QCOMPARE( list.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list3 = list; - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(0).value(), 0 ); - QCOMPARE( list.at(7).value(), 7 ); - QCOMPARE( list.size(), 10 ); - QCOMPARE( list3.at(0).value(), 0 ); - QCOMPARE( list3.at(7).value(), 7 ); - QCOMPARE( list3.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list3.append( FlexibleThrowerSmall(11) ); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(0).value(), 0 ); - QCOMPARE( list.at(7).value(), 7 ); - QCOMPARE( list.size(), 10 ); - QCOMPARE( list3.at(0).value(), 0 ); - QCOMPARE( list3.at(7).value(), 7 ); - QCOMPARE( list3.size(), 10 ); - - try { - list2.clear(); - list2.append( FlexibleThrowerSmall(11)); - throwType = ThrowAtCopy; - instances = objCounter; - list3 = list+list2; - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(0).value(), 0 ); - QCOMPARE( list.at(7).value(), 7 ); - QCOMPARE( list.size(), 10 ); - - // check that copy on write works atomar - list2.clear(); - list2.append( FlexibleThrowerSmall(11)); - list3 = list+list2; - instances = objCounter; - try { - throwType = ThrowAtCreate; - list3[7]=FlexibleThrowerSmall(12); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.at(7).value(), 7 ); - QCOMPARE( list.size(), 10 ); - QCOMPARE( list3.at(7).value(), 7 ); - QCOMPARE( list3.size(), 11 ); - - } - QCOMPARE(objCounter, intancesCount); // check that every object has been freed -} - -void tst_ExceptionSafety::exceptionLinkedList() -{ - const int intancesCount = objCounter; - { - int instances; - QLinkedList<FlexibleThrowerSmall> list; - QLinkedList<FlexibleThrowerSmall> list2; - QLinkedList<FlexibleThrowerSmall> list3; - - for( int i = 0; i<10; i++ ) - list.append( FlexibleThrowerSmall(i) ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list.append( FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list.prepend( FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.first().value(), 0 ); - QCOMPARE( list.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - list3 = list; - list3.append( FlexibleThrowerSmall(11) ); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( list.first().value(), 0 ); - QCOMPARE( list.size(), 10 ); - QCOMPARE( list3.size(), 10 ); - } - QCOMPARE(objCounter, intancesCount); // check that every object has been freed -} - -void tst_ExceptionSafety::exceptionVector() -{ - const int intancesCount = objCounter; - { - int instances; - QVector<FlexibleThrowerSmall> vector; - QVector<FlexibleThrowerSmall> vector2; - QVector<FlexibleThrowerSmall> vector3; - - for (int i = 0; i<10; i++) - vector.append( FlexibleThrowerSmall(i) ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - vector.append( FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - vector.prepend( FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(0).value(), 0 ); - QCOMPARE( vector.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - vector.insert( 8, FlexibleThrowerSmall(10)); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.at(8).value(), 8 ); - QCOMPARE( vector.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - vector3 = vector; - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(0).value(), 0 ); - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.size(), 10 ); - QCOMPARE( vector3.at(0).value(), 0 ); - QCOMPARE( vector3.at(7).value(), 7 ); - QCOMPARE( vector3.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCopy; - vector3.append( FlexibleThrowerSmall(11) ); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(0).value(), 0 ); - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.size(), 10 ); - QCOMPARE( vector3.at(0).value(), 0 ); - QCOMPARE( vector3.at(7).value(), 7 ); - - try { - vector2.clear(); - vector2.append( FlexibleThrowerSmall(11)); - instances = objCounter; - throwType = ThrowAtCopy; - vector3 = vector+vector2; - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(0).value(), 0 ); - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.size(), 10 ); - - // check that copy on write works atomar - vector2.clear(); - vector2.append( FlexibleThrowerSmall(11)); - vector3 = vector+vector2; - instances = objCounter; - try { - throwType = ThrowAtCreate; - vector3[7]=FlexibleThrowerSmall(12); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.size(), 10 ); - QCOMPARE( vector3.at(7).value(), 7 ); - QCOMPARE( vector3.size(), 11 ); - - instances = objCounter; - try { - throwType = ThrowAtCreate; - vector.resize(15); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowAtCreate; - vector.resize(15); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(7).value(), 7 ); - QCOMPARE( vector.size(), 10 ); - - instances = objCounter; - try { - throwType = ThrowLater; - vector.fill(FlexibleThrowerSmall(1), 15); - } catch (...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( vector.at(0).value(), 0 ); - QCOMPARE( vector.size(), 10 ); - } - QCOMPARE(objCounter, intancesCount); // check that every object has been freed -} - - -void tst_ExceptionSafety::exceptionMap() -{ - const int intancesCount = objCounter; - { - int instances; - MyMap map; - MyMap map2; - MyMap map3; - - throwType = ThrowNot; - for (int i = 0; i<10; i++) - map[ FlexibleThrowerSmall(i) ] = FlexibleThrowerSmall(i); - - return; // further test are deactivated until Map is fixed. - - for( int i = ThrowAtCopy; i<=ThrowAtComparison; i++ ) { - instances = objCounter; - try { - throwType = (ThrowType)i; - map[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10); - } catch(...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( map.size(), 10 ); - QCOMPARE( map[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) ); - } - - map2 = map; - instances = objCounter; - try { - throwType = ThrowLater; - map2[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10); - } catch(...) { - QCOMPARE(instances, objCounter); - } - /* qDebug("%d %d", map.size(), map2.size() ); - for( int i=0; i<map.size(); i++ ) - qDebug( "Value at %d: %d",i, map.value(FlexibleThrowerSmall(i), FlexibleThrowerSmall()).value() ); - QCOMPARE( map.value(FlexibleThrowerSmall(1), FlexibleThrowerSmall()), FlexibleThrowerSmall(1) ); - qDebug( "Value at %d: %d",1, map[FlexibleThrowerSmall(1)].value() ); - qDebug("%d %d", map.size(), map2.size() ); - */ - QCOMPARE( map[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) ); - QCOMPARE( map.size(), 10 ); - QCOMPARE( map2[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) ); - QCOMPARE( map2.size(), 10 ); - - } - QCOMPARE(objCounter, intancesCount); // check that every object has been freed -} - -void tst_ExceptionSafety::exceptionHash() -{ - const int intancesCount = objCounter; - { - int instances; - MyHash hash; - MyHash hash2; - MyHash hash3; - - for( int i = 0; i<10; i++ ) - hash[ FlexibleThrowerSmall(i) ] = FlexibleThrowerSmall(i); - - for( int i = ThrowAtCopy; i<=ThrowAtComparison; i++ ) { - instances = objCounter; - try { - throwType = (ThrowType)i; - hash[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10); - } catch(...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( hash.size(), 10 ); - } - - hash2 = hash; - instances = objCounter; - try { - throwType = ThrowLater; - hash2[ FlexibleThrowerSmall(10) ] = FlexibleThrowerSmall(10); - } catch(...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( hash[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) ); - QCOMPARE( hash.size(), 10 ); - QCOMPARE( hash2[ FlexibleThrowerSmall(1) ], FlexibleThrowerSmall(1) ); - QCOMPARE( hash2.size(), 10 ); - - hash2.clear(); - instances = objCounter; - try { - throwType = ThrowLater; - hash2.reserve(30); - } catch(...) { - QCOMPARE(instances, objCounter); - } - QCOMPARE( hash2.size(), 0 ); - - /* - try { - throwType = ThrowAtCopy; - hash.prepend( FlexibleThrowerSmall(10)); - } catch (...) { - } - QCOMPARE( hash.at(0).value(), 0 ); - QCOMPARE( hash.size(), 10 ); - - try { - throwType = ThrowAtCopy; - hash.insert( 8, FlexibleThrowerSmall(10)); - } catch (...) { - } - QCOMPARE( hash.at(7).value(), 7 ); - QCOMPARE( hash.at(8).value(), 8 ); - QCOMPARE( hash.size(), 10 ); - - qDebug("val"); - try { - throwType = ThrowAtCopy; - hash3 = hash; - } catch (...) { - } - QCOMPARE( hash.at(0).value(), 0 ); - QCOMPARE( hash.at(7).value(), 7 ); - QCOMPARE( hash.size(), 10 ); - QCOMPARE( hash3.at(0).value(), 0 ); - QCOMPARE( hash3.at(7).value(), 7 ); - QCOMPARE( hash3.size(), 10 ); - - try { - throwType = ThrowAtCopy; - hash3.append( FlexibleThrowerSmall(11) ); - } catch (...) { - } - QCOMPARE( hash.at(0).value(), 0 ); - QCOMPARE( hash.at(7).value(), 7 ); - QCOMPARE( hash.size(), 10 ); - QCOMPARE( hash3.at(0).value(), 0 ); - QCOMPARE( hash3.at(7).value(), 7 ); - QCOMPARE( hash3.at(11).value(), 11 ); - - try { - hash2.clear(); - hash2.append( FlexibleThrowerSmall(11)); - throwType = ThrowAtCopy; - hash3 = hash+hash2; - } catch (...) { - } - QCOMPARE( hash.at(0).value(), 0 ); - QCOMPARE( hash.at(7).value(), 7 ); - QCOMPARE( hash.size(), 10 ); - - // check that copy on write works atomar - hash2.clear(); - hash2.append( FlexibleThrowerSmall(11)); - hash3 = hash+hash2; - try { - throwType = ThrowAtCopy; - hash3[7]=FlexibleThrowerSmall(12); - } catch (...) { - } - QCOMPARE( hash.at(7).value(), 7 ); - QCOMPARE( hash.size(), 10 ); - QCOMPARE( hash3.at(7).value(), 7 ); - QCOMPARE( hash3.size(), 11 ); - */ - - - } - QCOMPARE(objCounter, intancesCount); // check that every object has been freed -} - -// Disable these tests until the level of exception safety in event loops is clear -#if 0 -enum -{ - ThrowEventId = QEvent::User + 42, - NoThrowEventId = QEvent::User + 43 -}; - -class ThrowEvent : public QEvent -{ -public: - ThrowEvent() - : QEvent(static_cast<QEvent::Type>(ThrowEventId)) - { - } -}; - -class NoThrowEvent : public QEvent -{ -public: - NoThrowEvent() - : QEvent(static_cast<QEvent::Type>(NoThrowEventId)) - {} -}; - -struct IntEx : public std::exception -{ - IntEx(int aEx) : ex(aEx) {} - int ex; -}; - -class TestObject : public QObject -{ -public: - TestObject() - : throwEventCount(0), noThrowEventCount(0) {} - - int throwEventCount; - int noThrowEventCount; - -protected: - bool event(QEvent *event) - { - if (int(event->type()) == ThrowEventId) { - throw IntEx(++throwEventCount); - } else if (int(event->type()) == NoThrowEventId) { - ++noThrowEventCount; - } - return QObject::event(event); - } -}; - -void tst_ExceptionSafety::exceptionEventLoop() -{ - // send an event that throws - TestObject obj; - ThrowEvent throwEvent; - try { - qApp->sendEvent(&obj, &throwEvent); - } catch (IntEx code) { - QCOMPARE(code.ex, 1); - } - QCOMPARE(obj.throwEventCount, 1); - - // post an event that throws - qApp->postEvent(&obj, new ThrowEvent); - - try { - qApp->processEvents(); - } catch (IntEx code) { - QCOMPARE(code.ex, 2); - } - QCOMPARE(obj.throwEventCount, 2); - - // post a normal event, then a throwing event, then a normal event - // run this in valgrind to ensure that it doesn't leak. - - qApp->postEvent(&obj, new NoThrowEvent); - qApp->postEvent(&obj, new ThrowEvent); - qApp->postEvent(&obj, new NoThrowEvent); - - try { - qApp->processEvents(); - } catch (IntEx code) { - QCOMPARE(code.ex, 3); - } - // here, we should have received on non-throwing event and one throwing one - QCOMPARE(obj.throwEventCount, 3); - QCOMPARE(obj.noThrowEventCount, 1); - - // spin the event loop again - qApp->processEvents(); - - // now, we should have received the second non-throwing event - QCOMPARE(obj.noThrowEventCount, 2); -} - -void tst_ExceptionSafety::exceptionSignalSlot() -{ - Emitter e; - ExceptionThrower thrower; - Receiver r1; - Receiver r2; - - // connect a signal to a normal object, a thrower and a normal object again - connect(&e, SIGNAL(testSignal()), &r1, SLOT(receiver())); - connect(&e, SIGNAL(testSignal()), &thrower, SLOT(thrower())); - connect(&e, SIGNAL(testSignal()), &r2, SLOT(receiver())); - - int code = 0; - try { - e.emitTestSignal(); - } catch (int c) { - code = c; - } - - // 5 is the magic number that's thrown by thrower - QCOMPARE(code, 5); - - // assumption: slots are called in the connection order - QCOMPARE(r1.received, 1); - QCOMPARE(r2.received, 0); -} -#endif - - -static bool outOfMemory = false; -void* internalMalloc(size_t bytes) { return outOfMemory ? 0 : malloc(bytes); } - -struct OutOfMemory -{ - OutOfMemory() { outOfMemory = true; } - ~OutOfMemory() { outOfMemory = false; } -}; - -void tst_ExceptionSafety::exceptionOOMQVarLengthArray() -{ -#ifdef QT_NO_EXCEPTIONS - // it will crash by design - Q_STATIC_ASSERT(false); -#else - QVarLengthArray<char> arr0; - int minSize = arr0.capacity(); - - // constructor throws - bool success = false; - try { - OutOfMemory oom; - QVarLengthArray<char> arr(minSize * 2); - } catch (const std::bad_alloc&) { - success = true; - } - QVERIFY(success); - - QVarLengthArray<char> arr; - - // resize throws - success = false; - try { - OutOfMemory oom; - arr.resize(minSize * 2); - } catch(const std::bad_alloc&) { - arr.resize(1); - success = true; - } - QVERIFY(success); -#endif -} - -#endif - -QTEST_MAIN(tst_ExceptionSafety) -#include "tst_exceptionsafety.moc" diff --git a/tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h b/tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h deleted file mode 100644 index 72a02ca9ba..0000000000 --- a/tests/auto/other/exceptionsafety_objects/3rdparty/memcheck.h +++ /dev/null @@ -1,319 +0,0 @@ - -/* - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (memcheck.h) only. The rest of Valgrind is licensed under the - terms of the GNU General Public License, version 2, unless - otherwise indicated. See the COPYING file in the source - distribution for details. - - ---------------------------------------------------------------- - - This file is part of MemCheck, a heavyweight Valgrind tool for - detecting memory errors. - - Copyright (C) 2000-2008 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (memcheck.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -#ifndef __MEMCHECK_H -#define __MEMCHECK_H - - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query memory permissions - inside your own programs. - - See comment near the top of valgrind.h on how to use them. -*/ - -#include "valgrind.h" - -/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! - This enum comprises an ABI exported by Valgrind to programs - which use client requests. DO NOT CHANGE THE ORDER OF THESE - ENTRIES, NOR DELETE ANY -- add new ones at the end. */ -typedef - enum { - VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'), - VG_USERREQ__MAKE_MEM_UNDEFINED, - VG_USERREQ__MAKE_MEM_DEFINED, - VG_USERREQ__DISCARD, - VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE, - VG_USERREQ__CHECK_MEM_IS_DEFINED, - VG_USERREQ__DO_LEAK_CHECK, - VG_USERREQ__COUNT_LEAKS, - - VG_USERREQ__GET_VBITS, - VG_USERREQ__SET_VBITS, - - VG_USERREQ__CREATE_BLOCK, - - VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, - - VG_USERREQ__ENABLE_OOM, - VG_USERREQ__GET_ALLOC_INDEX, - - /* This is just for memcheck's internal use - don't use it */ - _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR - = VG_USERREQ_TOOL_BASE('M','C') + 256, - - /* This is just for memcheck's internal use - don't use it */ - _VG_USERREQ__EXCEPTION - = VG_USERREQ_TOOL_BASE('M','C') + 512, - } Vg_MemCheckClientRequest; - - - -/* Client-code macros to manipulate the state of memory. */ - -/* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */ -#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_MEM_NOACCESS, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Similarly, mark memory at _qzz_addr as addressable but undefined - for _qzz_len bytes. */ -#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_MEM_UNDEFINED, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Similarly, mark memory at _qzz_addr as addressable and defined - for _qzz_len bytes. */ -#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_MEM_DEFINED, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is - not altered: bytes which are addressable are marked as defined, - but those which are not addressable are left unchanged. */ -#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Create a block-description handle. The description is an ascii - string which is included in any messages pertaining to addresses - within the specified memory range. Has no other effect on the - properties of the memory range. */ -#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__CREATE_BLOCK, \ - _qzz_addr, _qzz_len, _qzz_desc, \ - 0, 0); \ - _qzz_res; \ - })) - -/* Discard a block-description-handle. Returns 1 for an - invalid handle, 0 for a valid handle. */ -#define VALGRIND_DISCARD(_qzz_blkindex) \ - (__extension__ ({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__DISCARD, \ - 0, _qzz_blkindex, 0, 0, 0); \ - _qzz_res; \ - })) - - -/* Client-code macros to check the state of memory. */ - -/* Check that memory at _qzz_addr is addressable for _qzz_len bytes. - If suitable addressibility is not established, Valgrind prints an - error message and returns the address of the first offending byte. - Otherwise it returns zero. */ -#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Check that memory at _qzz_addr is addressable and defined for - _qzz_len bytes. If suitable addressibility and definedness are not - established, Valgrind prints an error message and returns the - address of the first offending byte. Otherwise it returns zero. */ -#define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \ - (__extension__({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__CHECK_MEM_IS_DEFINED, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Use this macro to force the definedness and addressibility of an - lvalue to be checked. If suitable addressibility and definedness - are not established, Valgrind prints an error message and returns - the address of the first offending byte. Otherwise it returns - zero. */ -#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \ - VALGRIND_CHECK_MEM_IS_DEFINED( \ - (volatile unsigned char *)&(__lvalue), \ - (unsigned long)(sizeof (__lvalue))) - - -/* Do a memory leak check mid-execution. */ -#define VALGRIND_DO_LEAK_CHECK \ - {unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DO_LEAK_CHECK, \ - 0, 0, 0, 0, 0); \ - } - -/* Just display summaries of leaked memory, rather than all the - details */ -#define VALGRIND_DO_QUICK_LEAK_CHECK \ - {unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DO_LEAK_CHECK, \ - 1, 0, 0, 0, 0); \ - } - -/* Return number of leaked, dubious, reachable and suppressed bytes found by - all previous leak checks. They must be lvalues. */ -#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \ - /* For safety on 64-bit platforms we assign the results to private - unsigned long variables, then assign these to the lvalues the user - specified, which works no matter what type 'leaked', 'dubious', etc - are. We also initialise '_qzz_leaked', etc because - VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as - initialised. */ \ - {unsigned long _qzz_res; \ - unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \ - unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__COUNT_LEAKS, \ - &_qzz_leaked, &_qzz_dubious, \ - &_qzz_reachable, &_qzz_suppressed, 0); \ - leaked = _qzz_leaked; \ - dubious = _qzz_dubious; \ - reachable = _qzz_reachable; \ - suppressed = _qzz_suppressed; \ - } - - -/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it - into the provided zzvbits array. Return values: - 0 if not running on valgrind - 1 success - 2 [previously indicated unaligned arrays; these are now allowed] - 3 if any parts of zzsrc/zzvbits are not addressable. - The metadata is not copied in cases 0, 2 or 3 so it should be - impossible to segfault your system by using this call. -*/ -#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \ - (__extension__({unsigned long _qzz_res; \ - char* czza = (char*)zza; \ - char* czzvbits = (char*)zzvbits; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__GET_VBITS, \ - czza, czzvbits, zznbytes, 0, 0 ); \ - _qzz_res; \ - })) - -/* Set the validity data for addresses [zza..zza+zznbytes-1], copying it - from the provided zzvbits array. Return values: - 0 if not running on valgrind - 1 success - 2 [previously indicated unaligned arrays; these are now allowed] - 3 if any parts of zza/zzvbits are not addressable. - The metadata is not copied in cases 0, 2 or 3 so it should be - impossible to segfault your system by using this call. -*/ -#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \ - (__extension__({unsigned int _qzz_res; \ - char* czza = (char*)zza; \ - char* czzvbits = (char*)zzvbits; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__SET_VBITS, \ - czza, czzvbits, zznbytes, 0, 0 ); \ - _qzz_res; \ - })) - -/* Enable or disable OOM simulation. */ -#define VALGRIND_ENABLE_OOM_AT_ALLOC_INDEX(index) \ - (__extension__ ({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__ENABLE_OOM, \ - 1, index, 0, 0, 0); \ - _qzz_res; \ - })) - -#define VALGRIND_DISABLE_OOM_AT_ALLOC_INDEX(index) \ - (__extension__ ({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \ - VG_USERREQ__ENABLE_OOM, \ - 0, index, 0, 0, 0); \ - _qzz_res; \ - })) - -/* Get the current allocation index. */ -#define VALGRIND_GET_ALLOC_INDEX \ - (__extension__ ({unsigned long _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, -1 /* default return */, \ - VG_USERREQ__GET_ALLOC_INDEX, \ - 0, 0, 0, 0, 0); \ - _qzz_res; \ - })) - - -#endif - diff --git a/tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h b/tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h deleted file mode 100644 index bb054b5fd1..0000000000 --- a/tests/auto/other/exceptionsafety_objects/3rdparty/valgrind.h +++ /dev/null @@ -1,3924 +0,0 @@ -/* -*- c -*- - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (valgrind.h) only. The rest of Valgrind is licensed under the - terms of the GNU General Public License, version 2, unless - otherwise indicated. See the COPYING file in the source - distribution for details. - - ---------------------------------------------------------------- - - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright (C) 2000-2008 Julian Seward. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (valgrind.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query Valgrind's - execution inside your own programs. - - The resulting executables will still run without Valgrind, just a - little bit more slowly than they otherwise would, but otherwise - unchanged. When not running on valgrind, each client request - consumes very few (eg. 7) instructions, so the resulting performance - loss is negligible unless you plan to execute client requests - millions of times per second. Nevertheless, if that is still a - problem, you can compile with the NVALGRIND symbol defined (gcc - -DNVALGRIND) so that client requests are not even compiled in. */ - -#ifndef __VALGRIND_H -#define __VALGRIND_H - -#include <stdarg.h> - -/* Nb: this file might be included in a file compiled with -ansi. So - we can't use C++ style "//" comments nor the "asm" keyword (instead - use "__asm__"). */ - -/* Derive some tags indicating what the target platform is. Note - that in this file we're using the compiler's CPP symbols for - identifying architectures, which are different to the ones we use - within the rest of Valgrind. Note, __powerpc__ is active for both - 32 and 64-bit PPC, whereas __powerpc64__ is only active for the - latter (on Linux, that is). */ -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64_linux -#undef PLAT_ppc32_aix5 -#undef PLAT_ppc64_aix5 - -#if !defined(_AIX) && defined(__i386__) -# define PLAT_x86_linux 1 -#elif !defined(_AIX) && defined(__x86_64__) -# define PLAT_amd64_linux 1 -#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__) -# define PLAT_ppc32_linux 1 -#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__) -# define PLAT_ppc64_linux 1 -#elif defined(_AIX) && defined(__64BIT__) -# define PLAT_ppc64_aix5 1 -#elif defined(_AIX) && !defined(__64BIT__) -# define PLAT_ppc32_aix5 1 -#endif - - -/* If we're not compiling for our target platform, don't generate - any inline asms. */ -#if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \ - && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \ - && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5) -# if !defined(NVALGRIND) -# define NVALGRIND 1 -# endif -#endif - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ -/* in here of use to end-users -- skip to the next section. */ -/* ------------------------------------------------------------------ */ - -#if defined(NVALGRIND) - -/* Define NVALGRIND to completely remove the Valgrind magic sequence - from the compiled code (analogous to NDEBUG's effects on - assert()) */ -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { \ - (_zzq_rlval) = (_zzq_default); \ - } - -#else /* ! NVALGRIND */ - -/* The following defines the magic code sequences which the JITter - spots and handles magically. Don't look too closely at them as - they will rot your brain. - - The assembly code sequences for all architectures is in this one - file. This is because this file must be stand-alone, and we don't - want to have multiple files. - - For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default - value gets put in the return slot, so that everything works when - this is executed not under Valgrind. Args are passed in a memory - block, and so there's no intrinsic limit to the number that could - be passed, but it's currently five. - - The macro args are: - _zzq_rlval result lvalue - _zzq_default default value (result returned when running on real CPU) - _zzq_request request code - _zzq_arg1..5 request params - - The other two macros are used to support function wrapping, and are - a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the - guest's NRADDR pseudo-register and whatever other information is - needed to safely run the call original from the wrapper: on - ppc64-linux, the R2 value at the divert point is also needed. This - information is abstracted into a user-visible type, OrigFn. - - VALGRIND_CALL_NOREDIR_* behaves the same as the following on the - guest, but guarantees that the branch instruction will not be - redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: - branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a - complete inline asm, since it needs to be combined with more magic - inline asm stuff to be useful. -*/ - -/* ------------------------- x86-linux ------------------------- */ - -#if defined(PLAT_x86_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "roll $3, %%edi ; roll $13, %%edi\n\t" \ - "roll $29, %%edi ; roll $19, %%edi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EDX = client_request ( %EAX ) */ \ - "xchgl %%ebx,%%ebx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - "xchgl %%ecx,%%ecx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%EAX */ \ - "xchgl %%edx,%%edx\n\t" -#endif /* PLAT_x86_linux */ - -/* ------------------------ amd64-linux ------------------------ */ - -#if defined(PLAT_amd64_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ - "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - { volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RDX = client_request ( %RAX ) */ \ - "xchgq %%rbx,%%rbx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RAX = guest_NRADDR */ \ - "xchgq %%rcx,%%rcx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_RAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%RAX */ \ - "xchgq %%rdx,%%rdx\n\t" -#endif /* PLAT_amd64_linux */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ - "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned int _zzq_args[6]; \ - unsigned int _zzq_result; \ - unsigned int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned long long int _zzq_args[6]; \ - register unsigned long long int _zzq_result __asm__("r3"); \ - register unsigned long long int* _zzq_ptr __asm__("r4"); \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1" \ - : "=r" (_zzq_result) \ - : "0" (_zzq_default), "r" (_zzq_ptr) \ - : "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned long long int __addr __asm__("r3"); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2" \ - : "=r" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4" \ - : "=r" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#endif /* PLAT_ppc64_linux */ - -/* ------------------------ ppc32-aix5 ------------------------- */ - -#if defined(PLAT_ppc32_aix5) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - unsigned int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \ - "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned int _zzq_args[7]; \ - register unsigned int _zzq_result; \ - register unsigned int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_args[6] = (unsigned int)(_zzq_default); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 4,%1\n\t" \ - "lwz 3, 24(4)\n\t" \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" \ - : "=b" (_zzq_result) \ - : "b" (_zzq_ptr) \ - : "r3", "r4", "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#endif /* PLAT_ppc32_aix5 */ - -/* ------------------------ ppc64-aix5 ------------------------- */ - -#if defined(PLAT_ppc64_aix5) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST( \ - _zzq_rlval, _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - { unsigned long long int _zzq_args[7]; \ - register unsigned long long int _zzq_result; \ - register unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int long long)(_zzq_request); \ - _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \ - _zzq_args[6] = (unsigned int long long)(_zzq_default); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 4,%1\n\t" \ - "ld 3, 48(4)\n\t" \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" \ - : "=b" (_zzq_result) \ - : "b" (_zzq_ptr) \ - : "r3", "r4", "cc", "memory"); \ - _zzq_rlval = _zzq_result; \ - } - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - register unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "r3", "cc", "memory" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#endif /* PLAT_ppc64_aix5 */ - -/* Insert assembly code for other platforms here... */ - -#endif /* NVALGRIND */ - - -/* ------------------------------------------------------------------ */ -/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ -/* ugly. It's the least-worst tradeoff I can think of. */ -/* ------------------------------------------------------------------ */ - -/* This section defines magic (a.k.a appalling-hack) macros for doing - guaranteed-no-redirection macros, so as to get from function - wrappers to the functions they are wrapping. The whole point is to - construct standard call sequences, but to do the call itself with a - special no-redirect call pseudo-instruction that the JIT - understands and handles specially. This section is long and - repetitious, and I can't see a way to make it shorter. - - The naming scheme is as follows: - - CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} - - 'W' stands for "word" and 'v' for "void". Hence there are - different macros for calling arity 0, 1, 2, 3, 4, etc, functions, - and for each, the possibility of returning a word-typed result, or - no result. -*/ - -/* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */ - -#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ - _vgwZU_##soname##_##fnname - -#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ - _vgwZZ_##soname##_##fnname - -/* Use this macro from within a wrapper function to collect the - context (address and possibly other info) of the original function. - Once you have that you can then use it in one of the CALL_FN_ - macros. The type of the argument _lval is OrigFn. */ -#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) - -/* Derivatives of the main macros below, for calling functions - returning void. */ - -#define CALL_FN_v_v(fnptr) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_v(_junk,fnptr); } while (0) - -#define CALL_FN_v_W(fnptr, arg1) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_W(_junk,fnptr,arg1); } while (0) - -#define CALL_FN_v_WW(fnptr, arg1,arg2) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) - -#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) - -/* ------------------------- x86-linux ------------------------- */ - -#if defined(PLAT_x86_linux) - -/* These regs are trashed by the hidden call. No need to mention eax - as gcc can already see that, plus causes gcc to bomb. */ -#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" - -/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $4, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $8, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $12, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $16, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $20, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $24, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $28, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $32, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $36, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $40, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $44, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "pushl 48(%%eax)\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - "addl $48, %%esp\n" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_x86_linux */ - -/* ------------------------ amd64-linux ------------------------ */ - -#if defined(PLAT_amd64_linux) - -/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ - "rdi", "r8", "r9", "r10", "r11" - -/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned - long) == 8. */ - -/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ - macros. In order not to trash the stack redzone, we need to drop - %rsp by 128 before the hidden call, and restore afterwards. The - nastyness is that it is only by luck that the stack still appears - to be unwindable during the hidden call - since then the behaviour - of any routine using this macro does not match what the CFI data - says. Sigh. - - Why is this important? Imagine that a wrapper has a stack - allocated local, and passes to the hidden call, a pointer to it. - Because gcc does not know about the hidden call, it may allocate - that local in the redzone. Unfortunately the hidden call may then - trash it before it comes to use it. So we must step clear of the - redzone, for the duration of the hidden call, to make it safe. - - Probably the same problem afflicts the other redzone-style ABIs too - (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is - self describing (none of this CFI nonsense) so at least messing - with the stack pointer doesn't give a danger of non-unwindable - stack. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - "addq $128,%%rsp\n\t" \ - VALGRIND_CALL_NOREDIR_RAX \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $8, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $16, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $24, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $32, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $40, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "subq $128,%%rsp\n\t" \ - "pushq 96(%%rax)\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - "addq $48, %%rsp\n" \ - "addq $128,%%rsp\n\t" \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_amd64_linux */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -/* This is useful for finding out about the on-stack stuff: - - extern int f9 ( int,int,int,int,int,int,int,int,int ); - extern int f10 ( int,int,int,int,int,int,int,int,int,int ); - extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); - extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); - - int g9 ( void ) { - return f9(11,22,33,44,55,66,77,88,99); - } - int g10 ( void ) { - return f10(11,22,33,44,55,66,77,88,99,110); - } - int g11 ( void ) { - return f11(11,22,33,44,55,66,77,88,99,110,121); - } - int g12 ( void ) { - return f12(11,22,33,44,55,66,77,88,99,110,121,132); - } -*/ - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* These CALL_FN_ macros assume that on ppc32-linux, - sizeof(unsigned long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,16\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,16\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,32\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,20(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "addi 1,1,32\n\t" \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64_linux) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)" /* restore tocptr */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,128" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,128" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,144" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - "addi 1,1,144" /* restore frame */ \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64_linux */ - -/* ------------------------ ppc32-aix5 ------------------------- */ - -#if defined(PLAT_ppc32_aix5) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Expand the stack frame, copying enough info that unwinding - still works. Trashes r3. */ - -#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ - "addi 1,1,-" #_n_fr "\n\t" \ - "lwz 3," #_n_fr "(1)\n\t" \ - "stw 3,0(1)\n\t" - -#define VG_CONTRACT_FRAME_BY(_n_fr) \ - "addi 1,1," #_n_fr "\n\t" - -/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(64) \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(64) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(64) \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(64) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(72) \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,64(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(72) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "stw 2,-8(11)\n\t" /* save tocptr */ \ - "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(72) \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,68(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,64(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,60(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,56(1)\n\t" \ - /* args1-8 */ \ - "lwz 3, 4(11)\n\t" /* arg1->r3 */ \ - "lwz 4, 8(11)\n\t" /* arg2->r4 */ \ - "lwz 5, 12(11)\n\t" /* arg3->r5 */ \ - "lwz 6, 16(11)\n\t" /* arg4->r6 */ \ - "lwz 7, 20(11)\n\t" /* arg5->r7 */ \ - "lwz 8, 24(11)\n\t" /* arg6->r8 */ \ - "lwz 9, 28(11)\n\t" /* arg7->r9 */ \ - "lwz 10, 32(11)\n\t" /* arg8->r10 */ \ - "lwz 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "lwz 2,-8(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(72) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_aix5 */ - -/* ------------------------ ppc64-aix5 ------------------------- */ - -#if defined(PLAT_ppc64_aix5) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Expand the stack frame, copying enough info that unwinding - still works. Trashes r3. */ - -#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \ - "addi 1,1,-" #_n_fr "\n\t" \ - "ld 3," #_n_fr "(1)\n\t" \ - "std 3,0(1)\n\t" - -#define VG_CONTRACT_FRAME_BY(_n_fr) \ - "addi 1,1," #_n_fr "\n\t" - -/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(128) \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(128) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(128) \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(128) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(144) \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(144) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - "mr 11,%1\n\t" \ - VG_EXPAND_FRAME_BY_trashes_r3(512) \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - VG_EXPAND_FRAME_BY_trashes_r3(144) \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VG_CONTRACT_FRAME_BY(144) \ - VG_CONTRACT_FRAME_BY(512) \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64_aix5 */ - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ -/* */ -/* ------------------------------------------------------------------ */ - -/* Some request codes. There are many more of these, but most are not - exposed to end-user view. These are the public ones, all of the - form 0x1000 + small_number. - - Core ones are in the range 0x00000000--0x0000ffff. The non-public - ones start at 0x2000. -*/ - -/* These macros are used by tools -- they must be public, but don't - embed them into other programs. */ -#define VG_USERREQ_TOOL_BASE(a,b) \ - ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) -#define VG_IS_TOOL_USERREQ(a, b, v) \ - (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) - -/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! - This enum comprises an ABI exported by Valgrind to programs - which use client requests. DO NOT CHANGE THE ORDER OF THESE - ENTRIES, NOR DELETE ANY -- add new ones at the end. */ -typedef - enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, - VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, - - /* These allow any function to be called from the simulated - CPU but run on the real CPU. Nb: the first arg passed to - the function is always the ThreadId of the running - thread! So CLIENT_CALL0 actually requires a 1 arg - function, etc. */ - VG_USERREQ__CLIENT_CALL0 = 0x1101, - VG_USERREQ__CLIENT_CALL1 = 0x1102, - VG_USERREQ__CLIENT_CALL2 = 0x1103, - VG_USERREQ__CLIENT_CALL3 = 0x1104, - - /* Can be useful in regression testing suites -- eg. can - send Valgrind's output to /dev/null and still count - errors. */ - VG_USERREQ__COUNT_ERRORS = 0x1201, - - /* These are useful and can be interpreted by any tool that - tracks malloc() et al, by using vg_replace_malloc.c. */ - VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, - VG_USERREQ__FREELIKE_BLOCK = 0x1302, - /* Memory pool support. */ - VG_USERREQ__CREATE_MEMPOOL = 0x1303, - VG_USERREQ__DESTROY_MEMPOOL = 0x1304, - VG_USERREQ__MEMPOOL_ALLOC = 0x1305, - VG_USERREQ__MEMPOOL_FREE = 0x1306, - VG_USERREQ__MEMPOOL_TRIM = 0x1307, - VG_USERREQ__MOVE_MEMPOOL = 0x1308, - VG_USERREQ__MEMPOOL_CHANGE = 0x1309, - VG_USERREQ__MEMPOOL_EXISTS = 0x130a, - - /* Allow printfs to valgrind log. */ - VG_USERREQ__PRINTF = 0x1401, - VG_USERREQ__PRINTF_BACKTRACE = 0x1402, - - /* Stack support. */ - VG_USERREQ__STACK_REGISTER = 0x1501, - VG_USERREQ__STACK_DEREGISTER = 0x1502, - VG_USERREQ__STACK_CHANGE = 0x1503 - } Vg_ClientRequest; - -#if !defined(__GNUC__) -# define __extension__ /* */ -#endif - -/* Returns the number of Valgrinds this code is running under. That - is, 0 if running natively, 1 if running under Valgrind, 2 if - running under Valgrind which is running under another Valgrind, - etc. */ -#define RUNNING_ON_VALGRIND __extension__ \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \ - VG_USERREQ__RUNNING_ON_VALGRIND, \ - 0, 0, 0, 0, 0); \ - _qzz_res; \ - }) - - -/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + - _qzz_len - 1]. Useful if you are debugging a JITter or some such, - since it provides a way to make sure valgrind will retranslate the - invalidated area. Returns no value. */ -#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DISCARD_TRANSLATIONS, \ - _qzz_addr, _qzz_len, 0, 0, 0); \ - } - - -/* These requests are for getting Valgrind itself to print something. - Possibly with a backtrace. This is a really ugly hack. */ - -#if defined(NVALGRIND) - -# define VALGRIND_PRINTF(...) -# define VALGRIND_PRINTF_BACKTRACE(...) - -#else /* NVALGRIND */ - -/* Modern GCC will optimize the static routine out if unused, - and unused attribute will shut down warnings about it. */ -static int VALGRIND_PRINTF(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -static int -VALGRIND_PRINTF(const char *format, ...) -{ - unsigned long _qzz_res; - va_list vargs; - va_start(vargs, format); - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF, - (unsigned long)format, (unsigned long)vargs, - 0, 0, 0); - va_end(vargs); - return (int)_qzz_res; -} - -static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -static int -VALGRIND_PRINTF_BACKTRACE(const char *format, ...) -{ - unsigned long _qzz_res; - va_list vargs; - va_start(vargs, format); - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE, - (unsigned long)format, (unsigned long)vargs, - 0, 0, 0); - va_end(vargs); - return (int)_qzz_res; -} - -#endif /* NVALGRIND */ - - -/* These requests allow control to move from the simulated CPU to the - real CPU, calling an arbitrary function. - - Note that the current ThreadId is inserted as the first argument. - So this call: - - VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) - - requires f to have this signature: - - Word f(Word tid, Word arg1, Word arg2) - - where "Word" is a word-sized type. - - Note that these client requests are not entirely reliable. For example, - if you call a function with them that subsequently calls printf(), - there's a high chance Valgrind will crash. Generally, your prospects of - these working are made higher if the called function does not refer to - any global variables, and does not refer to any libc or other functions - (printf et al). Any kind of entanglement with libc or dynamic linking is - likely to have a bad outcome, for tricky reasons which we've grappled - with a lot in the past. -*/ -#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL0, \ - _qyy_fn, \ - 0, 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL1, \ - _qyy_fn, \ - _qyy_arg1, 0, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL2, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, 0, 0); \ - _qyy_res; \ - }) - -#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ - __extension__ \ - ({unsigned long _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__CLIENT_CALL3, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, \ - _qyy_arg3, 0); \ - _qyy_res; \ - }) - - -/* Counts the number of errors that have been recorded by a tool. Nb: - the tool must record the errors with VG_(maybe_record_error)() or - VG_(unique_error)() for them to be counted. */ -#define VALGRIND_COUNT_ERRORS \ - __extension__ \ - ({unsigned int _qyy_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \ - VG_USERREQ__COUNT_ERRORS, \ - 0, 0, 0, 0, 0); \ - _qyy_res; \ - }) - -/* Mark a block of memory as having been allocated by a malloc()-like - function. `addr' is the start of the usable block (ie. after any - redzone) `rzB' is redzone size if the allocator can apply redzones; - use '0' if not. Adding redzones makes it more likely Valgrind will spot - block overruns. `is_zeroed' indicates if the memory is zeroed, as it is - for calloc(). Put it immediately after the point where a block is - allocated. - - If you're using Memcheck: If you're allocating memory via superblocks, - and then handing out small chunks of each superblock, if you don't have - redzones on your small blocks, it's worth marking the superblock with - VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are - detected. But if you can put redzones on, it's probably better to not do - this, so that messages for small overruns are described in terms of the - small block rather than the superblock (but if you have a big overrun - that skips over a redzone, you could miss an error this way). See - memcheck/tests/custom_alloc.c for an example. - - WARNING: if your allocator uses malloc() or 'new' to allocate - superblocks, rather than mmap() or brk(), this will not work properly -- - you'll likely get assertion failures during leak detection. This is - because Valgrind doesn't like seeing overlapping heap blocks. Sorry. - - Nb: block must be freed via a free()-like function specified - with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */ -#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed, 0); \ - } - -/* Mark a block of memory as having been freed by a free()-like function. - `rzB' is redzone size; it must match that given to - VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak - checker. Put it immediately after the point where the block is freed. */ -#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0, 0); \ - } - -/* Create a memory pool. */ -#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__CREATE_MEMPOOL, \ - pool, rzB, is_zeroed, 0, 0); \ - } - -/* Destroy a memory pool. */ -#define VALGRIND_DESTROY_MEMPOOL(pool) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__DESTROY_MEMPOOL, \ - pool, 0, 0, 0, 0); \ - } - -/* Associate a piece of memory with a memory pool. */ -#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_ALLOC, \ - pool, addr, size, 0, 0); \ - } - -/* Disassociate a piece of memory from a memory pool. */ -#define VALGRIND_MEMPOOL_FREE(pool, addr) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_FREE, \ - pool, addr, 0, 0, 0); \ - } - -/* Disassociate any pieces outside a particular range. */ -#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_TRIM, \ - pool, addr, size, 0, 0); \ - } - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MOVE_MEMPOOL, \ - poolA, poolB, 0, 0, 0); \ - } - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_CHANGE, \ - pool, addrA, addrB, size, 0); \ - } - -/* Return 1 if a mempool exists, else 0. */ -#define VALGRIND_MEMPOOL_EXISTS(pool) \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__MEMPOOL_EXISTS, \ - pool, 0, 0, 0, 0); \ - _qzz_res; \ - }) - -/* Mark a piece of memory as being a stack. Returns a stack id. */ -#define VALGRIND_STACK_REGISTER(start, end) \ - ({unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_REGISTER, \ - start, end, 0, 0, 0); \ - _qzz_res; \ - }) - -/* Unmark the piece of memory associated with a stack id as being a - stack. */ -#define VALGRIND_STACK_DEREGISTER(id) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_DEREGISTER, \ - id, 0, 0, 0, 0); \ - } - -/* Change the start and end address of the stack id. */ -#define VALGRIND_STACK_CHANGE(id, start, end) \ - {unsigned int _qzz_res; \ - VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \ - VG_USERREQ__STACK_CHANGE, \ - id, start, end, 0, 0); \ - } - - -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64_linux -#undef PLAT_ppc32_aix5 -#undef PLAT_ppc64_aix5 - -#endif /* __VALGRIND_H */ diff --git a/tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro b/tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro deleted file mode 100644 index 665ca99e41..0000000000 --- a/tests/auto/other/exceptionsafety_objects/exceptionsafety_objects.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += testcase -TARGET = tst_exceptionsafety_objects -QT += widgets testlib -HEADERS += oomsimulator.h 3rdparty/valgrind.h 3rdparty/memcheck.h -SOURCES += tst_exceptionsafety_objects.cpp -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/exceptionsafety_objects/oomsimulator.h b/tests/auto/other/exceptionsafety_objects/oomsimulator.h deleted file mode 100644 index 23a7f3839a..0000000000 --- a/tests/auto/other/exceptionsafety_objects/oomsimulator.h +++ /dev/null @@ -1,293 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <malloc.h> -#include <limits.h> -#include <stdio.h> -#include <exception> - -#if !defined(Q_OS_WIN) -# include "3rdparty/memcheck.h" -#endif - -static bool mallocFailActive = false; -static int mallocFailIndex = 0; -static int mallocCount = 0; - -static void my_terminate_handler() -{ - // set a breakpoint here to get a backtrace for your uncaught exceptions - fprintf(stderr, "Uncaught Exception Detected. Set a breakpoint in my_terminate_handler()\n"); - exit(1); -} - -#if defined(__GLIBC__) && !defined(__UCLIBC__) -/* Use glibc's memory allocation hooks */ - -// From glibc 2.14, the malloc hook variables are declared volatile. -// Note: The malloc hook implementation is marked as deprecated. - -#if !defined(__MALLOC_HOOK_VOLATILE) -# define __MALLOC_HOOK_VOLATILE -#endif - -/* our hooks */ -static void *my_malloc_hook(size_t, const void *); -static void *my_realloc_hook(void *, size_t, const void *); -static void *my_memalign_hook(size_t, size_t, const void *); -static void my_free_hook(void *, const void *); - -/* original hooks. */ -static void *(*__MALLOC_HOOK_VOLATILE old_malloc_hook)(size_t, const void *); -static void *(*__MALLOC_HOOK_VOLATILE old_realloc_hook)(void *, size_t, const void *); -static void *(*__MALLOC_HOOK_VOLATILE old_memalign_hook)(size_t, size_t, const void *); -static void (*__MALLOC_HOOK_VOLATILE old_free_hook)(void *, const void *); - -/* initializer function */ -static void my_init_hook(); - -/* Override initialising hook from the C library. */ - -void (*__MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = my_init_hook; - -static void disableHooks() -{ - __malloc_hook = old_malloc_hook; - __realloc_hook = old_realloc_hook; - __memalign_hook = old_memalign_hook; - __free_hook = old_free_hook; -} - -static void enableHooks() -{ - __malloc_hook = my_malloc_hook; - __realloc_hook = my_realloc_hook; - __memalign_hook = my_memalign_hook; - __free_hook = my_free_hook; -} - -void my_init_hook() -{ - old_malloc_hook = __malloc_hook; - old_realloc_hook = __realloc_hook; - old_memalign_hook = __memalign_hook; - old_free_hook = __free_hook; - enableHooks(); -} - -void *my_malloc_hook(size_t size, const void *) -{ - ++mallocCount; - - if (mallocFailActive && --mallocFailIndex < 0) - return 0; // simulate OOM - - __malloc_hook = old_malloc_hook; - void *result = ::malloc (size); - __malloc_hook = my_malloc_hook; - - return result; -} - -void *my_memalign_hook(size_t alignment, size_t size, const void *) -{ - ++mallocCount; - - if (mallocFailActive && --mallocFailIndex < 0) - return 0; // simulate OOM - - __memalign_hook = old_memalign_hook; - void *result = ::memalign(alignment, size); - __memalign_hook = my_memalign_hook; - - return result; -} - -void *my_realloc_hook(void *ptr, size_t size, const void *) -{ - ++mallocCount; - - if (mallocFailActive && --mallocFailIndex < 0) - return 0; // simulate OOM - - __realloc_hook = old_realloc_hook; - __malloc_hook = old_malloc_hook; - void *result = ::realloc(ptr, size); - __malloc_hook = my_malloc_hook; - __realloc_hook = my_realloc_hook; - - return result; -} - -void my_free_hook(void *ptr, const void *) -{ - __free_hook = old_free_hook; - ::free(ptr); - __free_hook = my_free_hook; -} - -#elif defined(Q_CC_MSVC) - -#include "crtdbg.h" - -static int qCrtAllocHook(int allocType, void * /*userData*/, size_t /*size*/, - int blockType, long /*requestNumber*/, - const unsigned char * /*filename*/, int /*lineNumber*/) -{ - if (blockType == _CRT_BLOCK) - return true; // ignore allocations from the C library - - switch (allocType) { - case _HOOK_ALLOC: - case _HOOK_REALLOC: - ++mallocCount; - if (mallocFailActive && --mallocFailIndex < 0) - return false; // simulate OOM - } - - return true; -} - -static struct QCrtDebugRegistrator -{ - QCrtDebugRegistrator() - { - _CrtSetAllocHook(qCrtAllocHook); - } - -} crtDebugRegistrator; - -#else - -static void disableHooks() -{ -} - -#endif - -struct AllocFailer -{ - inline AllocFailer(int index) { reactivateAt(index); } - inline ~AllocFailer() { deactivate(); } - - inline void reactivateAt(int index) - { -#ifdef RUNNING_ON_VALGRIND - if (RUNNING_ON_VALGRIND) - VALGRIND_ENABLE_OOM_AT_ALLOC_INDEX(VALGRIND_GET_ALLOC_INDEX + index + 1); -#endif - mallocFailIndex = index; - mallocFailActive = true; - } - - inline void deactivate() - { - mallocFailActive = false; -#ifdef RUNNING_ON_VALGRIND - VALGRIND_ENABLE_OOM_AT_ALLOC_INDEX(0); -#endif - } - - inline int currentAllocIndex() const - { -#ifdef RUNNING_ON_VALGRIND - if (RUNNING_ON_VALGRIND) - return VALGRIND_GET_ALLOC_INDEX; -#endif - return mallocCount; - } - - static bool initialize() - { - std::set_terminate(my_terminate_handler); -#ifdef RUNNING_ON_VALGRIND - if (RUNNING_ON_VALGRIND) { - if (VALGRIND_GET_ALLOC_INDEX == -1u) { - qWarning("You must use a valgrind with oom simulation support"); - return false; - } - // running in valgrind - don't use glibc hooks - disableHooks(); - - // never stop simulating OOM - VALGRIND_DISABLE_OOM_AT_ALLOC_INDEX(-1u); - } -#endif - return true; - } -}; - -static void *new_helper(std::size_t size) -{ - void *ptr = malloc(size); -#ifndef QT_NO_EXCEPTIONS - if (!ptr) - throw std::bad_alloc(); -#endif - return ptr; -} - -#ifdef Q_CC_MSVC -# pragma warning(push) -# pragma warning(disable: 4290) -#endif - -// overload operator new -#ifndef QT_NO_EXCEPTIONS -void* operator new(size_t size) throw (std::bad_alloc) { return new_helper(size); } -void* operator new[](size_t size) throw (std::bad_alloc) { return new_helper(size); } -#endif -void* operator new(size_t size, const std::nothrow_t&) throw() { return malloc(size); } -void* operator new[](std::size_t size, const std::nothrow_t&) throw() { return malloc(size); } - -// overload operator delete -void operator delete(void *ptr) throw() { if (ptr) free(ptr); } -void operator delete[](void *ptr) throw() { if (ptr) free(ptr); } -void operator delete(void *ptr, const std::nothrow_t&) throw() { if (ptr) free(ptr); } -void operator delete[](void *ptr, const std::nothrow_t&) throw() { if (ptr) free (ptr); } - -#ifdef Q_CC_MSVC -# pragma warning(pop) -#endif - -// ignore placement new and placement delete - those don't allocate. - - diff --git a/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp deleted file mode 100644 index da715516d7..0000000000 --- a/tests/auto/other/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ /dev/null @@ -1,803 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui/QtGui> -#include <QtWidgets/QtWidgets> -#include <QtTest/QtTest> - -#include <stddef.h> -#include <exception> - -QT_USE_NAMESPACE - -// this test only works with GLIBC - -#include "oomsimulator.h" -#include "3rdparty/memcheck.h" - -class tst_ExceptionSafety_Objects: public QObject -{ - Q_OBJECT - -public slots: - void initTestCase(); -#ifndef QT_NO_EXCEPTIONS - void cleanupTestCase(); - -private slots: - void objects_data(); - void objects(); - - void widgets_data(); - void widgets(); - - void vector_data(); - void vector(); - - void list_data(); - void list(); - - void linkedList_data(); - void linkedList(); - -private: - static QtMessageHandler testMessageHandler; - static void safeMessageHandler(QtMsgType, const QMessageLogContext&, const QString&); -#endif -}; - -#ifdef QT_NO_EXCEPTIONS -void tst_ExceptionSafety_Objects::initTestCase() -{ - QSKIP("This test requires exception support"); -} - -#else -// helper structs to create an arbitrary widget -struct AbstractTester -{ - virtual ~AbstractTester() {} - virtual void operator()(QObject *parent) = 0; -}; -Q_DECLARE_METATYPE(AbstractTester *) - -typedef void (*TestFunction)(QObject*); -Q_DECLARE_METATYPE(TestFunction) - -template <typename T> -struct ObjectCreator : public AbstractTester -{ - void operator()(QObject *) - { - QScopedPointer<T> ptr(new T); - } -}; - -struct BitArrayCreator : public AbstractTester -{ - void operator()(QObject *) - { QScopedPointer<QBitArray> bitArray(new QBitArray(100, true)); } -}; - -struct ByteArrayMatcherCreator : public AbstractTester -{ - void operator()(QObject *) - { QScopedPointer<QByteArrayMatcher> ptr(new QByteArrayMatcher("ralf test",8)); } -}; - -struct CryptographicHashCreator : public AbstractTester -{ - void operator()(QObject *) - { - QScopedPointer<QCryptographicHash> ptr(new QCryptographicHash(QCryptographicHash::Sha1)); - ptr->addData("ralf test",8); - } -}; - -struct DataStreamCreator : public AbstractTester -{ - void operator()(QObject *) - { - QScopedPointer<QByteArray> arr(new QByteArray("hallo, test")); - QScopedPointer<QDataStream> ptr(new QDataStream(arr.data(), QIODevice::ReadWrite)); - ptr->writeBytes("ralf test",8); - } -}; - -struct DirCreator : public AbstractTester -{ - void operator()(QObject *) - { - QDir::cleanPath("../////././"); - QScopedPointer<QDir> ptr(new QDir(".")); - while( ptr->cdUp() ) - ; // just going up - ptr->count(); - ptr->exists(ptr->path()); - - QStringList filters; - filters << "*.cpp" << "*.cxx" << "*.cc"; - ptr->setNameFilters(filters); - } -}; - -void tst_ExceptionSafety_Objects::objects_data() -{ - QTest::addColumn<AbstractTester *>("objectCreator"); - -#define NEWROW(T) QTest::newRow(#T) << static_cast<AbstractTester *>(new ObjectCreator<T >) - NEWROW(QObject); - NEWROW(QBuffer); - NEWROW(QFile); - NEWROW(QProcess); - NEWROW(QSettings); - NEWROW(QThread); - NEWROW(QThreadPool); - NEWROW(QTranslator); - -#define NEWROW2(T, CREATOR) QTest::newRow(#T) << static_cast<AbstractTester *>(new CREATOR) - NEWROW2(QBitArray, BitArrayCreator); - NEWROW2(QByteArrayMatcher, ByteArrayMatcherCreator); - NEWROW2(QCryptographicHash, CryptographicHashCreator); - NEWROW2(QDataStream, DataStreamCreator); - NEWROW2(QDir, DirCreator); -} - -// create and destructs an object, and lets each and every allocation -// during construction and destruction fail. -template <typename T> -static void doOOMTest(T &testFunc, QObject *parent, int start=0) -{ - int currentOOMIndex = start; - bool caught = false; - bool done = false; - - AllocFailer allocFailer(0); - int allocCountBefore = allocFailer.currentAllocIndex(); - - do { - allocFailer.reactivateAt(++currentOOMIndex); - - caught = false; - - try { - testFunc(parent); - } catch (const std::bad_alloc &) { - caught = true; - } catch (const std::exception &ex) { - if (strcmp(ex.what(), "autotest swallow") != 0) - throw; - caught = true; - } - - if (!caught) { - void *buf = malloc(42); - if (buf) { - // we got memory here - oom test is over. - free(buf); - done = true; - } - } - - // if we get a FAIL, stop executing now - if (QTest::currentTestFailed()) - done = true; - -//#define REALLY_VERBOSE -#ifdef REALLY_VERBOSE - fprintf(stderr, " OOM Index: %d\n", currentOOMIndex); -#endif - - - } while (caught || !done); - - allocFailer.deactivate(); - -//#define VERBOSE -#ifdef VERBOSE - fprintf(stderr, "OOM Test done, checked allocs: %d (range %d - %d)\n", currentOOMIndex, - allocCountBefore, allocFailer.currentAllocIndex()); -#else - Q_UNUSED(allocCountBefore); -#endif -} - -static int alloc1Failed = 0; -static int alloc2Failed = 0; -static int alloc3Failed = 0; -static int alloc4Failed = 0; -static int malloc1Failed = 0; -static int malloc2Failed = 0; - -// Tests that new, new[] and malloc() fail at least once during OOM testing. -class SelfTestObject : public QObject -{ -public: - SelfTestObject(QObject *parent = 0) - : QObject(parent) - { - try { delete new int; } catch (const std::bad_alloc &) { ++alloc1Failed; throw; } - try { delete [] new double[5]; } catch (const std::bad_alloc &) { ++alloc2Failed; throw ;} - void *buf = malloc(42); - if (buf) - free(buf); - else - ++malloc1Failed; - } - - ~SelfTestObject() - { - try { delete new int; } catch (const std::bad_alloc &) { ++alloc3Failed; } - try { delete [] new double[5]; } catch (const std::bad_alloc &) { ++alloc4Failed; } - void *buf = malloc(42); - if (buf) - free(buf); - else - ++malloc2Failed = true; - } -}; - -QtMessageHandler tst_ExceptionSafety_Objects::testMessageHandler; - -void tst_ExceptionSafety_Objects::safeMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, - const QString &msg) -{ - // this temporarily suspends OOM testing while handling a message - int currentIndex = mallocFailIndex; - AllocFailer allocFailer(0); - allocFailer.deactivate(); - (*testMessageHandler)(type, ctxt, msg); - allocFailer.reactivateAt(currentIndex); -} - -typedef void (*PVF)(); -PVF defaultTerminate; -void debugTerminate() -{ - // you can detect uncaught exceptions with a breakpoint in here - (*defaultTerminate)(); -} - -PVF defaultUnexpected; -void debugUnexpected() -{ - // you can detect unexpected exceptions with a breakpoint in here - (*defaultUnexpected)(); -} - -void tst_ExceptionSafety_Objects::initTestCase() -{ - // set handlers for bad exception cases, you might want to step in and breakpoint the default handlers too - defaultTerminate = std::set_terminate(&debugTerminate); - defaultUnexpected = std::set_unexpected(&debugUnexpected); - testMessageHandler = qInstallMessageHandler(safeMessageHandler); - - QVERIFY(AllocFailer::initialize()); - - // sanity check whether OOM simulation works - AllocFailer allocFailer(0); - - // malloc fail index is 0 -> this malloc should fail. - void *buf = malloc(42); - allocFailer.deactivate(); - QVERIFY(!buf); - - // malloc fail index is 1 - second malloc should fail. - allocFailer.reactivateAt(1); - buf = malloc(42); - void *buf2 = malloc(42); - allocFailer.deactivate(); - - QVERIFY(buf); - free(buf); - QVERIFY(!buf2); - - ObjectCreator<SelfTestObject> *selfTest = new ObjectCreator<SelfTestObject>; - doOOMTest(*selfTest, 0); - delete selfTest; - QCOMPARE(alloc1Failed, 1); - QCOMPARE(alloc2Failed, 1); - QCOMPARE(alloc3Failed, 2); - QCOMPARE(alloc4Failed, 3); - QCOMPARE(malloc1Failed, 1); - QCOMPARE(malloc2Failed, 1); -} - -void tst_ExceptionSafety_Objects::cleanupTestCase() -{ - qInstallMessageHandler(testMessageHandler); -} - -void tst_ExceptionSafety_Objects::objects() -{ - QLatin1String tag = QLatin1String(QTest::currentDataTag()); - if (tag == QLatin1String("QFile") - || tag == QLatin1String("QProcess") - || tag == QLatin1String("QSettings") - || tag == QLatin1String("QThread") - || tag == QLatin1String("QThreadPool")) - QSKIP("This type of object is not currently strongly exception safe"); - - QFETCH(AbstractTester *, objectCreator); - - doOOMTest(*objectCreator, 0); - - delete objectCreator; -} - -template <typename T> -struct WidgetCreator : public AbstractTester -{ - void operator()(QObject *parent) - { - if (parent && !parent->isWidgetType()) - qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); - QScopedPointer<T> ptr(parent ? new T(static_cast<QWidget *>(parent)) : new T); - } -}; - -// QSizeGrip doesn't have a default constructor - always pass parent (even though it might be 0) -template <> struct WidgetCreator<QSizeGrip> : public AbstractTester -{ - void operator()(QObject *parent) - { - if (parent && !parent->isWidgetType()) - qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); - QScopedPointer<QSizeGrip> ptr(new QSizeGrip(static_cast<QWidget *>(parent))); - } -}; - -// QDesktopWidget doesn't need a parent. -template <> struct WidgetCreator<QDesktopWidget> : public AbstractTester -{ - void operator()(QObject *parent) - { - if (parent && !parent->isWidgetType()) - qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); - QScopedPointer<QDesktopWidget> ptr(new QDesktopWidget()); - } -}; -void tst_ExceptionSafety_Objects::widgets_data() -{ - QTest::addColumn<AbstractTester *>("widgetCreator"); - -#undef NEWROW -#define NEWROW(T) QTest::newRow(#T) << static_cast<AbstractTester *>(new WidgetCreator<T >) - - NEWROW(QWidget); - - NEWROW(QButtonGroup); - NEWROW(QCheckBox); - NEWROW(QColumnView); - NEWROW(QComboBox); - NEWROW(QCommandLinkButton); - NEWROW(QDateEdit); - NEWROW(QDateTimeEdit); - NEWROW(QDesktopWidget); - NEWROW(QDial); - NEWROW(QDoubleSpinBox); - NEWROW(QFocusFrame); - NEWROW(QFontComboBox); - NEWROW(QFrame); - NEWROW(QGroupBox); - NEWROW(QLabel); - NEWROW(QLCDNumber); - NEWROW(QLineEdit); - NEWROW(QListView); - NEWROW(QListWidget); - NEWROW(QMainWindow); - NEWROW(QMenu); - NEWROW(QMenuBar); - NEWROW(QPlainTextEdit); - NEWROW(QProgressBar); - NEWROW(QPushButton); - NEWROW(QRadioButton); - NEWROW(QScrollArea); - NEWROW(QScrollBar); - NEWROW(QSizeGrip); - NEWROW(QSlider); - NEWROW(QSpinBox); - NEWROW(QSplitter); - NEWROW(QStackedWidget); - NEWROW(QStatusBar); - NEWROW(QTabBar); - NEWROW(QTableView); - NEWROW(QTableWidget); - NEWROW(QTabWidget); - NEWROW(QTextBrowser); - NEWROW(QTextEdit); - NEWROW(QTimeEdit); - NEWROW(QToolBar); - NEWROW(QToolBox); - NEWROW(QToolButton); - NEWROW(QTreeView); - NEWROW(QTreeWidget); -} - -void tst_ExceptionSafety_Objects::widgets() -{ - QLatin1String tag = QLatin1String(QTest::currentDataTag()); - if (tag == QLatin1String("QColumnView") - || tag == QLatin1String("QComboBox") - || tag == QLatin1String("QCommandLinkButton") - || tag == QLatin1String("QDateEdit") - || tag == QLatin1String("QDateTimeEdit") - || tag == QLatin1String("QDesktopWidget") - || tag == QLatin1String("QDoubleSpinBox") - || tag == QLatin1String("QFontComboBox") - || tag == QLatin1String("QGroupBox") - || tag == QLatin1String("QLineEdit") - || tag == QLatin1String("QListView") - || tag == QLatin1String("QListWidget") - || tag == QLatin1String("QMainWindow") - || tag == QLatin1String("QMenu") - || tag == QLatin1String("QMenuBar") - || tag == QLatin1String("QPlainTextEdit") - || tag == QLatin1String("QProgressBar") - || tag == QLatin1String("QPushButton") - || tag == QLatin1String("QScrollArea") - || tag == QLatin1String("QSpinBox") - || tag == QLatin1String("QStackedWidget") - || tag == QLatin1String("QStatusBar") - || tag == QLatin1String("QTableView") - || tag == QLatin1String("QTableWidget") - || tag == QLatin1String("QTabWidget") - || tag == QLatin1String("QTextBrowser") - || tag == QLatin1String("QTextEdit") - || tag == QLatin1String("QTimeEdit") - || tag == QLatin1String("QToolBar") - || tag == QLatin1String("QToolBox") - || tag == QLatin1String("QTreeView") - || tag == QLatin1String("QTreeWidget")) - QSKIP("This type of widget is not currently strongly exception safe"); - - if (tag == QLatin1String("QWidget")) - QSKIP("QTBUG-18927"); - - QFETCH(AbstractTester *, widgetCreator); - - doOOMTest(*widgetCreator, 0, 00000); - - QWidget parent; - doOOMTest(*widgetCreator, &parent, 00000); - - delete widgetCreator; - - // if the test reaches here without crashing, we passed :) - QVERIFY(true); -} - -struct Integer -{ - Integer(int value = 42) - : ptr(new int(value)) - { - ++instanceCount; - } - - Integer(const Integer &other) - : ptr(new int(*other.ptr)) - { - ++instanceCount; - } - - Integer &operator=(const Integer &other) - { - int *newPtr = new int(*other.ptr); - delete ptr; - ptr = newPtr; - return *this; - } - - ~Integer() - { - --instanceCount; - delete ptr; - } - - int value() const - { - return *ptr; - } - - int *ptr; - static int instanceCount; -}; - -int Integer::instanceCount = 0; - -struct IntegerMoveable - { - IntegerMoveable(int value = 42) - : val(value) - { - delete new int; - ++instanceCount; - } - - IntegerMoveable(const IntegerMoveable &other) - : val(other.val) - { - delete new int; - ++instanceCount; - } - - IntegerMoveable &operator=(const IntegerMoveable &other) - { - delete new int; - val = other.val; - return *this; - } - - ~IntegerMoveable() - { - --instanceCount; - } - - int value() const - { - return val; - } - - int val; - static int instanceCount; - }; - -int IntegerMoveable::instanceCount = 0; -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(IntegerMoveable, Q_MOVABLE_TYPE); -QT_END_NAMESPACE - -template <typename T, template<typename> class Container> -void containerInsertTest(QObject*) -{ - Container<T> container; - - // insert an item in an empty container - try { - container.insert(container.begin(), 41); - } catch (...) { - QVERIFY(container.isEmpty()); - QCOMPARE(T::instanceCount, 0); - return; - } - - QCOMPARE(container.size(), 1); - QCOMPARE(T::instanceCount, 1); - - // insert an item before another item - try { - container.insert(container.begin(), 42); - } catch (...) { - QCOMPARE(container.size(), 1); - QCOMPARE(container.first().value(), 41); - QCOMPARE(T::instanceCount, 1); - return; - } - - QCOMPARE(T::instanceCount, 2); - - // insert an item in between - try { - container.insert(container.begin() + 1, 43); - } catch (...) { - QCOMPARE(container.size(), 2); - QCOMPARE(container.first().value(), 41); - QCOMPARE((container.begin() + 1)->value(), 42); - QCOMPARE(T::instanceCount, 2); - return; - } - - QCOMPARE(T::instanceCount, 3); -} - -template <typename T, template<typename> class Container> -void containerAppendTest(QObject*) -{ - Container<T> container; - - // append to an empty container - try { - container.append(42); - } catch (...) { - QCOMPARE(container.size(), 0); - QCOMPARE(T::instanceCount, 0); - return; - } - - // append to a container with one item - try { - container.append(43); - } catch (...) { - QCOMPARE(container.size(), 1); - QCOMPARE(container.first().value(), 42); - QCOMPARE(T::instanceCount, 1); - return; - } - - Container<T> container2; - - try { - container2.append(44); - } catch (...) { - // don't care - return; - } - QCOMPARE(T::instanceCount, 3); - - // append another container with one item - try { - container += container2; - } catch (...) { - QCOMPARE(container.size(), 2); - QCOMPARE(container.first().value(), 42); - QCOMPARE((container.begin() + 1)->value(), 43); - QCOMPARE(T::instanceCount, 3); - return; - } - - QCOMPARE(T::instanceCount, 4); -} - -template <typename T, template<typename> class Container> -void containerEraseTest(QObject*) -{ - Container<T> container; - - try { - container.append(42); - container.append(43); - container.append(44); - container.append(45); - container.append(46); - } catch (...) { - // don't care - return; - } - - // sanity checks - QCOMPARE(container.size(), 5); - QCOMPARE(T::instanceCount, 5); - - // delete the first one - try { - container.erase(container.begin()); - } catch (...) { - QCOMPARE(container.size(), 5); - QCOMPARE(container.first().value(), 42); - QCOMPARE(T::instanceCount, 5); - return; - } - - QCOMPARE(container.size(), 4); - QCOMPARE(container.first().value(), 43); - QCOMPARE(T::instanceCount, 4); - - // delete the last one - try { - container.erase(container.end() - 1); - } catch (...) { - QCOMPARE(container.size(), 4); - QCOMPARE(T::instanceCount, 4); - return; - } - - QCOMPARE(container.size(), 3); - QCOMPARE(container.first().value(), 43); - QCOMPARE((container.begin() + 1)->value(), 44); - QCOMPARE((container.begin() + 2)->value(), 45); - QCOMPARE(T::instanceCount, 3); - - // delete the middle one - try { - container.erase(container.begin() + 1); - } catch (...) { - QCOMPARE(container.size(), 3); - QCOMPARE(container.first().value(), 43); - QCOMPARE((container.begin() + 1)->value(), 44); - QCOMPARE((container.begin() + 2)->value(), 45); - QCOMPARE(T::instanceCount, 3); - return; - } - - QCOMPARE(container.size(), 2); - QCOMPARE(container.first().value(), 43); - QCOMPARE((container.begin() + 1)->value(), 45); - QCOMPARE(T::instanceCount, 2); -} - -template <template<typename T> class Container> -static void containerData() -{ - QTest::addColumn<TestFunction>("testFunction"); - - QTest::newRow("insert static") << static_cast<TestFunction>(containerInsertTest<Integer, Container>); - QTest::newRow("append static") << static_cast<TestFunction>(containerAppendTest<Integer, Container>); - QTest::newRow("erase static") << static_cast<TestFunction>(containerEraseTest<Integer, Container>); - QTest::newRow("insert moveable") << static_cast<TestFunction>(containerInsertTest<IntegerMoveable, Container>); - QTest::newRow("append moveable") << static_cast<TestFunction>(containerAppendTest<IntegerMoveable, Container>); - QTest::newRow("erase moveable") << static_cast<TestFunction>(containerEraseTest<IntegerMoveable, Container>); -} - -void tst_ExceptionSafety_Objects::vector_data() -{ - containerData<QVector>(); -} - -void tst_ExceptionSafety_Objects::vector() -{ - QFETCH(TestFunction, testFunction); - - if (QLatin1String(QTest::currentDataTag()) == QLatin1String("insert static") - || QLatin1String(QTest::currentDataTag()) == QLatin1String("insert moveable")) - QSKIP("QVector::insert is currently not strongly exception safe"); - - doOOMTest(testFunction, 0); -} - -void tst_ExceptionSafety_Objects::list_data() -{ - containerData<QList>(); -} - -void tst_ExceptionSafety_Objects::list() -{ - QFETCH(TestFunction, testFunction); - - doOOMTest(testFunction, 0); -} - -void tst_ExceptionSafety_Objects::linkedList_data() -{ - containerData<QLinkedList>(); -} - -void tst_ExceptionSafety_Objects::linkedList() -{ - QFETCH(TestFunction, testFunction); - - doOOMTest(testFunction, 0); -} - -#endif - -QTEST_MAIN(tst_ExceptionSafety_Objects) -#include "tst_exceptionsafety_objects.moc" diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index 1d57206a73..63cbca539d 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -4,8 +4,6 @@ SUBDIRS=\ baselineexample \ collections \ compiler \ - exceptionsafety \ - # exceptionsafety_objects \ # QObjectPrivate is not safe gestures \ headersclean \ lancelot \ @@ -70,4 +68,3 @@ wince*|!contains(QT_CONFIG, accessibility): SUBDIRS -= qaccessibility !embedded|wince*: SUBDIRS -= \ qdirectpainter -!linux*-g++*:SUBDIRS -= exceptionsafety_objects diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index 54c5bb85f0..99e2e825c0 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -15,7 +15,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[int, string]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(int,123) + Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi)]]></Description> </Incident> <Incident type="pass" file="" line="0"> @@ -24,19 +24,19 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[null hash, invalid]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(QVariantHash) + Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant()]]></Description> </Incident> <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[string, null user type]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(QString,A simple string) + Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass)]]></Description> </Incident> <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[both non-null user type]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(PhonyClass,<value not representable as string>) + Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description> </Incident> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index 9d03a8e3da..504507f032 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -4,20 +4,20 @@ PASS : tst_Cmptest::initTestCase() PASS : tst_Cmptest::compare_boolfuncs() PASS : tst_Cmptest::compare_pointerfuncs() FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same - Actual (actual): QVariant(int,123) + Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi) Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] PASS : tst_Cmptest::compare_tostring(both invalid) FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same - Actual (actual): QVariant(QVariantHash) + Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant() Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same - Actual (actual): QVariant(QString,A simple string) + Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass) Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same - Actual (actual): QVariant(PhonyClass,<value not representable as string>) + Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>) Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)] PASS : tst_Cmptest::compareQStringLists(empty lists) diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index ccab93d7c0..df35058acc 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -17,7 +17,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[int, string]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(int,123) + Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi)]]></Description> </Incident> <Incident type="pass" file="" line="0"> @@ -26,19 +26,19 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[null hash, invalid]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(QVariantHash) + Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant()]]></Description> </Incident> <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[string, null user type]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(QString,A simple string) + Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass)]]></Description> </Incident> <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214"> <DataTag><![CDATA[both non-null user type]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (actual): QVariant(PhonyClass,<value not representable as string>) + Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description> </Incident> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index 0cb88147b0..e7d76ac839 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -9,16 +9,16 @@ <testcase result="pass" name="compare_pointerfuncs"/> <testcase result="fail" name="compare_tostring"> <failure tag="int, string" message="Compared values are not the same - Actual (actual): QVariant(int,123) + Actual (actual) : QVariant(int,123) Expected (expected): QVariant(QString,hi)" result="fail"/> <failure tag="null hash, invalid" message="Compared values are not the same - Actual (actual): QVariant(QVariantHash) + Actual (actual) : QVariant(QVariantHash) Expected (expected): QVariant()" result="fail"/> <failure tag="string, null user type" message="Compared values are not the same - Actual (actual): QVariant(QString,A simple string) + Actual (actual) : QVariant(QString,A simple string) Expected (expected): QVariant(PhonyClass)" result="fail"/> <failure tag="both non-null user type" message="Compared values are not the same - Actual (actual): QVariant(PhonyClass,<value not representable as string>) + Actual (actual) : QVariant(PhonyClass,<value not representable as string>) Expected (expected): QVariant(PhonyClass,<value not representable as string>)" result="fail"/> </testcase> <testcase result="fail" name="compareQStringLists"> diff --git a/tests/auto/testlib/selftests/expected_datetime.lightxml b/tests/auto/testlib/selftests/expected_datetime.lightxml index d8acae9c26..183744b2e2 100644 --- a/tests/auto/testlib/selftests/expected_datetime.lightxml +++ b/tests/auto/testlib/selftests/expected_datetime.lightxml @@ -9,7 +9,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="66"> <Description><![CDATA[Compared values are not the same Actual (local): 2000/05/03 04:03:04.000[local time] - Expected (utc): 2000/05/03 04:03:04.000[UTC]]]></Description> + Expected (utc) : 2000/05/03 04:03:04.000[UTC]]]></Description> </Incident> </TestFunction> <TestFunction name="qurl"> diff --git a/tests/auto/testlib/selftests/expected_datetime.txt b/tests/auto/testlib/selftests/expected_datetime.txt index ce9e1f36b4..0cbc6506d5 100644 --- a/tests/auto/testlib/selftests/expected_datetime.txt +++ b/tests/auto/testlib/selftests/expected_datetime.txt @@ -3,7 +3,7 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER PASS : tst_DateTime::initTestCase() FAIL! : tst_DateTime::dateTime() Compared values are not the same Actual (local): 2000/05/03 04:03:04.000[local time] - Expected (utc): 2000/05/03 04:03:04.000[UTC] + Expected (utc) : 2000/05/03 04:03:04.000[UTC] Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(33)] PASS : tst_DateTime::qurl(empty urls) FAIL! : tst_DateTime::qurl(empty rhs) Compared values are not the same diff --git a/tests/auto/testlib/selftests/expected_datetime.xml b/tests/auto/testlib/selftests/expected_datetime.xml index d7c9afabee..42b566c074 100644 --- a/tests/auto/testlib/selftests/expected_datetime.xml +++ b/tests/auto/testlib/selftests/expected_datetime.xml @@ -11,7 +11,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="66"> <Description><![CDATA[Compared values are not the same Actual (local): 2000/05/03 04:03:04.000[local time] - Expected (utc): 2000/05/03 04:03:04.000[UTC]]]></Description> + Expected (utc) : 2000/05/03 04:03:04.000[UTC]]]></Description> </Incident> </TestFunction> <TestFunction name="qurl"> diff --git a/tests/auto/testlib/selftests/expected_datetime.xunitxml b/tests/auto/testlib/selftests/expected_datetime.xunitxml index af0e4db7e8..00bd43f904 100644 --- a/tests/auto/testlib/selftests/expected_datetime.xunitxml +++ b/tests/auto/testlib/selftests/expected_datetime.xunitxml @@ -8,7 +8,7 @@ <testcase result="fail" name="dateTime"> <failure message="Compared values are not the same Actual (local): 2000/05/03 04:03:04.000[local time] - Expected (utc): 2000/05/03 04:03:04.000[UTC]" result="fail"/> + Expected (utc) : 2000/05/03 04:03:04.000[UTC]" result="fail"/> </testcase> <testcase result="fail" name="qurl"> <failure tag="empty rhs" message="Compared values are not the same diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt index dc32fd76f1..da98f9c19d 100644 --- a/tests/auto/testlib/selftests/expected_float.txt +++ b/tests/auto/testlib/selftests/expected_float.txt @@ -3,15 +3,15 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER PASS : tst_float::initTestCase() PASS : tst_float::floatComparisons(should SUCCEED 1) FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the same (fuzzy compare) - Actual (operandLeft): 1 + Actual (operandLeft) : 1 Expected (operandRight): 3 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] FAIL! : tst_float::floatComparisons(should FAIL 2) Compared floats are not the same (fuzzy compare) - Actual (operandLeft): 1e-07 + Actual (operandLeft) : 1e-07 Expected (operandRight): 3e-07 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the same (fuzzy compare) - Actual (operandLeft): 99998 + Actual (operandLeft) : 99998 Expected (operandRight): 99999 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)] PASS : tst_float::floatComparisons(should SUCCEED 2) diff --git a/tests/auto/testlib/selftests/expected_strcmp.lightxml b/tests/auto/testlib/selftests/expected_strcmp.lightxml index d5135fd7df..4c30c9f801 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.lightxml +++ b/tests/auto/testlib/selftests/expected_strcmp.lightxml @@ -35,13 +35,13 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="121"> <Description><![CDATA[Compared values are not the same Actual (QByteArray("foo")): 66 6F 6F - Expected (QByteArray()): ]]></Description> + Expected (QByteArray()) : ]]></Description> </Incident> </TestFunction> <TestFunction name="failByteArrayEmpty"> <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="126"> <Description><![CDATA[Compared values are not the same - Actual (QByteArray("")): + Actual (QByteArray("")) : Expected (QByteArray("foo")): 66 6F 6F]]></Description> </Incident> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_strcmp.txt b/tests/auto/testlib/selftests/expected_strcmp.txt index 797aefa82f..f3ad169fb7 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.txt +++ b/tests/auto/testlib/selftests/expected_strcmp.txt @@ -18,10 +18,10 @@ FAIL! : tst_StrCmp::failByteArray() Compared values are not the same Loc: [./tst_strcmp.cpp(82)] FAIL! : tst_StrCmp::failByteArrayNull() Compared values are not the same Actual (QByteArray("foo")): 66 6F 6F - Expected (QByteArray()): + Expected (QByteArray()) : Loc: [./tst_strcmp.cpp(88)] FAIL! : tst_StrCmp::failByteArrayEmpty() Compared values are not the same - Actual (QByteArray("")): + Actual (QByteArray("")) : Expected (QByteArray("foo")): 66 6F 6F Loc: [./tst_strcmp.cpp(93)] FAIL! : tst_StrCmp::failByteArraySingleChars() Compared values are not the same diff --git a/tests/auto/testlib/selftests/expected_strcmp.xml b/tests/auto/testlib/selftests/expected_strcmp.xml index 0c5a73918d..db9ed34bb8 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.xml +++ b/tests/auto/testlib/selftests/expected_strcmp.xml @@ -37,13 +37,13 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="121"> <Description><![CDATA[Compared values are not the same Actual (QByteArray("foo")): 66 6F 6F - Expected (QByteArray()): ]]></Description> + Expected (QByteArray()) : ]]></Description> </Incident> </TestFunction> <TestFunction name="failByteArrayEmpty"> <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="126"> <Description><![CDATA[Compared values are not the same - Actual (QByteArray("")): + Actual (QByteArray("")) : Expected (QByteArray("foo")): 66 6F 6F]]></Description> </Incident> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_strcmp.xunitxml b/tests/auto/testlib/selftests/expected_strcmp.xunitxml index a900e2f17a..dde9ff5299 100644 --- a/tests/auto/testlib/selftests/expected_strcmp.xunitxml +++ b/tests/auto/testlib/selftests/expected_strcmp.xunitxml @@ -22,11 +22,11 @@ <testcase result="fail" name="failByteArrayNull"> <failure message="Compared values are not the same Actual (QByteArray("foo")): 66 6F 6F - Expected (QByteArray()): " result="fail"/> + Expected (QByteArray()) : " result="fail"/> </testcase> <testcase result="fail" name="failByteArrayEmpty"> <failure message="Compared values are not the same - Actual (QByteArray("")): + Actual (QByteArray("")) : Expected (QByteArray("foo")): 66 6F 6F" result="fail"/> </testcase> <testcase result="fail" name="failByteArraySingleChars"> diff --git a/tests/auto/testlib/selftests/expected_subtest.lightxml b/tests/auto/testlib/selftests/expected_subtest.lightxml index b156dc3991..5adbb771af 100644 --- a/tests/auto/testlib/selftests/expected_subtest.lightxml +++ b/tests/auto/testlib/selftests/expected_subtest.lightxml @@ -122,7 +122,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154"> <DataTag><![CDATA[data1]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (str): hello1 + Actual (str) : hello1 Expected (QString("hello0")): hello0]]></Description> </Incident> <Message type="qdebug" file="" line="0"> @@ -140,7 +140,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154"> <DataTag><![CDATA[data2]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (str): hello2 + Actual (str) : hello2 Expected (QString("hello0")): hello0]]></Description> </Incident> <Message type="qdebug" file="" line="0"> diff --git a/tests/auto/testlib/selftests/expected_subtest.txt b/tests/auto/testlib/selftests/expected_subtest.txt index 4537f983e5..bb88f189ec 100644 --- a/tests/auto/testlib/selftests/expected_subtest.txt +++ b/tests/auto/testlib/selftests/expected_subtest.txt @@ -33,14 +33,14 @@ PASS : tst_Subtest::test3(data0) QDEBUG : tst_Subtest::test3(data1) init test3 data1 QDEBUG : tst_Subtest::test3(data1) test2 test3 data1 FAIL! : tst_Subtest::test3(data1) Compared values are not the same - Actual (str): hello1 + Actual (str) : hello1 Expected (QString("hello0")): hello0 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp(154)] QDEBUG : tst_Subtest::test3(data1) cleanup test3 data1 QDEBUG : tst_Subtest::test3(data2) init test3 data2 QDEBUG : tst_Subtest::test3(data2) test2 test3 data2 FAIL! : tst_Subtest::test3(data2) Compared values are not the same - Actual (str): hello2 + Actual (str) : hello2 Expected (QString("hello0")): hello0 Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp(154)] QDEBUG : tst_Subtest::test3(data2) cleanup test3 data2 diff --git a/tests/auto/testlib/selftests/expected_subtest.xml b/tests/auto/testlib/selftests/expected_subtest.xml index 365df51e23..094e22383d 100644 --- a/tests/auto/testlib/selftests/expected_subtest.xml +++ b/tests/auto/testlib/selftests/expected_subtest.xml @@ -124,7 +124,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154"> <DataTag><![CDATA[data1]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (str): hello1 + Actual (str) : hello1 Expected (QString("hello0")): hello0]]></Description> </Incident> <Message type="qdebug" file="" line="0"> @@ -142,7 +142,7 @@ <Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154"> <DataTag><![CDATA[data2]]></DataTag> <Description><![CDATA[Compared values are not the same - Actual (str): hello2 + Actual (str) : hello2 Expected (QString("hello0")): hello0]]></Description> </Incident> <Message type="qdebug" file="" line="0"> diff --git a/tests/auto/testlib/selftests/expected_subtest.xunitxml b/tests/auto/testlib/selftests/expected_subtest.xunitxml index 6097000e7f..6f8fc3db45 100644 --- a/tests/auto/testlib/selftests/expected_subtest.xunitxml +++ b/tests/auto/testlib/selftests/expected_subtest.xunitxml @@ -38,13 +38,13 @@ <!-- tag="data1" message="init test3 data1 " type="qdebug" --> <!-- tag="data1" message="test2 test3 data1 " type="qdebug" --> <failure tag="data1" message="Compared values are not the same - Actual (str): hello1 + Actual (str) : hello1 Expected (QString("hello0")): hello0" result="fail"/> <!-- tag="data1" message="cleanup test3 data1 " type="qdebug" --> <!-- tag="data2" message="init test3 data2 " type="qdebug" --> <!-- tag="data2" message="test2 test3 data2 " type="qdebug" --> <failure tag="data2" message="Compared values are not the same - Actual (str): hello2 + Actual (str) : hello2 Expected (QString("hello0")): hello0" result="fail"/> <!-- tag="data2" message="cleanup test3 data2 " type="qdebug" --> </testcase> diff --git a/tests/auto/dbus/qdbusabstractinterface/pinger.cpp b/tests/auto/tools/moc/interface-from-include.h index be4fc30409..ef8d53684b 100644 --- a/tests/auto/dbus/qdbusabstractinterface/pinger.cpp +++ b/tests/auto/tools/moc/interface-from-include.h @@ -3,7 +3,7 @@ ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** -** This file is part of the QtDBus module of the Qt Toolkit. +** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage @@ -38,30 +38,18 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#ifndef INTERFACE_FROM_INCLUDE_H +#define INTERFACE_FROM_INCLUDE_H -/* - * This file was generated by qdbusxml2cpp version 0.7 - * Command line was: qdbusxml2cpp -i interface.h -p pinger org.qtproject.QtDBus.Pinger.xml - * - * qdbusxml2cpp is Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). - * - * This is an auto-generated file. - * This file may have been hand-edited. Look for HAND-EDIT comments - * before re-generating it. - */ +#include <testinterface.h> -#include "pinger.h" - -/* - * Implementation of interface class ComTrolltechQtDBusPingerInterface - */ - -ComTrolltechQtDBusPingerInterface::ComTrolltechQtDBusPingerInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +class TestComponent : public QObject, public TestInterface { -} + Q_OBJECT + Q_INTERFACES(TestInterface) +public: -ComTrolltechQtDBusPingerInterface::~ComTrolltechQtDBusPingerInterface() -{ -} + virtual void foobar() { } +}; +#endif diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 3459bede85..e7303d716e 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -523,6 +523,7 @@ private slots: void structQObject(); void namespacedFlags(); void warnOnMultipleInheritance(); + void ignoreOptionClashes(); void forgottenQInterface(); void os9Newline(); void winNewline(); @@ -969,6 +970,46 @@ void tst_Moc::warnOnMultipleInheritance() #endif } +void tst_Moc::ignoreOptionClashes() +{ +#ifdef MOC_CROSS_COMPILED + QSKIP("Not tested when cross-compiled"); +#endif +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) + QProcess proc; + QStringList args; + const QString header = m_sourceDirectory + QStringLiteral("/interface-from-include.h"); + const QString includeDir = m_sourceDirectory + "/Test.framework/Headers"; + // given --ignore-option-clashes, -pthread should be ignored, but the -I path should not be. + args << "--ignore-option-clashes" << "-pthread" << "-I" << includeDir << "-fno-builtin" << header; + proc.start("moc", args); + bool finished = proc.waitForFinished(); + if (!finished) + qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); + QVERIFY(finished); + if (proc.exitCode() != 0) { + qDebug() << proc.readAllStandardError(); + } + QCOMPARE(proc.exitCode(), 0); + QCOMPARE(proc.readAllStandardError(), QByteArray()); + QByteArray mocOut = proc.readAllStandardOutput(); + + // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation. + QStringList gccArgs; + gccArgs << "-c" << "-x" << "c++" << "-I" << ".." + << "-I" << qtIncludePath << "-I" << includeDir << "-o" << "/dev/null" << "-fPIE" << "-"; + proc.start("gcc", gccArgs); + QVERIFY(proc.waitForStarted()); + proc.write(mocOut); + proc.closeWriteChannel(); + + QVERIFY(proc.waitForFinished()); + QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); +#else + QSKIP("Only tested on linux/gcc"); +#endif +} + void tst_Moc::forgottenQInterface() { #ifdef MOC_CROSS_COMPILED diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index 65d36247f6..81b69f6b89 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -612,6 +612,8 @@ void tst_QFiledialog::defaultSuffix() QCOMPARE(fd.defaultSuffix(), QString()); fd.setDefaultSuffix("txt"); QCOMPARE(fd.defaultSuffix(), QString("txt")); + fd.setDefaultSuffix(".txt"); + QCOMPARE(fd.defaultSuffix(), QString("txt")); fd.setDefaultSuffix(QString()); QCOMPARE(fd.defaultSuffix(), QString()); } @@ -1334,6 +1336,38 @@ QString saveName(QWidget *, const QString &, const QString &, const QString &, Q return "saveName"; } +QT_BEGIN_NAMESPACE +typedef QUrl (*_qt_filedialog_existing_directory_url_hook)(QWidget *parent, const QString &caption, const QUrl &dir, QFileDialog::Options options, const QStringList &supportedSchemes); +extern Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_url_hook qt_filedialog_existing_directory_url_hook; +QT_END_NAMESPACE +QUrl existingUrl(QWidget *, const QString &, const QUrl &, QFileDialog::Options, const QStringList &) { + return QUrl("http://dirUrl"); +} + +QT_BEGIN_NAMESPACE +typedef QUrl (*_qt_filedialog_open_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes); +extern Q_WIDGETS_EXPORT _qt_filedialog_open_file_url_hook qt_filedialog_open_file_url_hook; +QT_END_NAMESPACE +QUrl openUrl(QWidget *, const QString &, const QUrl &, const QString &, QString *, QFileDialog::Options, const QStringList &) { + return QUrl("http://openUrl"); +} + +QT_BEGIN_NAMESPACE +typedef QList<QUrl> (*_qt_filedialog_open_file_urls_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes); +extern Q_WIDGETS_EXPORT _qt_filedialog_open_file_urls_hook qt_filedialog_open_file_urls_hook; +QT_END_NAMESPACE +QList<QUrl> openUrls(QWidget *, const QString &, const QUrl &, const QString &, QString *, QFileDialog::Options, const QStringList &) { + return QList<QUrl>() << QUrl("http://openUrls"); +} + +QT_BEGIN_NAMESPACE +typedef QUrl (*_qt_filedialog_save_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes); +extern Q_WIDGETS_EXPORT _qt_filedialog_save_file_url_hook qt_filedialog_save_file_url_hook; +QT_END_NAMESPACE +QUrl saveUrl(QWidget *, const QString &, const QUrl &, const QString &, QString *, QFileDialog::Options, const QStringList &) { + return QUrl("http://saveUrl"); +} + void tst_QFiledialog::hooks() { @@ -1346,6 +1380,20 @@ void tst_QFiledialog::hooks() QCOMPARE(QFileDialog::getOpenFileName(), QString("openName")); QCOMPARE(QFileDialog::getOpenFileNames(), QStringList("openNames")); QCOMPARE(QFileDialog::getSaveFileName(), QString("saveName")); + QCOMPARE(QFileDialog::getExistingDirectoryUrl(), QUrl::fromLocalFile("dir")); + QCOMPARE(QFileDialog::getOpenFileUrl(), QUrl::fromLocalFile("openName")); + QCOMPARE(QFileDialog::getOpenFileUrls(), QList<QUrl>() << QUrl::fromLocalFile("openNames")); + QCOMPARE(QFileDialog::getSaveFileUrl(), QUrl::fromLocalFile("saveName")); + + qt_filedialog_existing_directory_url_hook = &existingUrl; + qt_filedialog_save_file_url_hook = &saveUrl; + qt_filedialog_open_file_url_hook = &openUrl; + qt_filedialog_open_file_urls_hook = &openUrls; + + QCOMPARE(QFileDialog::getExistingDirectoryUrl(), QUrl("http://dirUrl")); + QCOMPARE(QFileDialog::getOpenFileUrl(), QUrl("http://openUrl")); + QCOMPARE(QFileDialog::getOpenFileUrls(), QList<QUrl>() << QUrl("http://openUrls")); + QCOMPARE(QFileDialog::getSaveFileUrl(), QUrl("http://saveUrl")); } #ifdef Q_OS_UNIX diff --git a/tests/auto/widgets/graphicsview/graphicsview.pro b/tests/auto/widgets/graphicsview/graphicsview.pro index 9955e45b64..dce3c6dda9 100644 --- a/tests/auto/widgets/graphicsview/graphicsview.pro +++ b/tests/auto/widgets/graphicsview/graphicsview.pro @@ -26,7 +26,7 @@ SUBDIRS=\ qgraphicsscene \ qgraphicssceneindex \ -# These tests require the cleanlooks style -!contains(styles, cleanlooks):SUBDIRS -= \ +# These tests require the fusion style +!contains(styles, fusion):SUBDIRS -= \ qgraphicsproxywidget \ qgraphicswidget \ diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro index 3eb18e61eb..8e8c0708a3 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/qgraphicsanchorlayout.pro @@ -3,4 +3,3 @@ TARGET = tst_qgraphicsanchorlayout QT += widgets widgets-private testlib QT += core-private gui-private SOURCES += tst_qgraphicsanchorlayout.cpp -CONFIG += parallel_test diff --git a/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro b/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro index 4fe3405d11..550d3debf7 100644 --- a/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro +++ b/tests/auto/widgets/graphicsview/qgraphicseffectsource/qgraphicseffectsource.pro @@ -5,4 +5,3 @@ QT += widgets widgets-private testlib QT += core-private gui-private SOURCES += tst_qgraphicseffectsource.cpp -CONFIG += parallel_test diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro index 5796cbfd73..e49139a8ad 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro +++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/qgraphicsgridlayout.pro @@ -3,4 +3,3 @@ TARGET = tst_qgraphicsgridlayout QT += widgets testlib SOURCES += tst_qgraphicsgridlayout.cpp -CONFIG += parallel_test diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 8c8f27d635..1ffb5c3b5c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -126,6 +126,7 @@ private slots: void spanningItem2x3_data(); void spanningItem2x3(); void spanningItem(); + void spanAcrossEmptyRow(); void heightForWidth(); void widthForHeight(); void heightForWidthWithSpanning(); @@ -3192,23 +3193,19 @@ void tst_QGraphicsGridLayout::heightForWidthWithSpanning() QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, -1)), QSizeF(1, 1)); QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(-1, -1)), QSizeF(200, 100)); - QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue); QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(-1, -1)), QSizeF(30000, 30000)); QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(200, -1)), QSizeF(200, 100)); QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(200, -1)), QSizeF(200, 100)); - QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue); QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 100)); QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(2, -1)), QSizeF(2, 10000)); QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(2, -1)), QSizeF(2, 10000)); - QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue); QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(2, -1)), QSizeF(2, 10000)); QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize, QSizeF(200, -1)), QSizeF(200, 100)); QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize, QSizeF(200, -1)), QSizeF(200, 100)); - QEXPECT_FAIL("", "Due to an old bug this wrongly returns QWIDGETSIZE_MAX", Continue); - QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 10000)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize, QSizeF(200, -1)), QSizeF(200, 100)); } Q_DECLARE_METATYPE(QSizePolicy::Policy) @@ -3364,6 +3361,37 @@ void tst_QGraphicsGridLayout::spanningItem() QCOMPARE(layout->maximumSize(), QSizeF(160,80)); } +void tst_QGraphicsGridLayout::spanAcrossEmptyRow() +{ + QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window); + QGraphicsGridLayout *layout = new QGraphicsGridLayout(form); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + RectWidget *w1 = new RectWidget; + RectWidget *w2 = new RectWidget; + RectWidget *w3 = new RectWidget; + + QSizeF size(10, 10); + for (int i = 0; i < 3; ++i) { + w1->setSizeHint((Qt::SizeHint)i, size); + w2->setSizeHint((Qt::SizeHint)i, size); + w3->setSizeHint((Qt::SizeHint)i, size); + size+=size; //[(10,10), (20,20), (40,40)] + } + layout->addItem(w1, 0, 0, 1, 1); + layout->addItem(w2, 0, 1, 1, 2); + layout->addItem(w3, 0, 99, 1, 1); + + form->resize(60,20); + QCOMPARE(w1->geometry(), QRectF( 0, 0, 20, 20)); + QCOMPARE(w2->geometry(), QRectF(20, 0, 20, 20)); + QCOMPARE(w3->geometry(), QRectF(40, 0, 20, 20)); + + QCOMPARE(layout->effectiveSizeHint(Qt::MinimumSize), QSizeF(30, 10)); + QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 20)); + QCOMPARE(layout->effectiveSizeHint(Qt::MaximumSize), QSizeF(120, 40)); +} + void tst_QGraphicsGridLayout::stretchAndHeightForWidth() { QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window); diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro index 50a886cece..2bf1a1d676 100644 --- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro +++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/qgraphicslinearlayout.pro @@ -2,5 +2,3 @@ CONFIG += testcase TARGET = tst_qgraphicslinearlayout QT += widgets testlib SOURCES += tst_qgraphicslinearlayout.cpp -CONFIG += parallel_test - diff --git a/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro b/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro index 5fd3bdf8d6..3d0d73566e 100644 --- a/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro +++ b/tests/auto/widgets/graphicsview/qgraphicssceneindex/qgraphicssceneindex.pro @@ -4,5 +4,4 @@ requires(contains(QT_CONFIG,private_tests)) QT += widgets widgets-private testlib QT += core-private gui-private SOURCES += tst_qgraphicssceneindex.cpp -CONFIG += parallel_test DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro b/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro index 4e119cbcb3..481bc96d96 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/qgraphicswidget.pro @@ -6,5 +6,4 @@ QT += core-private gui-private SOURCES += tst_qgraphicswidget.cpp -linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = lucid ]"):DEFINES+=UBUNTU_LUCID # QTBUG-20778 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index 31439e203c..2dd2089f81 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -3194,9 +3194,6 @@ void tst_QGraphicsWidget::initialShow2() qApp->setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); -#ifdef UBUNTU_LUCID - QEXPECT_FAIL("", "QTBUG-20778", Abort); -#endif QTRY_COMPARE(widget->repaints, expectedRepaintCount); } diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 8e888f06ee..dfb780c8fa 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -106,6 +106,8 @@ private slots: void moveCursorStrikesBack_data(); void moveCursorStrikesBack(); + void moveCursorBiggerJump(); + void hideRows_data(); void hideRows(); @@ -1354,6 +1356,34 @@ void tst_QTableView::moveCursorStrikesBack() QCOMPARE(newColumn, expectedColumn); } +void tst_QTableView::moveCursorBiggerJump() +{ + QtTestTableModel model(50, 7); + QTableView view; + view.setModel(&model); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + int height = view.horizontalHeader()->height(); + for (int i=0;i<8;i++) + height += view.verticalHeader()->sectionSize(i); + view.resize(view.width(), height); + view.setCurrentIndex(model.index(0,0)); + + QTest::keyClick(&view, Qt::Key_PageDown); + QCOMPARE(view.indexAt(QPoint(0,0)), model.index(1,0)); + QTest::keyClick(&view, Qt::Key_PageDown); + QCOMPARE(view.indexAt(QPoint(0,0)), model.index(8,0)); + QTest::keyClick(&view, Qt::Key_PageDown); + QCOMPARE(view.indexAt(QPoint(0,0)), model.index(15,0)); + QTest::keyClick(&view, Qt::Key_PageUp); + QCOMPARE(view.indexAt(QPoint(0,0)), model.index(14,0)); + QTest::keyClick(&view, Qt::Key_PageUp); + QCOMPARE(view.indexAt(QPoint(0,0)), model.index(7,0)); + QTest::keyClick(&view, Qt::Key_PageUp); + QCOMPARE(view.indexAt(QPoint(0,0)), model.index(0,0)); +} + void tst_QTableView::hideRows_data() { QTest::addColumn<int>("rowCount"); @@ -3762,8 +3792,6 @@ void tst_QTableView::task259308_scrollVerticalHeaderSwappedSections() QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0)); int newRow = tv.rowAt(tv.viewport()->height()); - if (newRow == tv.rowAt(tv.viewport()->height() - 1)) // Overlapping row - newRow++; QTest::keyClick(&tv, Qt::Key_PageDown); // Scroll down and check current QTRY_COMPARE(tv.currentIndex().row(), newRow); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 9a7b7956d8..dcda9f7fd7 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -2017,6 +2017,8 @@ void tst_QTreeView::clicked() view.setModel(&model); view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QModelIndex firstIndex = model.index(0, 0, QModelIndex()); QVERIFY(firstIndex.isValid()); int itemHeight = view.visualRect(firstIndex).height(); diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index 2b9b4fd761..ab2df2e250 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -84,6 +84,7 @@ private slots: void controlTypes(); void controlTypes2(); void adjustSizeShouldMakeSureLayoutIsActivated(); + void testRetainSizeWhenHidden(); }; tst_QLayout::tst_QLayout() @@ -350,5 +351,47 @@ void tst_QLayout::adjustSizeShouldMakeSureLayoutIsActivated() QCOMPARE(main.size(), QSize(200, 10)); } +void tst_QLayout::testRetainSizeWhenHidden() +{ + QWidget widget; + QBoxLayout layout(QBoxLayout::TopToBottom, &widget); + + QLabel *label1 = new QLabel("label1 text", &widget); + layout.addWidget(label1); + QLabel *label2 = new QLabel("label2 text", &widget); + layout.addWidget(label2); + + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + int normalHeight = widget.height(); + + // a. Verify that a removed visible will mean lesser size after adjust + label1->hide(); + widget.adjustSize(); + int heightWithoutLabel1 = widget.height(); + QVERIFY(heightWithoutLabel1 < normalHeight); + + // b restore with verify that the size is the same + label1->show(); + QCOMPARE(widget.sizeHint().height(), normalHeight); + + // c verify that a policy with retainSizeWhenHidden is respected + QSizePolicy sp_remove = label1->sizePolicy(); + QSizePolicy sp_retain = label1->sizePolicy(); + sp_retain.setRetainSizeWhenHidden(true); + + label1->setSizePolicy(sp_retain); + label1->hide(); + QCOMPARE(widget.sizeHint().height(), normalHeight); + + // d check that changing the policy to not wanting size will result in lesser size + label1->setSizePolicy(sp_remove); + QCOMPARE(widget.sizeHint().height(), heightWithoutLabel1); + + // e verify that changing back the hidden widget to want the hidden size will ensure that it gets more size + label1->setSizePolicy(sp_retain); + QCOMPARE(widget.sizeHint().height(), normalHeight); +} + QTEST_MAIN(tst_QLayout) #include "tst_qlayout.moc" diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 82d3fae0fa..4631154230 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -160,6 +160,7 @@ private slots: void maxVisibleItems(); void task_QTBUG_10491_currentIndexAndModelColumn(); void highlightedSignal(); + void itemData(); void task_QTBUG_31146_popupCompletion(); }; @@ -2756,6 +2757,151 @@ void tst_QComboBox::highlightedSignal() QCOMPARE(spy.size(), 1); } +void tst_QComboBox::itemData() +{ + QComboBox comboBox; + const int itemCount = 10; + + // ensure that the currentText(), the DisplayRole and the EditRole + // stay in sync when using QComboBox's default model + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("item text %1").arg(i); + comboBox.addItem(itemText); + } + + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("item text %1").arg(i); + QCOMPARE(comboBox.itemText(i), itemText); + QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText); + + comboBox.setCurrentIndex(i); + QCOMPARE(comboBox.currentIndex(), i); + QCOMPARE(comboBox.currentText(), itemText); + QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText); + } + + for (int i = 0; i < itemCount; ++i) { + // now change by using setItemText + QString itemText = QString("setItemText %1").arg(i); + comboBox.setItemText(i, itemText); + } + + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("setItemText %1").arg(i); + QCOMPARE(comboBox.itemText(i), itemText); + QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText); + + comboBox.setCurrentIndex(i); + QCOMPARE(comboBox.currentIndex(), i); + QCOMPARE(comboBox.currentText(), itemText); + QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText); + } + + for (int i = 0; i < itemCount; ++i) { + // now change by changing the DisplayRole's data + QString itemText = QString("setItemData(DisplayRole) %1").arg(i); + comboBox.setItemData(i, QVariant(itemText), Qt::DisplayRole); + } + + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("setItemData(DisplayRole) %1").arg(i); + QCOMPARE(comboBox.itemText(i), itemText); + QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText); + + comboBox.setCurrentIndex(i); + QCOMPARE(comboBox.currentIndex(), i); + QCOMPARE(comboBox.currentText(), itemText); + QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText); + } + + for (int i = 0; i < itemCount; ++i) { + // now change by changing the EditRole's data + QString itemText = QString("setItemData(EditRole) %1").arg(i); + comboBox.setItemData(i, QVariant(itemText), Qt::EditRole); + } + + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("setItemData(EditRole) %1").arg(i); + QCOMPARE(comboBox.itemText(i), itemText); + QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText); + + comboBox.setCurrentIndex(i); + QCOMPARE(comboBox.currentIndex(), i); + QCOMPARE(comboBox.currentText(), itemText); + QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText); + } + + comboBox.clear(); + + + // set additional user data in the addItem call + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("item text %1").arg(i); + QString itemDataText = QString("item data %1").arg(i); + comboBox.addItem(itemText, QVariant(itemDataText)); + } + + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("item text %1").arg(i); + QString itemDataText = QString("item data %1").arg(i); + QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i).toString(), itemDataText); + + comboBox.setCurrentIndex(i); + QCOMPARE(comboBox.currentIndex(), i); + QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText); + QCOMPARE(comboBox.currentData().toString(), itemDataText); + + } + + comboBox.clear(); + + + // additional roles, setItemData + // UserRole + 0 -> string + // UserRole + 1 -> double + // UserRole + 2 -> icon + QString qtlogoPath = QFINDTESTDATA("qtlogo.png"); + QIcon icon = QIcon(QPixmap(qtlogoPath)); + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("item text %1").arg(i); + QString itemDataText = QString("item data %1").arg(i); + double d = i; + comboBox.addItem(itemText); + comboBox.setItemData(i, QVariant(itemDataText), Qt::UserRole); + comboBox.setItemData(i, QVariant(d), Qt::UserRole + 1); + comboBox.setItemData(i, QVariant::fromValue(icon), Qt::UserRole + 2); + } + + for (int i = 0; i < itemCount; ++i) { + QString itemText = QString("item text %1").arg(i); + QString itemDataText = QString("item data %1").arg(i); + double d = i; + QCOMPARE(comboBox.itemData(i, Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::EditRole).toString(), itemText); + QCOMPARE(comboBox.itemData(i, Qt::UserRole).toString(), itemDataText); + QCOMPARE(comboBox.itemData(i, Qt::UserRole + 1).toDouble(), d); + QCOMPARE(comboBox.itemData(i, Qt::UserRole + 2).value<QIcon>(), icon); + + comboBox.setCurrentIndex(i); + QCOMPARE(comboBox.currentData(Qt::DisplayRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::EditRole).toString(), itemText); + QCOMPARE(comboBox.currentData(Qt::UserRole).toString(), itemDataText); + QCOMPARE(comboBox.currentData(Qt::UserRole + 1).toDouble(), d); + QCOMPARE(comboBox.currentData(Qt::UserRole + 2).value<QIcon>(), icon); + } +} + void tst_QComboBox::task_QTBUG_31146_popupCompletion() { QComboBox comboBox; diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index b0e454b643..db5b89f396 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -72,6 +72,8 @@ private slots: void testConstructor2_data(); void testConstructor3(); void testConstructor3_data(); + void testConstructor4(); + void testConstructor4_data(); void setOrientation_data(); void setOrientation(); void addButton1_data(); @@ -201,6 +203,41 @@ void tst_QDialogButtonBox::testConstructor3() QTEST(buttonBox.buttons().count(), "buttonCount"); } +void tst_QDialogButtonBox::testConstructor4_data() +{ + QTest::addColumn<QDialogButtonBox::StandardButtons>("buttons"); + QTest::addColumn<int>("buttonCount"); + + QTest::newRow("nothing") << (QDialogButtonBox::StandardButtons)0 << 0; + QTest::newRow("only 1") << QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok) << 1; + QTest::newRow("only 1.. twice") + << (QDialogButtonBox::Ok | QDialogButtonBox::Ok) + << 1; + QTest::newRow("only 2") + << (QDialogButtonBox::Ok | QDialogButtonBox::Cancel) + << 2; + QTest::newRow("two different things") + << (QDialogButtonBox::Save | QDialogButtonBox::Close) + << 2; + QTest::newRow("three") + << (QDialogButtonBox::Ok + | QDialogButtonBox::Cancel + | QDialogButtonBox::Help) + << 3; + QTest::newRow("everything") + << (QDialogButtonBox::StandardButtons)UINT_MAX + << 18; +} + +void tst_QDialogButtonBox::testConstructor4() +{ + QFETCH(QDialogButtonBox::StandardButtons, buttons); + + QDialogButtonBox buttonBox(buttons); + QCOMPARE(buttonBox.orientation(), Qt::Horizontal); + QTEST(buttonBox.buttons().count(), "buttonCount"); +} + void tst_QDialogButtonBox::setOrientation_data() { QTest::addColumn<int>("orientation"); diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index d428e2705d..3000aad9ce 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -46,6 +46,9 @@ #include "qstringlist.h" #include "qstyle.h" #include "qvalidator.h" +#include "qwidgetaction.h" +#include "qimage.h" +#include "qicon.h" #include "qcompleter.h" #include "qstandarditemmodel.h" #include <qpa/qplatformtheme.h> @@ -61,8 +64,12 @@ #include <private/qlineedit_p.h> #include <private/qwidgetlinecontrol_p.h> #include <qmenu.h> +#include <qlabel.h> #include <qlayout.h> #include <qspinbox.h> +#include <qlistview.h> +#include <qstringlistmodel.h> +#include <qsortfilterproxymodel.h> #include <qdebug.h> #include "qcommonstyle.h" @@ -290,6 +297,9 @@ private slots: void undoRedoAndEchoModes_data(); void undoRedoAndEchoModes(); + void clearButton(); + void sideWidgets(); + protected slots: void editingFinished(); @@ -866,12 +876,18 @@ public: void tst_QLineEdit::hasAcceptableInputValidator() { + QSignalSpy spyChanged(testWidget, SIGNAL(textChanged(QString))); + QSignalSpy spyEdited(testWidget, SIGNAL(textEdited(QString))); + QFocusEvent lostFocus(QEvent::FocusOut); ValidatorWithFixup val; testWidget->setValidator(&val); testWidget->setText("foobar"); qApp->sendEvent(testWidget, &lostFocus); QVERIFY(testWidget->hasAcceptableInput()); + + QCOMPARE(spyChanged.count(), 2); + QCOMPARE(spyEdited.count(), 0); } @@ -4042,5 +4058,80 @@ void tst_QLineEdit::undoRedoAndEchoModes() QCOMPARE(testWidget->text(), expected.at(2)); } +void tst_QLineEdit::clearButton() +{ + // Construct a listview with a stringlist model and filter model. + QWidget testWidget; + QVBoxLayout *l = new QVBoxLayout(&testWidget); + QLineEdit *filterLineEdit = new QLineEdit(&testWidget); + l->addWidget(filterLineEdit); + QListView *listView = new QListView(&testWidget); + QStringListModel *model = new QStringListModel(QStringList() << QStringLiteral("aa") << QStringLiteral("ab") << QStringLiteral("cc"), listView); + QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(listView); + filterModel->setSourceModel(model); + connect(filterLineEdit, SIGNAL(textChanged(QString)), filterModel, SLOT(setFilterFixedString(QString))); + listView->setModel(filterModel); + l->addWidget(listView); + testWidget.move(300, 300); + testWidget.show(); + qApp->setActiveWindow(&testWidget); + QVERIFY(QTest::qWaitForWindowActive(&testWidget)); + // Flip the clear button on,off, trying to detect crashes. + filterLineEdit->setClearButtonEnabled(true); + QVERIFY(filterLineEdit->isClearButtonEnabled()); + filterLineEdit->setClearButtonEnabled(true); + QVERIFY(filterLineEdit->isClearButtonEnabled()); + filterLineEdit->setClearButtonEnabled(false); + QVERIFY(!filterLineEdit->isClearButtonEnabled()); + filterLineEdit->setClearButtonEnabled(false); + QVERIFY(!filterLineEdit->isClearButtonEnabled()); + filterLineEdit->setClearButtonEnabled(true); + QVERIFY(filterLineEdit->isClearButtonEnabled()); + // Emulate filtering + QToolButton *clearButton = filterLineEdit->findChild<QToolButton *>(); + QVERIFY(clearButton); + QCOMPARE(filterModel->rowCount(), 3); + QTest::keyClick(filterLineEdit, 'a'); + QTRY_COMPARE(filterModel->rowCount(), 2); // matches 'aa', 'ab' + QTest::keyClick(filterLineEdit, 'b'); + QTRY_COMPARE(filterModel->rowCount(), 1); // matches 'ab' + QTest::mouseClick(clearButton, Qt::LeftButton, 0, QRect(QPoint(0, 0), clearButton->size()).center()); + QTRY_COMPARE(filterModel->rowCount(), 3); +} + +void tst_QLineEdit::sideWidgets() +{ + QWidget testWidget; + QVBoxLayout *l = new QVBoxLayout(&testWidget); + QLineEdit *lineEdit = new QLineEdit(&testWidget); + l->addWidget(lineEdit); + l->addSpacerItem(new QSpacerItem(0, 50, QSizePolicy::Ignored, QSizePolicy::Fixed)); + QImage image(QSize(20, 20), QImage::Format_ARGB32); + image.fill(Qt::yellow); + QAction *iconAction = new QAction(QIcon(QPixmap::fromImage(image)), QString(), lineEdit); + QWidgetAction *label1Action = new QWidgetAction(lineEdit); + label1Action->setDefaultWidget(new QLabel(QStringLiteral("l1"))); + QWidgetAction *label2Action = new QWidgetAction(lineEdit); + label2Action->setDefaultWidget(new QLabel(QStringLiteral("l2"))); + QWidgetAction *label3Action = new QWidgetAction(lineEdit); + label3Action->setDefaultWidget(new QLabel(QStringLiteral("l3"))); + lineEdit->addAction(iconAction, QLineEdit::LeadingPosition); + lineEdit->addAction(label2Action, QLineEdit::LeadingPosition); + lineEdit->addAction(label1Action, QLineEdit::TrailingPosition); + lineEdit->addAction(label3Action, QLineEdit::TrailingPosition); + testWidget.move(300, 300); + testWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&testWidget)); + // Arbitrarily add/remove actions, trying to detect crashes. Add QTRY_VERIFY(false) to view the result. + delete label3Action; + lineEdit->removeAction(label2Action); + lineEdit->removeAction(iconAction); + lineEdit->removeAction(label1Action); + lineEdit->removeAction(iconAction); + lineEdit->removeAction(label1Action); + lineEdit->addAction(iconAction); + lineEdit->addAction(iconAction); +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index a64b34c56a..004fdda5ef 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -98,6 +98,9 @@ private slots: void setValue_data(); void setValue(); + void setDisplayIntegerBase_data(); + void setDisplayIntegerBase(); + void setPrefixSuffix_data(); void setPrefixSuffix(); @@ -274,6 +277,61 @@ void tst_QSpinBox::setValue() QCOMPARE(spin.value(), expected); } +void tst_QSpinBox::setDisplayIntegerBase_data() +{ + QTest::addColumn<int>("value"); + QTest::addColumn<int>("base"); + QTest::addColumn<QString>("string"); + + QTest::newRow("base 10") << 42 << 10 << "42"; + QTest::newRow("base 2") << 42 << 2 << "101010"; + QTest::newRow("base 8") << 42 << 8 << "52"; + QTest::newRow("base 16") << 42 << 16 << "2a"; + QTest::newRow("base 0") << 42 << 0 << "42"; + QTest::newRow("base -4") << 42 << -4 << "42"; + QTest::newRow("base 40") << 42 << 40 << "42"; + + QTest::newRow("negative base 10") << -42 << 10 << "-42"; + QTest::newRow("negative base 2") << -42 << 2 << "-101010"; + QTest::newRow("negative base 8") << -42 << 8 << "-52"; + QTest::newRow("negative base 16") << -42 << 16 << "-2a"; + QTest::newRow("negative base 0") << -42 << 0 << "-42"; + QTest::newRow("negative base -4") << -42 << -4 << "-42"; + QTest::newRow("negative base 40") << -42 << 40 << "-42"; + + QTest::newRow("0 base 10") << 0 << 10 << "0"; + QTest::newRow("0 base 2") << 0 << 2 << "0"; + QTest::newRow("0 base 8") << 0 << 8 << "0"; + QTest::newRow("0 base 16") << 0 << 16 << "0"; + QTest::newRow("0 base 0") << 0 << 0 << "0"; + QTest::newRow("0 base -4") << 0 << -4 << "0"; + QTest::newRow("0 base 40") << 0 << 40 << "0"; +} + +void tst_QSpinBox::setDisplayIntegerBase() +{ + QFETCH(int, value); + QFETCH(int, base); + QFETCH(QString, string); + + SpinBox spin; + spin.setRange(INT_MIN, INT_MAX); + + spin.setValue(value); + QCOMPARE(spin.lineEdit()->text(), QString::number(value)); + + spin.setDisplayIntegerBase(base); + QCOMPARE(spin.lineEdit()->text(), string); + + spin.setValue(0); + QCOMPARE(spin.value(), 0); + QCOMPARE(spin.lineEdit()->text(), QString::number(0, base)); + + spin.lineEdit()->clear(); + QTest::keyClicks(spin.lineEdit(), string); + QCOMPARE(spin.value(), value); +} + void tst_QSpinBox::setPrefixSuffix_data() { QTest::addColumn<QString>("prefix"); diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index a188e3bfe1..0dac7d85e4 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -97,6 +97,8 @@ private slots: void changeTitleWhileDoubleClickingTab(); void taskQTBUG_10052_widgetLayoutWhenMoving(); + + void tabBarClicked(); }; // Testing get/set functions @@ -652,5 +654,45 @@ void tst_QTabBar::taskQTBUG_10052_widgetLayoutWhenMoving() QVERIFY(w2.moved); } +void tst_QTabBar::tabBarClicked() +{ + QTabBar tabBar; + tabBar.addTab("0"); + QSignalSpy clickSpy(&tabBar, SIGNAL(tabBarClicked(int))); + QSignalSpy doubleClickSpy(&tabBar, SIGNAL(tabBarDoubleClicked(int))); + + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + Qt::MouseButton button = Qt::LeftButton; + while (button <= Qt::MaxMouseButton) { + const QPoint tabPos = tabBar.tabRect(0).center(); + + QTest::mouseClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0); + + const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y()); + + QTest::mouseClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1); + + button = Qt::MouseButton(button << 1); + } +} + QTEST_MAIN(tst_QTabBar) #include "tst_qtabbar.moc" diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index 5dd9ee9b0f..fa518e6afd 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -42,6 +42,7 @@ #include <QtTest/QtTest> #include <qtabwidget.h> +#include <qtabbar.h> #include <qdebug.h> #include <qapplication.h> #include <qlabel.h> @@ -110,6 +111,7 @@ class tst_QTabWidget:public QObject { void minimumSizeHint(); void heightForWidth_data(); void heightForWidth(); + void tabBarClicked(); private: int addPage(); @@ -666,6 +668,46 @@ void tst_QTabWidget::heightForWidth() delete window; } +void tst_QTabWidget::tabBarClicked() +{ + QTabWidget tabWidget; + tabWidget.addTab(new QWidget(&tabWidget), "0"); + QSignalSpy clickSpy(&tabWidget, SIGNAL(tabBarClicked(int))); + QSignalSpy doubleClickSpy(&tabWidget, SIGNAL(tabBarDoubleClicked(int))); + + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + QTabBar &tabBar = *tabWidget.tabBar(); + Qt::MouseButton button = Qt::LeftButton; + while (button <= Qt::MaxMouseButton) { + const QPoint tabPos = tabBar.tabRect(0).center(); + + QTest::mouseClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), 0); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, tabPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), 0); + + const QPoint barPos(tabBar.tabRect(0).right() + 5, tabBar.tabRect(0).center().y()); + + QTest::mouseClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 1); + QCOMPARE(clickSpy.takeFirst().takeFirst().toInt(), -1); + QCOMPARE(doubleClickSpy.count(), 0); + + QTest::mouseDClick(&tabBar, button, 0, barPos); + QCOMPARE(clickSpy.count(), 0); + QCOMPARE(doubleClickSpy.count(), 1); + QCOMPARE(doubleClickSpy.takeFirst().takeFirst().toInt(), -1); + + button = Qt::MouseButton(button << 1); + } +} QTEST_MAIN(tst_QTabWidget) #include "tst_qtabwidget.moc" diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp index ef5fd36254..0beffebfb7 100644 --- a/tests/benchmarks/corelib/io/qfile/main.cpp +++ b/tests/benchmarks/corelib/io/qfile/main.cpp @@ -54,6 +54,10 @@ # include <windows.h> #endif +#if defined(Q_OS_QNX) && defined(open) +#undef open +#endif + #define BUFSIZE 1024*512 #define FACTOR 1024*512 #define TF_SIZE FACTOR*81 diff --git a/tests/benchmarks/corelib/tools/qset/main.cpp b/tests/benchmarks/corelib/tools/qset/main.cpp new file mode 100644 index 0000000000..744cc745d3 --- /dev/null +++ b/tests/benchmarks/corelib/tools/qset/main.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QSet> +#include <QTest> + +class tst_QSet : public QObject +{ + Q_OBJECT + +private slots: + void intersect_int_data(); + void intersect_int(); + void intersect_complexType_data(); + void intersect_complexType(); +}; + +void tst_QSet::intersect_int_data() +{ + QTest::addColumn<int>("lhsSize"); + QTest::addColumn<int>("rhsSize"); + QTest::addColumn<int>("intersectSize"); + + QTest::newRow("1000000.intersect(1000) = empty") << 1000000 << 1000 << 0; + QTest::newRow("1000.intersect(1000000) = empty") << 1000 << 1000000 << 0; + QTest::newRow("1000000.intersect(1000) = 500") << 1000000 << 1000 << 500; + QTest::newRow("1000.intersect(1000000) = 500") << 1000 << 1000000 << 500; + QTest::newRow("1000000.intersect(1000) = 1000") << 1000000 << 1000 << 1000; + QTest::newRow("1000.intersect(1000000) = 1000") << 1000 << 1000000 << 1000; +} + +void tst_QSet::intersect_int() +{ + QFETCH(int, lhsSize); + QFETCH(int, rhsSize); + QFETCH(int, intersectSize); + + // E.g. when lhsSize = 1000, rhsSize = 1000000 and intersectSize = 500: + // lhsSize = { 0, 1, ... 1000 } + // rhsSize = { 500, 501, ... 1000500 } + + QSet<int> lhs; + for (int i = 0; i < lhsSize; ++i) + lhs.insert(i); + + QSet<int> rhs; + const int start = lhsSize - intersectSize; + for (int i = start; i < start + rhsSize; ++i) + rhs.insert(i); + + QBENCHMARK { + lhs.intersect(rhs); + } + + QVERIFY(lhs.size() == intersectSize); +} + +struct ComplexType +{ + ComplexType(int a) : a(a) {} + int a; + int b; + int c; +}; + +inline uint qHash(const ComplexType &key, uint seed = 0) +{ + return uint(key.a) ^ seed; +} + +inline bool operator==(const ComplexType &lhs, const ComplexType &rhs) +{ + return lhs.a == rhs.a; +} + +void tst_QSet::intersect_complexType_data() +{ + intersect_int_data(); +} + +void tst_QSet::intersect_complexType() +{ + QFETCH(int, lhsSize); + QFETCH(int, rhsSize); + QFETCH(int, intersectSize); + + QSet<ComplexType> lhs; + for (int i = 0; i < lhsSize; ++i) + lhs.insert(ComplexType(i)); + + QSet<ComplexType> rhs; + const int start = lhsSize - intersectSize; + for (int i = start; i < start + rhsSize; ++i) + rhs.insert(ComplexType(i)); + + QBENCHMARK { + lhs.intersect(rhs); + } +} + +QTEST_MAIN(tst_QSet) + +#include "main.moc" diff --git a/tests/benchmarks/corelib/tools/qset/qset.pro b/tests/benchmarks/corelib/tools/qset/qset.pro new file mode 100644 index 0000000000..8fb8bcfa0b --- /dev/null +++ b/tests/benchmarks/corelib/tools/qset/qset.pro @@ -0,0 +1,4 @@ +TARGET = tst_qset +QT = core testlib +SOURCES += main.cpp +CONFIG += release diff --git a/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp b/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp index c32ff0d099..b590269b70 100644 --- a/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/benchmarks/gui/itemviews/qtableview/tst_qtableview.cpp @@ -44,6 +44,8 @@ #include <QTableView> #include <QImage> #include <QPainter> +#include <QHeaderView> +#include <QStandardItemModel> class QtTestTableModel: public QAbstractTableModel { @@ -149,6 +151,7 @@ private slots: void columnInsertion(); void columnRemoval_data(); void columnRemoval(); + void sizeHintForColumnWhenHidden(); private: static inline void spanInit_helper(QTableView *); }; @@ -361,5 +364,23 @@ void tst_QTableView::columnRemoval() } } +void tst_QTableView::sizeHintForColumnWhenHidden() +{ + QTableView view; + QStandardItemModel model(12500, 6); + for (int r = 0; r < model.rowCount(); ++r) + for (int c = 0; c < model.columnCount(); ++c) { + QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(r).arg(c)); + model.setItem(r, c, item); + } + + view.horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + view.setModel(&model); + QBENCHMARK_ONCE { + view.horizontalHeader()->resizeSection(0, 10); // this force resizeSections - on a hidden view. + } + +} + QTEST_MAIN(tst_QTableView) #include "tst_qtableview.moc" diff --git a/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro b/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro index 7031b83210..92d20f50d0 100644 --- a/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro +++ b/tests/benchmarks/network/access/qnetworkreply/qnetworkreply.pro @@ -2,7 +2,7 @@ TEMPLATE = app TARGET = tst_bench_qnetworkreply QT -= gui -QT += network testlib +QT += core-private network network-private testlib CONFIG += release diff --git a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp index 58cb65e1c7..55376d5a79 100644 --- a/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/benchmarks/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -50,6 +50,9 @@ #include <QtNetwork/qtcpserver.h> #include "../../../../auto/network-settings.h" +#ifdef QT_BUILD_INTERNAL +#include <QtNetwork/private/qhostinfo_p.h> +#endif Q_DECLARE_METATYPE(QSharedPointer<char>) @@ -460,7 +463,9 @@ private slots: #ifndef QT_NO_SSL void echoPerformance_data(); void echoPerformance(); -#endif + void preConnectEncrypted(); +#endif // !QT_NO_SSL + void preConnectEncrypted_data(); void downloadPerformance(); void uploadPerformance(); @@ -472,9 +477,13 @@ private slots: void httpDownloadPerformanceDownloadBuffer(); void httpsRequestChain(); void httpsUpload(); + void preConnect_data(); + void preConnect(); private: void runHttpsUploadRequest(const QByteArray &data, const QNetworkRequest &request); + QPair<QNetworkReply *, qint64> runGetRequest(QNetworkAccessManager *manager, + const QNetworkRequest &request); }; void tst_qnetworkreply::initTestCase() @@ -495,6 +504,19 @@ void tst_qnetworkreply::httpLatency() } } +QPair<QNetworkReply *, qint64> tst_qnetworkreply::runGetRequest( + QNetworkAccessManager *manager, const QNetworkRequest &request) +{ + QElapsedTimer timer; + timer.start(); + QNetworkReply *reply = manager->get(request); + connect(reply, SIGNAL(sslErrors(QList<QSslError>)), reply, SLOT(ignoreSslErrors())); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(20); + qint64 elapsed = timer.elapsed(); + return qMakePair(reply, elapsed); +} + #ifndef QT_NO_SSL void tst_qnetworkreply::echoPerformance_data() { @@ -527,7 +549,60 @@ void tst_qnetworkreply::echoPerformance() delete reply; } } + +void tst_qnetworkreply::preConnectEncrypted() +{ + QString hostName = QLatin1String("www.google.com"); + + QNetworkAccessManager manager; + QNetworkRequest request(QUrl("https://" + hostName)); + + // make sure we have a full request including + // DNS lookup, TCP and SSL handshakes +#ifdef QT_BUILD_INTERNAL + qt_qhostinfo_clear_cache(); +#else + qWarning("no internal build, could not clear DNS cache. Results may not be representative."); +#endif + + // first, benchmark a normal request + QPair<QNetworkReply *, qint64> normalResult = runGetRequest(&manager, request); + QNetworkReply *normalReply = normalResult.first; + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(normalReply->error() == QNetworkReply::NoError); + qint64 normalElapsed = normalResult.second; + + // clear all caches again +#ifdef QT_BUILD_INTERNAL + qt_qhostinfo_clear_cache(); +#else + qWarning("no internal build, could not clear DNS cache. Results may not be representative."); #endif + manager.clearAccessCache(); + + // now try to make the connection beforehand + QFETCH(int, sleepTime); + manager.connectToHostEncrypted(hostName); + QTestEventLoop::instance().enterLoopMSecs(sleepTime); + + // now make another request and hopefully use the existing connection + QPair<QNetworkReply *, qint64> preConnectResult = runGetRequest(&manager, request); + QNetworkReply *preConnectReply = normalResult.first; + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(preConnectReply->error() == QNetworkReply::NoError); + qint64 preConnectElapsed = preConnectResult.second; + qDebug() << request.url().toString() << "full request:" << normalElapsed + << "ms, pre-connect request:" << preConnectElapsed << "ms, difference:" + << (normalElapsed - preConnectElapsed) << "ms"; +} +#endif // !QT_NO_SSL + +void tst_qnetworkreply::preConnectEncrypted_data() +{ + QTest::addColumn<int>("sleepTime"); + QTest::newRow("2secs") << 2000; // to start a new request after preconnecting is done + QTest::newRow("100ms") << 100; // to start a new request while preconnecting is in-flight +} void tst_qnetworkreply::downloadPerformance() { @@ -850,6 +925,56 @@ void tst_qnetworkreply::httpsUpload() } } +void tst_qnetworkreply::preConnect_data() +{ + preConnectEncrypted_data(); +} + +void tst_qnetworkreply::preConnect() +{ + QString hostName = QLatin1String("www.google.com"); + + QNetworkAccessManager manager; + QNetworkRequest request(QUrl("http://" + hostName)); + + // make sure we have a full request including + // DNS lookup and TCP handshake +#ifdef QT_BUILD_INTERNAL + qt_qhostinfo_clear_cache(); +#else + qWarning("no internal build, could not clear DNS cache. Results may not be representative."); +#endif + + // first, benchmark a normal request + QPair<QNetworkReply *, qint64> normalResult = runGetRequest(&manager, request); + QNetworkReply *normalReply = normalResult.first; + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(normalReply->error() == QNetworkReply::NoError); + qint64 normalElapsed = normalResult.second; + + // clear all caches again +#ifdef QT_BUILD_INTERNAL + qt_qhostinfo_clear_cache(); +#else + qWarning("no internal build, could not clear DNS cache. Results may not be representative."); +#endif + manager.clearAccessCache(); + + // now try to make the connection beforehand + QFETCH(int, sleepTime); + manager.connectToHost(hostName); + QTestEventLoop::instance().enterLoopMSecs(sleepTime); + + // now make another request and hopefully use the existing connection + QPair<QNetworkReply *, qint64> preConnectResult = runGetRequest(&manager, request); + QNetworkReply *preConnectReply = normalResult.first; + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(preConnectReply->error() == QNetworkReply::NoError); + qint64 preConnectElapsed = preConnectResult.second; + qDebug() << request.url().toString() << "full request:" << normalElapsed + << "ms, pre-connect request:" << preConnectElapsed << "ms, difference:" + << (normalElapsed - preConnectElapsed) << "ms"; +} QTEST_MAIN(tst_qnetworkreply) diff --git a/tests/manual/corelib/tools/qhash/main.cpp b/tests/manual/corelib/tools/qhash/main.cpp new file mode 100644 index 0000000000..fd38350c88 --- /dev/null +++ b/tests/manual/corelib/tools/qhash/main.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +//#define QT_STRICT_ITERATORS +#include <QHash> + +void testEraseNoError() +{ + QHash<int, int> a; + + a.insert(100, 100); + a.insert(101, 200); + a.insert(5, 50); + a.insertMulti(5, 60); + a.insertMulti(5, 70); + a.insertMulti(5, 80); + + QHash<int, int>::iterator i = a.begin(); + while (i.key() != 5) + ++i; + ++i; + a.erase(i); + + qDebug() << "Erase - got no errors on iterator check"; +} + +void testErase() +{ + QHash<int, int> a, b; + a.insert(5, 50); + a.insert(6, 60); + a.insert(7, 70); + b = a; + a.erase(a.begin()); + b.erase(b.end() - 1); + qDebug() << "Erase - Executing line with error now."; + a.erase(b.begin()); +} + + +int main() +{ + testEraseNoError(); + testErase(); + return 0; +} diff --git a/tests/manual/corelib/tools/qhash/main.pro b/tests/manual/corelib/tools/qhash/main.pro new file mode 100644 index 0000000000..bba41b9c12 --- /dev/null +++ b/tests/manual/corelib/tools/qhash/main.pro @@ -0,0 +1 @@ +SOURCES = main.cpp diff --git a/tests/manual/corelib/tools/qlist/main.cpp b/tests/manual/corelib/tools/qlist/main.cpp new file mode 100644 index 0000000000..8c1ee2890c --- /dev/null +++ b/tests/manual/corelib/tools/qlist/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <QDebug> +//#define QT_STRICT_ITERATORS +#include <QVector> +void testErase() +{ + QList<int> a, b; + a.append(5); + a.append(6); + a.append(7); + b = a; + a.erase(a.begin()); + qDebug() << "erase - Executing line with error now."; + // a.erase(a.end()); + a.erase(b.begin()); +} +void testInsert() +{ + QList<int> a, b; + a.insert(a.begin(), 1); + a.insert(a.begin(), 2); + a.insert(a.end(), 3); + b = a; + qDebug() << "insert - Executing line with error now."; + a.insert(b.begin(), 4); +} +int main() +{ + // testErase(); + testInsert(); + return 0; +}
\ No newline at end of file diff --git a/tests/manual/corelib/tools/qlist/main.pro b/tests/manual/corelib/tools/qlist/main.pro new file mode 100644 index 0000000000..bba41b9c12 --- /dev/null +++ b/tests/manual/corelib/tools/qlist/main.pro @@ -0,0 +1 @@ +SOURCES = main.cpp diff --git a/tests/manual/corelib/tools/qmap/main.cpp b/tests/manual/corelib/tools/qmap/main.cpp new file mode 100644 index 0000000000..0d88e3f170 --- /dev/null +++ b/tests/manual/corelib/tools/qmap/main.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//#define Q_NO_DEBUGMAP_PARENT_TEST +// Comment in line above to skip the parent test. +#include <QtCore/QMap> +#include <QDebug> + +void noBugErase() +{ + QMap<int, int> a, b; + a[10] = 11; + a[11] = 12; + b = a; + b.erase(b.begin()); +} + +void noBugInsertWithHints() +{ + QMap<int, int> a; + QMap<int, int> b; + for (int u = 100; u < 10000; u += 20) + a.insert(u, u); + b = a; + QMap<int, int>::const_iterator b_ite(b.begin()); // b.begin() ensures correct detach() + ++b_ite; + b.insert(b_ite, 501, 501); + b.insert(b_ite, 115, 115); + QMap<int, int> c; + c = b; + c.setSharable(false); +} + +void testInsertWithHintCorruption() +{ + qDebug() << "Starting testInsertWithHintCorruption"; + + QMap<int, int> a; + QMap<int, int> b; + for (int u = 100; u < 10000; u += 20) + a.insert(u, u); + b = a; + QMap<int, int>::const_iterator b_ite = b.constBegin(); + ++b_ite; + b.insert(b_ite, 501, 501); + b.insert(b_ite, 115, 115); // insert with wrong hint. + QMap<int, int> c; + c = b; + c.setSharable(false); + qDebug() << "End of testInsertWithHintCorruption - failed silently"; +} + +void testEraseCorruption() +{ + qDebug() << "Starting testEraseCorruption"; + + QMap<int, int> a, b; + a[10] = 11; + a[11] = 12; + b = a; + b.erase(a.begin()); + qDebug() << "End of testEraseCorruption - failed silently"; +} + +int main() +{ + noBugErase(); + noBugInsertWithHints(); + + // testEraseCorruption(); + testInsertWithHintCorruption(); + return 0; +} diff --git a/tests/manual/corelib/tools/qmap/qmaptest.pro b/tests/manual/corelib/tools/qmap/qmaptest.pro new file mode 100644 index 0000000000..fbe7013144 --- /dev/null +++ b/tests/manual/corelib/tools/qmap/qmaptest.pro @@ -0,0 +1,2 @@ +TEMPLATE = app +SOURCES = main.cpp diff --git a/tests/manual/corelib/tools/qset/main.cpp b/tests/manual/corelib/tools/qset/main.cpp new file mode 100644 index 0000000000..34a6c58c63 --- /dev/null +++ b/tests/manual/corelib/tools/qset/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +//#define QT_STRICT_ITERATORS +#include <QSet> + +void testErase() +{ + QSet<int> a, b; + a.insert(5); + a.insert(6); + a.insert(7); + b = a; + a.erase(a.begin()); + b.erase(b.end() - 1); + qDebug() << "erase - no errors until now"; + a.erase(b.begin()); +} + +int main() +{ + testErase(); + return 0; +} diff --git a/tests/manual/corelib/tools/qset/main.pro b/tests/manual/corelib/tools/qset/main.pro new file mode 100644 index 0000000000..bba41b9c12 --- /dev/null +++ b/tests/manual/corelib/tools/qset/main.pro @@ -0,0 +1 @@ +SOURCES = main.cpp diff --git a/tests/manual/corelib/tools/qvarlengtharray/main.cpp b/tests/manual/corelib/tools/qvarlengtharray/main.cpp new file mode 100644 index 0000000000..759f4b3905 --- /dev/null +++ b/tests/manual/corelib/tools/qvarlengtharray/main.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +//#define QT_STRICT_ITERATORS +#include <QVarLengthArray> + +void testErase() +{ + QVarLengthArray<int> a, b; + a.append(5); + a.append(6); + a.append(7); + b = a; + a.erase(a.begin()); + a.erase(a.end() - 1); + qDebug() << "erase - no errors until now"; + // a.erase(a.end()); + a.erase(b.begin()); +} + +void testInsert() +{ + QVarLengthArray<int> a, b; + a.insert(a.begin(), 1); + a.insert(a.begin(), 2); + a.insert(a.end(), 3); + b = a; + qDebug() << "insert - no errors until now"; + a.insert(b.begin(), 1, 4); +} + +int main() +{ + // testErase(); + testInsert(); + return 0; +} diff --git a/tests/manual/corelib/tools/qvarlengtharray/main.pro b/tests/manual/corelib/tools/qvarlengtharray/main.pro new file mode 100644 index 0000000000..4ce070ab75 --- /dev/null +++ b/tests/manual/corelib/tools/qvarlengtharray/main.pro @@ -0,0 +1 @@ +SOURCES=main.cpp diff --git a/tests/manual/corelib/tools/qvector/main.cpp b/tests/manual/corelib/tools/qvector/main.cpp new file mode 100644 index 0000000000..2dce4a9264 --- /dev/null +++ b/tests/manual/corelib/tools/qvector/main.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +//#define QT_STRICT_ITERATORS +#include <QVector> + +void testErase() +{ + QVector<int> a, b; + a.append(5); + a.append(6); + a.append(7); + b = a; + a.erase(a.begin()); + a.erase(a.end() - 1); + qDebug() << "erase - no errors until now"; + // a.erase(a.end()); + a.erase(b.begin()); +} + +void testInsert() +{ + QVector<int> a, b; + a.insert(a.begin(), 1, 1); + a.insert(a.begin(), 1, 2); + a.insert(a.begin(), 1, 3); + b = a; + qDebug() << "insert - no errors until now"; + a.insert(b.begin(), 1, 4); +} + +int main() +{ + testErase(); + // testInsert(); + return 0; +} diff --git a/tests/manual/corelib/tools/qvector/main.pro b/tests/manual/corelib/tools/qvector/main.pro new file mode 100644 index 0000000000..bba41b9c12 --- /dev/null +++ b/tests/manual/corelib/tools/qvector/main.pro @@ -0,0 +1 @@ +SOURCES = main.cpp diff --git a/tests/manual/dialogs/colordialogpanel.h b/tests/manual/dialogs/colordialogpanel.h index 05ca336a23..7f2898cea0 100644 --- a/tests/manual/dialogs/colordialogpanel.h +++ b/tests/manual/dialogs/colordialogpanel.h @@ -45,9 +45,11 @@ #include <QPointer> #include <QColorDialog> +QT_BEGIN_NAMESPACE class QComboBox; class QCheckBox; class QPushButton; +QT_END_NAMESPACE class ColorDialogPanel : public QWidget { diff --git a/tests/manual/dialogs/dialogs.pro b/tests/manual/dialogs/dialogs.pro index 4ed200ab7f..d19c3026d0 100644 --- a/tests/manual/dialogs/dialogs.pro +++ b/tests/manual/dialogs/dialogs.pro @@ -5,6 +5,6 @@ TARGET = dialogs TEMPLATE = app SOURCES += main.cpp filedialogpanel.cpp colordialogpanel.cpp fontdialogpanel.cpp \ - wizardpanel.cpp + wizardpanel.cpp messageboxpanel.cpp HEADERS += filedialogpanel.h colordialogpanel.h fontdialogpanel.h \ - wizardpanel.h + wizardpanel.h messageboxpanel.h diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp index a342122570..000d755cef 100644 --- a/tests/manual/dialogs/filedialogpanel.cpp +++ b/tests/manual/dialogs/filedialogpanel.cpp @@ -154,9 +154,11 @@ FileDialogPanel::FileDialogPanel(QWidget *parent) , m_nameFilterDetailsVisible(new QCheckBox(tr("Name filter details visible"))) , m_resolveSymLinks(new QCheckBox(tr("Resolve symlinks"))) , m_native(new QCheckBox(tr("Use native dialog"))) + , m_customDirIcons(new QCheckBox(tr("Don't use custom directory icons"))) , m_acceptMode(createCombo(this, acceptModeComboData, sizeof(acceptModeComboData)/sizeof(ComboData))) , m_fileMode(createCombo(this, fileModeComboData, sizeof(fileModeComboData)/sizeof(ComboData))) , m_viewMode(createCombo(this, viewModeComboData, sizeof(viewModeComboData)/sizeof(ComboData))) + , m_allowedSchemes(new QLineEdit(this)) , m_defaultSuffix(new QLineEdit(this)) , m_directory(new QLineEdit(this)) , m_selectedFileName(new QLineEdit(this)) @@ -171,11 +173,13 @@ FileDialogPanel::FileDialogPanel(QWidget *parent) optionsLayout->addRow(tr("AcceptMode:"), m_acceptMode); optionsLayout->addRow(tr("FileMode:"), m_fileMode); optionsLayout->addRow(tr("ViewMode:"), m_viewMode); + optionsLayout->addRow(tr("Allowed Schemes:"), m_allowedSchemes); optionsLayout->addRow(m_native); optionsLayout->addRow(m_confirmOverWrite); optionsLayout->addRow(m_nameFilterDetailsVisible); optionsLayout->addRow(m_resolveSymLinks); optionsLayout->addRow(m_readOnly); + optionsLayout->addRow(m_customDirIcons); // Files QGroupBox *filesGroupBox = new QGroupBox(tr("Files / Filters")); @@ -216,9 +220,13 @@ FileDialogPanel::FileDialogPanel(QWidget *parent) row = 0; column++; addButton(tr("getOpenFileName"), buttonLayout, row, column, this, SLOT(getOpenFileName())); + addButton(tr("getOpenFileUrl"), buttonLayout, row, column, this, SLOT(getOpenFileUrl())); addButton(tr("getOpenFileNames"), buttonLayout, row, column, this, SLOT(getOpenFileNames())); + addButton(tr("getOpenFileUrls"), buttonLayout, row, column, this, SLOT(getOpenFileUrls())); addButton(tr("getSaveFileName"), buttonLayout, row, column, this, SLOT(getSaveFileName())); + addButton(tr("getSaveFileUrl"), buttonLayout, row, column, this, SLOT(getSaveFileUrl())); addButton(tr("getExistingDirectory"), buttonLayout, row, column, this, SLOT(getExistingDirectory())); + addButton(tr("getExistingDirectoryUrl"), buttonLayout, row, column, this, SLOT(getExistingDirectoryUrl())); addButton(tr("Restore defaults"), buttonLayout, row, column, this, SLOT(restoreDefaults())); // Main layout @@ -316,9 +324,16 @@ QFileDialog::Options FileDialogPanel::options() const result |= QFileDialog::DontConfirmOverwrite; if (!m_native->isChecked()) result |= QFileDialog::DontUseNativeDialog; + if (!m_customDirIcons->isChecked()) + result |= QFileDialog::DontUseCustomDirectoryIcons; return result; } +QStringList FileDialogPanel::allowedSchemes() const +{ + return m_allowedSchemes->text().simplified().split(' ', QString::SkipEmptyParts); +} + void FileDialogPanel::getOpenFileNames() { QString selectedFilter = m_selectedNameFilter->text().trimmed(); @@ -334,6 +349,22 @@ void FileDialogPanel::getOpenFileNames() } } +void FileDialogPanel::getOpenFileUrls() +{ + QString selectedFilter = m_selectedNameFilter->text().trimmed(); + const QList<QUrl> files = + QFileDialog::getOpenFileUrls(this, tr("getOpenFileNames Qt %1").arg(QLatin1String(QT_VERSION_STR)), + QUrl(m_directory->text()), filterString(), &selectedFilter, options(), + allowedSchemes()); + if (!files.isEmpty()) { + QString result; + QDebug(&result).nospace() + << "Files: " << QUrl::toStringList(files) + << "\nName filter: " << selectedFilter; + QMessageBox::information(this, tr("getOpenFileNames"), result, QMessageBox::Ok); + } +} + void FileDialogPanel::getOpenFileName() { QString selectedFilter = m_selectedNameFilter->text().trimmed(); @@ -349,6 +380,22 @@ void FileDialogPanel::getOpenFileName() } } +void FileDialogPanel::getOpenFileUrl() +{ + QString selectedFilter = m_selectedNameFilter->text().trimmed(); + const QUrl file = + QFileDialog::getOpenFileUrl(this, tr("getOpenFileUrl Qt %1").arg(QLatin1String(QT_VERSION_STR)), + QUrl(m_directory->text()), filterString(), &selectedFilter, options(), + allowedSchemes()); + if (file.isValid()) { + QString result; + QDebug(&result).nospace() + << "File: " << file.toString() + << "\nName filter: " << selectedFilter; + QMessageBox::information(this, tr("getOpenFileName"), result, QMessageBox::Ok); + } +} + void FileDialogPanel::getSaveFileName() { QString selectedFilter = m_selectedNameFilter->text().trimmed(); @@ -364,6 +411,22 @@ void FileDialogPanel::getSaveFileName() } } +void FileDialogPanel::getSaveFileUrl() +{ + QString selectedFilter = m_selectedNameFilter->text().trimmed(); + const QUrl file = + QFileDialog::getSaveFileUrl(this, tr("getSaveFileName Qt %1").arg(QLatin1String(QT_VERSION_STR)), + QUrl(m_directory->text()), filterString(), &selectedFilter, options(), + allowedSchemes()); + if (file.isValid()) { + QString result; + QDebug(&result).nospace() + << "File: " << file.toString() + << "\nName filter: " << selectedFilter; + QMessageBox::information(this, tr("getSaveFileNames"), result, QMessageBox::Ok); + } +} + void FileDialogPanel::getExistingDirectory() { const QString dir = @@ -373,17 +436,29 @@ void FileDialogPanel::getExistingDirectory() QMessageBox::information(this, tr("getExistingDirectory"), QLatin1String("Directory: ") + dir, QMessageBox::Ok); } +void FileDialogPanel::getExistingDirectoryUrl() +{ + const QUrl dir = + QFileDialog::getExistingDirectoryUrl(this, tr("getExistingDirectory Qt %1").arg(QLatin1String(QT_VERSION_STR)), + QUrl(m_directory->text()), options() | QFileDialog::ShowDirsOnly, + allowedSchemes()); + if (!dir.isEmpty()) + QMessageBox::information(this, tr("getExistingDirectory"), QLatin1String("Directory: ") + dir.toString(), QMessageBox::Ok); +} + void FileDialogPanel::restoreDefaults() { QFileDialog d; setComboBoxValue(m_acceptMode, d.acceptMode()); setComboBoxValue(m_fileMode, d.fileMode()); setComboBoxValue(m_viewMode, d.viewMode()); + m_allowedSchemes->setText(QString()); m_confirmOverWrite->setChecked(d.confirmOverwrite()); m_nameFilterDetailsVisible->setChecked(d.isNameFilterDetailsVisible()); m_resolveSymLinks->setChecked(d.resolveSymlinks()); m_readOnly->setChecked(d.isReadOnly()); m_native->setChecked(true); + m_customDirIcons->setChecked(d.testOption(QFileDialog::DontUseCustomDirectoryIcons)); m_directory->setText(QDir::homePath()); m_defaultSuffix->setText(QLatin1String("txt")); m_nameFilters->setPlainText(QLatin1String("Any files (*)\nImage files (*.png *.xpm *.jpg)\nText files (*.txt)")); diff --git a/tests/manual/dialogs/filedialogpanel.h b/tests/manual/dialogs/filedialogpanel.h index 2977de4164..2e1d5d4de9 100644 --- a/tests/manual/dialogs/filedialogpanel.h +++ b/tests/manual/dialogs/filedialogpanel.h @@ -46,11 +46,13 @@ #include <QFileDialog> #include <QPointer> +QT_BEGIN_NAMESPACE class QPushButton; class QCheckBox; class QComboBox; class QLineEdit; class QPlainTextEdit; +QT_END_NAMESPACE class LabelLineEdit; class FileDialogPanel : public QWidget @@ -66,9 +68,13 @@ public slots: void deleteNonModalDialog(); void deleteModalDialog(); void getOpenFileNames(); + void getOpenFileUrls(); void getOpenFileName(); + void getOpenFileUrl(); void getSaveFileName(); + void getSaveFileUrl(); void getExistingDirectory(); + void getExistingDirectoryUrl(); void accepted(); void showAcceptedResult(); void restoreDefaults(); @@ -80,6 +86,7 @@ private slots: private: QString filterString() const; QFileDialog::Options options() const; + QStringList allowedSchemes() const; void applySettings(QFileDialog *d) const; QCheckBox *m_readOnly; @@ -87,9 +94,11 @@ private: QCheckBox *m_nameFilterDetailsVisible; QCheckBox *m_resolveSymLinks; QCheckBox *m_native; + QCheckBox *m_customDirIcons; QComboBox *m_acceptMode; QComboBox *m_fileMode; QComboBox *m_viewMode; + QLineEdit *m_allowedSchemes; QLineEdit *m_defaultSuffix; QLineEdit *m_directory; QLineEdit *m_selectedFileName; diff --git a/tests/manual/dialogs/fontdialogpanel.cpp b/tests/manual/dialogs/fontdialogpanel.cpp index 02f05f9580..c72bf77351 100644 --- a/tests/manual/dialogs/fontdialogpanel.cpp +++ b/tests/manual/dialogs/fontdialogpanel.cpp @@ -67,12 +67,20 @@ FontDialogPanel::FontDialogPanel(QWidget *parent) , m_fontSizeBox(new QDoubleSpinBox) , m_noButtons(new QCheckBox(tr("Don't display OK/Cancel buttons"))) , m_dontUseNativeDialog(new QCheckBox(tr("Don't use native dialog"))) + , m_scalableFilter(new QCheckBox(tr("Filter scalable fonts"))) + , m_nonScalableFilter(new QCheckBox(tr("Filter non scalable fonts"))) + , m_monospacedFilter(new QCheckBox(tr("Filter monospaced fonts"))) + , m_proportionalFilter(new QCheckBox(tr("Filter proportional fonts"))) { // Options QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this); QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox); optionsLayout->addWidget(m_noButtons); optionsLayout->addWidget(m_dontUseNativeDialog); + optionsLayout->addWidget(m_scalableFilter); + optionsLayout->addWidget(m_nonScalableFilter); + optionsLayout->addWidget(m_monospacedFilter); + optionsLayout->addWidget(m_proportionalFilter); // Font QGroupBox *fontGroupBox = new QGroupBox(tr("Font"), this); @@ -201,6 +209,10 @@ void FontDialogPanel::applySettings(QFontDialog *d) const { d->setOption(QFontDialog::NoButtons, m_noButtons->isChecked()); d->setOption(QFontDialog::DontUseNativeDialog, m_dontUseNativeDialog->isChecked()); + d->setOption(QFontDialog::ScalableFonts, m_scalableFilter->isChecked()); + d->setOption(QFontDialog::NonScalableFonts, m_nonScalableFilter->isChecked()); + d->setOption(QFontDialog::MonospacedFonts, m_monospacedFilter->isChecked()); + d->setOption(QFontDialog::ProportionalFonts, m_proportionalFilter->isChecked()); QFont font = m_fontFamilyBox->currentFont(); font.setPointSizeF(m_fontSizeBox->value()); diff --git a/tests/manual/dialogs/fontdialogpanel.h b/tests/manual/dialogs/fontdialogpanel.h index f3bbbb3939..4592c2ec6e 100644 --- a/tests/manual/dialogs/fontdialogpanel.h +++ b/tests/manual/dialogs/fontdialogpanel.h @@ -45,10 +45,12 @@ #include <QPointer> #include <QFontDialog> +QT_BEGIN_NAMESPACE class QCheckBox; class QPushButton; class QFontComboBox; class QDoubleSpinBox; +QT_END_NAMESPACE class FontDialogPanel : public QWidget { @@ -77,6 +79,10 @@ private: QDoubleSpinBox *m_fontSizeBox; QCheckBox *m_noButtons; QCheckBox *m_dontUseNativeDialog; + QCheckBox *m_scalableFilter; + QCheckBox *m_nonScalableFilter; + QCheckBox *m_monospacedFilter; + QCheckBox *m_proportionalFilter; QPushButton *m_deleteNonModalDialogButton; QPushButton *m_deleteModalDialogButton; QString m_result; diff --git a/tests/manual/dialogs/main.cpp b/tests/manual/dialogs/main.cpp index 4ad2842e44..c5f14cabef 100644 --- a/tests/manual/dialogs/main.cpp +++ b/tests/manual/dialogs/main.cpp @@ -43,6 +43,7 @@ #include "colordialogpanel.h" #include "fontdialogpanel.h" #include "wizardpanel.h" +#include "messageboxpanel.h" #include <QMainWindow> #include <QApplication> @@ -73,6 +74,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) tabWidget->addTab(new ColorDialogPanel, tr("QColorDialog")); tabWidget->addTab(new FontDialogPanel, tr("QFontDialog")); tabWidget->addTab(new WizardPanel, tr("QWizard")); + tabWidget->addTab(new MessageBoxPanel, tr("QMessageBox")); setCentralWidget(tabWidget); } diff --git a/tests/manual/dialogs/messageboxpanel.cpp b/tests/manual/dialogs/messageboxpanel.cpp new file mode 100644 index 0000000000..6fc84e11fd --- /dev/null +++ b/tests/manual/dialogs/messageboxpanel.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "messageboxpanel.h" + +#include <QGroupBox> +#include <QPushButton> +#include <QVBoxLayout> +#include <QHBoxLayout> +#include <QMessageBox> +#include <QPushButton> +#include <QDebug> +#include <QComboBox> +#include <QLineEdit> +#include <QLabel> +#include <QCheckBox> + +MessageBoxPanel::MessageBoxPanel(QWidget *parent) : QWidget(parent) +,m_iconComboBox(new QComboBox) +,m_textInMsgBox(new QLineEdit) +,m_informativeText(new QLineEdit) +,m_detailedtext(new QLineEdit) +,m_buttonsMask(new QLineEdit) +,m_btnExec(new QPushButton) +,m_btnShowApply(new QPushButton) +,m_resultLabel(new QLabel) +,m_chkReallocMsgBox(new QCheckBox(QString::fromLatin1("Reallocate Message Box"))) +,m_msgbox(new QMessageBox) +{ + // --- Options --- + QGroupBox *optionsGroupBox = new QGroupBox(tr("Options"), this); + QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroupBox); + + // text + optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box text"))); + m_textInMsgBox->setText(QString::fromLatin1("This is a simple test with a text that is not long")); + optionsLayout->addWidget(m_textInMsgBox); + + // informative text + optionsLayout->addWidget(new QLabel(QString::fromLatin1("Informative Text"))); + optionsLayout->addWidget(m_informativeText); + + // detailed text + optionsLayout->addWidget(new QLabel(QString::fromLatin1("detailed Text"))); + optionsLayout->addWidget(m_detailedtext); + + // icon + QStringList items; + items << "NoIcon" << "Information" << "Warning" << "Critical" << "Question"; + m_iconComboBox->addItems(items); + optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box icon"))); + optionsLayout->addWidget(m_iconComboBox); + + // buttons mask + optionsLayout->addWidget(new QLabel(QString::fromLatin1("Message box button mask (in hex)"))); + m_validator = new QRegExpValidator(QRegExp("0[xX]?[0-9a-fA-F]+"), this); + m_buttonsMask->setMaxLength(10); + m_buttonsMask->setValidator(m_validator); + m_buttonsMask->setText(QString::fromLatin1("0x00300400")); + optionsLayout->addWidget(m_buttonsMask); + + // reallocate + optionsLayout->addWidget(m_chkReallocMsgBox); + optionsLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding)); + + // Exec/Show + QGroupBox *execGroupBox = new QGroupBox(tr("Exec")); + QVBoxLayout *execLayout = new QVBoxLayout(execGroupBox); + m_btnExec->setText(QString::fromLatin1("Exec message box")); + connect(m_btnExec, SIGNAL(clicked()), this, SLOT(doExec())); + execLayout->addWidget(m_btnExec); + + m_btnShowApply->setText(QString::fromLatin1("Show / apply")); + connect(m_btnShowApply, SIGNAL(clicked()), this, SLOT(doShowApply())); + execLayout->addWidget(m_btnShowApply); + + // result label + execLayout->addWidget(m_resultLabel); + + execLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding)); + execGroupBox->setLayout(execLayout); + + // Main layout + QHBoxLayout *mainLayout = new QHBoxLayout(); + mainLayout->addWidget(optionsGroupBox); + mainLayout->addWidget(execGroupBox); + + setLayout(mainLayout); +} + +void MessageBoxPanel::setupMessageBox(QMessageBox &box) +{ + m_resultLabel->setText(QString()); + box.setText(m_textInMsgBox->text()); + box.setInformativeText(m_informativeText->text()); + box.setDetailedText(m_detailedtext->text()); + + QString btnHexText = m_buttonsMask->text(); + btnHexText = btnHexText.replace(QString::fromLatin1("0x"), QString(), Qt::CaseInsensitive); + bool ok; + QMessageBox::StandardButtons btns = (QMessageBox::StandardButtons) btnHexText.toUInt(&ok, 16); + box.setStandardButtons((QMessageBox::StandardButtons) btns); + if (box.standardButtons() == (QMessageBox::StandardButtons) 0) + box.setStandardButtons(QMessageBox::Ok); // just to have something. + + box.setIcon((QMessageBox::Icon) m_iconComboBox->currentIndex()); +} + +MessageBoxPanel::~MessageBoxPanel() +{ + if (m_msgbox) + m_msgbox->deleteLater(); +} + +void MessageBoxPanel::doExec() +{ + if (!m_msgbox || m_chkReallocMsgBox->isChecked()) { + if (m_msgbox) + m_msgbox->deleteLater(); + m_msgbox = new QMessageBox; + } + setupMessageBox(*m_msgbox); + m_msgbox->setWindowModality(Qt::NonModal); + + int res = m_msgbox->exec(); + QString sres; + sres.setNum(res, 16); + m_resultLabel->setText(QString::fromLatin1("Return value (hex): %1").arg(sres)); +} + +void MessageBoxPanel::doShowApply() +{ + if (!m_msgbox || m_chkReallocMsgBox->isChecked()) { + if (m_msgbox) + m_msgbox->deleteLater(); + m_msgbox = new QMessageBox; + } + setupMessageBox(*m_msgbox); + if (!m_msgbox->isVisible()) { + m_msgbox->setWindowModality(Qt::NonModal); + m_msgbox->show(); + } +} diff --git a/tests/manual/dialogs/messageboxpanel.h b/tests/manual/dialogs/messageboxpanel.h new file mode 100644 index 0000000000..9f7e35210c --- /dev/null +++ b/tests/manual/dialogs/messageboxpanel.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2013 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MESSAGEBOXPANEL_H +#define MESSAGEBOXPANEL_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QComboBox; +class QCheckBox; +class QPushButton; +class QLineEdit; +class QValidator; +class QLabel; +class QMessageBox; +class QCheckBox; +QT_END_NAMESPACE + +class MessageBoxPanel : public QWidget +{ + Q_OBJECT +public: + explicit MessageBoxPanel(QWidget *parent = 0); + ~MessageBoxPanel(); + +public slots: + void doExec(); + void doShowApply(); + +private: + QComboBox *m_iconComboBox; + QLineEdit *m_textInMsgBox; + QLineEdit *m_informativeText; + QLineEdit *m_detailedtext; + QLineEdit *m_buttonsMask; + QPushButton *m_btnExec; + QPushButton *m_btnShowApply; + QValidator *m_validator; + QLabel *m_resultLabel; + QCheckBox *m_chkReallocMsgBox; + QMessageBox *m_msgbox; + void setupMessageBox(QMessageBox &box); +}; + +#endif diff --git a/tests/manual/dialogs/wizardpanel.h b/tests/manual/dialogs/wizardpanel.h index 6a2268e94c..10e0c5071e 100644 --- a/tests/manual/dialogs/wizardpanel.h +++ b/tests/manual/dialogs/wizardpanel.h @@ -46,7 +46,9 @@ class WizardStyleControl; class WizardOptionsControl; +QT_BEGIN_NAMESPACE class QWizard; +QT_END_NAMESPACE class WizardPanel : public QWidget { diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 2fa05f65e0..c04f22b53b 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -20,6 +20,7 @@ qlayout \ qlocale \ qnetworkaccessmanager/qget \ qnetworkconfigurationmanager \ +qnetworkconfiguration \ qnetworkreply \ qpainfo \ qscreen \ diff --git a/tests/manual/qdesktopservices/tst_qdesktopservices.cpp b/tests/manual/qdesktopservices/tst_qdesktopservices.cpp index 534816a01b..9c39002fba 100644 --- a/tests/manual/qdesktopservices/tst_qdesktopservices.cpp +++ b/tests/manual/qdesktopservices/tst_qdesktopservices.cpp @@ -104,6 +104,11 @@ void tst_QDesktopServices::openUrl_data() << QUrl("http://google.com/search?q=/profile/5") << "This should search \"/profile/5\" on Google."; + // see QTBUG-31945 + QTest::newRow("two-fragments") + << QUrl("http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW81") + << "This should open \"Implementing a Container View Controller\" in the UIViewController docs"; + QTest::newRow("mail") << QUrl("mailto:development@qt-project.org") << "This should open an email composer with the destination set to development@qt-project.org"; @@ -118,7 +123,7 @@ void tst_QDesktopServices::openUrl() QFETCH(QUrl, data); QFETCH(QString, message); qWarning("\n\nOpening \"%s\": %s", qPrintable(data.toString()), qPrintable(message)); - QDesktopServices::openUrl(data); + QVERIFY(QDesktopServices::openUrl(data)); } QTEST_MAIN(tst_QDesktopServices) diff --git a/tests/manual/qnetworkconfiguration/main.cpp b/tests/manual/qnetworkconfiguration/main.cpp new file mode 100644 index 0000000000..c611cfc9e2 --- /dev/null +++ b/tests/manual/qnetworkconfiguration/main.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Research in Motion. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QDebug> +#include <qtest.h> +#include <QtTest/QtTest> +#include <QtNetwork/qnetworkconfiguration.h> +#include <QtNetwork/qnetworkconfigmanager.h> + +class tst_qnetworkconfiguration : public QObject +{ + Q_OBJECT + +private slots: + void bearerType(); + void bearerTypeFamily(); +}; + +void tst_qnetworkconfiguration::bearerType() +{ + QNetworkConfigurationManager m; + QList<QNetworkConfiguration> allConfs = m.allConfigurations(); + QElapsedTimer timer; + for (int a = 0; a < allConfs.count(); a++) { + timer.start(); + QNetworkConfiguration::BearerType type = allConfs.at(a).bearerType(); + qint64 elapsed = timer.elapsed(); + QString typeString; + switch (type) { + case QNetworkConfiguration::BearerUnknown: + typeString = QLatin1String("Unknown"); + break; + case QNetworkConfiguration::BearerEthernet: + typeString = QLatin1String("Ethernet"); + break; + case QNetworkConfiguration::BearerWLAN: + typeString = QLatin1String("WLAN"); + break; + case QNetworkConfiguration::Bearer2G: + typeString = QLatin1String("2G"); + break; + case QNetworkConfiguration::BearerCDMA2000: + typeString = QLatin1String("CDMA2000"); + break; + case QNetworkConfiguration::BearerWCDMA: + typeString = QLatin1String("WCDMA"); + break; + case QNetworkConfiguration::BearerHSPA: + typeString = QLatin1String("HSPA"); + break; + case QNetworkConfiguration::BearerBluetooth: + typeString = QLatin1String("Bluetooth"); + break; + case QNetworkConfiguration::BearerWiMAX: + typeString = QLatin1String("WiMAX"); + break; + case QNetworkConfiguration::BearerEVDO: + typeString = QLatin1String("EVDO"); + break; + case QNetworkConfiguration::BearerLTE: + typeString = QLatin1String("LTE"); + break; + default: + typeString = "unknown bearer (?)"; + } + + const char *isDefault = (allConfs.at(a) == m.defaultConfiguration()) + ? "*DEFAULT*" : ""; + qDebug() << isDefault << "identifier:" << allConfs.at(a).identifier() + << "bearer type name:" << allConfs.at(a).bearerTypeName() + << "bearer type:" << type << "(" << typeString << ")" + << "elapsed:" << elapsed; + QCOMPARE(allConfs.at(a).bearerTypeName(), typeString); + } +} + +void tst_qnetworkconfiguration::bearerTypeFamily() +{ + QNetworkConfigurationManager m; + foreach (const QNetworkConfiguration &config, + m.allConfigurations(QNetworkConfiguration::Active)) { + QString family; + switch (config.bearerTypeFamily()) { + case QNetworkConfiguration::Bearer3G: + family = QLatin1String("Bearer3G"); + break; + case QNetworkConfiguration::Bearer4G: + family = QLatin1String("Bearer4G"); + break; + default: + family = config.bearerTypeName(); + } + qDebug() << config.name() << "has bearer type" + << config.bearerTypeName() << "of bearer type family" + << family; + } +} + +QTEST_MAIN(tst_qnetworkconfiguration) + +#include "main.moc" diff --git a/tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro b/tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro new file mode 100644 index 0000000000..25ef41b92a --- /dev/null +++ b/tests/manual/qnetworkconfiguration/qnetworkconfiguration.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = tst_qnetworkconfiguration + +QT -= gui +QT += network testlib + +SOURCES += main.cpp diff --git a/tests/manual/qpainfo/main.cpp b/tests/manual/qpainfo/main.cpp index 6b712304a0..0f5119bab3 100644 --- a/tests/manual/qpainfo/main.cpp +++ b/tests/manual/qpainfo/main.cpp @@ -49,6 +49,7 @@ #include <QStringList> #include <QVariant> #include <QFont> +#include <QFontDatabase> #include <QSysInfo> #include <QLibraryInfo> #include <QStandardPaths> @@ -85,6 +86,12 @@ std::ostream &operator<<(std::ostream &str, const QStringList &l) return str; } +std::ostream &operator<<(std::ostream &str, const QFont &f) +{ + std::cout << '"' << f.family().toStdString() << "\" " << f.pointSize(); + return str; +} + static QStringList toNativeSeparators(QStringList in) { for (int i = 0; i < in.size(); ++i) @@ -184,7 +191,12 @@ int main(int argc, char **argv) << " from " << platformTheme->themeHint(QPlatformTheme::IconThemeSearchPaths).toStringList() << '\n'; } if (const QFont *systemFont = platformTheme->font()) - std::cout << " System font: \"" << systemFont->family().toStdString() << "\" " << systemFont->pointSize() << '\n'; + std::cout << " System font: " << *systemFont<< '\n'; + std::cout << " General font : " << QFontDatabase::systemFont(QFontDatabase::GeneralFont) << '\n' + << " Fixed font : " << QFontDatabase::systemFont(QFontDatabase::FixedFont) << '\n' + << " Title font : " << QFontDatabase::systemFont(QFontDatabase::TitleFont) << '\n' + << " Smallest font: " << QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont) << "\n\n"; + if (platformTheme->usePlatformNativeDialog(QPlatformTheme::FileDialog)) std::cout << " Native file dialog\n"; if (platformTheme->usePlatformNativeDialog(QPlatformTheme::ColorDialog)) diff --git a/tests/manual/qtabletevent/regular_widgets/main.cpp b/tests/manual/qtabletevent/regular_widgets/main.cpp index 1e2f5c00da..ce77cf8cff 100644 --- a/tests/manual/qtabletevent/regular_widgets/main.cpp +++ b/tests/manual/qtabletevent/regular_widgets/main.cpp @@ -43,12 +43,38 @@ #include <QDebug> #include <QMouseEvent> #include <QTabletEvent> -#include <QWidget> +#include <QMainWindow> +#include <QMenuBar> +#include <QMenu> +#include <QAction> +#include <QVector> +#include <QPainter> +#include <QCursor> + +enum TabletPointType { + TabletButtonPress, + TabletButtonRelease, + TabletMove, + TabletDraw +}; + +struct TabletPoint +{ + TabletPoint(const QPoint &p = QPoint(), TabletPointType t = TabletMove) : pos(p), type(t) {} + + QPoint pos; + TabletPointType type; +}; class EventReportWidget : public QWidget { + Q_OBJECT public: EventReportWidget(); + +public slots: + void clearPoints() { m_points.clear(); update(); } + protected: void mouseDoubleClickEvent(QMouseEvent *event) { outputMouseEvent(event); } void mouseMoveEvent(QMouseEvent *event) { outputMouseEvent(event); } @@ -57,11 +83,14 @@ protected: void tabletEvent(QTabletEvent *); + void paintEvent(QPaintEvent *); + private: void outputMouseEvent(QMouseEvent *event); bool m_lastIsMouseMove; bool m_lastIsTabletMove; + QVector<TabletPoint> m_points; }; EventReportWidget::EventReportWidget() @@ -69,6 +98,34 @@ EventReportWidget::EventReportWidget() , m_lastIsTabletMove(false) { } +void EventReportWidget::paintEvent(QPaintEvent *) +{ + QPainter p(this); + const QRect geom = QRect(QPoint(0, 0), size()); + p.fillRect(geom, Qt::white); + p.drawRect(QRect(geom.topLeft(), geom.bottomRight() - QPoint(1,1))); + foreach (const TabletPoint &t, m_points) { + if (geom.contains(t.pos)) { + QPainterPath pp; + pp.addEllipse(t.pos, 5, 5); + switch (t.type) { + case TabletButtonPress: + p.fillPath(pp, Qt::black); + break; + case TabletButtonRelease: + p.fillPath(pp, Qt::red); + break; + case TabletMove: + p.drawPath(pp); + break; + case TabletDraw: + p.fillPath(pp, Qt::blue); + break; + } + } + } +} + void EventReportWidget::tabletEvent(QTabletEvent *event) { QWidget::tabletEvent(event); @@ -89,14 +146,20 @@ void EventReportWidget::tabletEvent(QTabletEvent *event) m_lastIsTabletMove = true; type = QString::fromLatin1("TabletMove"); + m_points.push_back(TabletPoint(event->pos(), event->pressure() ? TabletDraw : TabletMove)); + update(); break; case QEvent::TabletPress: m_lastIsTabletMove = false; type = QString::fromLatin1("TabletPress"); + m_points.push_back(TabletPoint(event->pos(), TabletButtonPress)); + update(); break; case QEvent::TabletRelease: m_lastIsTabletMove = false; type = QString::fromLatin1("TabletRelease"); + m_points.push_back(TabletPoint(event->pos(), TabletButtonRelease)); + update(); break; default: Q_ASSERT(false); @@ -105,7 +168,8 @@ void EventReportWidget::tabletEvent(QTabletEvent *event) qDebug() << "Tablet event, type = " << type << " position = " << event->pos() - << " global position = " << event->globalPos(); + << " global position = " << event->globalPos() + << " cursor at " << QCursor::pos(); } void EventReportWidget::outputMouseEvent(QMouseEvent *event) @@ -144,7 +208,18 @@ void EventReportWidget::outputMouseEvent(QMouseEvent *event) int main(int argc, char *argv[]) { QApplication app(argc, argv); - EventReportWidget widget; - widget.show(); + QMainWindow mainWindow; + mainWindow.setWindowTitle(QString::fromLatin1("Tablet Test %1").arg(QT_VERSION_STR)); + EventReportWidget *widget = new EventReportWidget; + widget->setMinimumSize(640, 480); + QMenu *fileMenu = mainWindow.menuBar()->addMenu("File"); + QObject::connect(fileMenu->addAction("Clear"), SIGNAL(triggered()), widget, SLOT(clearPoints())); + QAction *quitAction = fileMenu->addAction("Quit"); + QObject::connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); + mainWindow.setCentralWidget(widget); + mainWindow.show(); return app.exec(); } + +#include "main.moc" diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp new file mode 100644 index 0000000000..463366433c --- /dev/null +++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.cpp @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QtWidgets> + +const int rowCount = 2000; + +class TableDialog : public QDialog +{ + Q_OBJECT +public: + TableDialog() : model(rowCount, 3) { create(); } + void create() + { + resize(1000, 233); + gridLayout = new QGridLayout(this); + tableView = new QTableView(this); + + gridLayout->addWidget(tableView, 0, 0, 2, 1); + spinPrecision = new QSpinBox(this); + gridLayout->addWidget(spinPrecision, 0, 1, 1, 1); + verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding); + gridLayout->addItem(verticalSpacer, 1, 1, 1, 1); + + QString ii = QString::fromLatin1("ii"); + QStringList is; + spinPrecision->setMinimum(-1); + spinPrecision->setMaximum(rowCount + 2); + for (int u = 0; u < rowCount; ++u) { + if (u % 25 == 0) + ii += QString::fromLatin1("i"); + else + ii[ii.length() - 1] = QChar::fromLatin1('a' + (u % 25)); + ii[ii.length() - 2] = QChar::fromLatin1('i'); + is.append(ii); + } + + for (int u = 0; u < rowCount; ++u) { + QString col1; + col1 = QString::fromLatin1("Row: %1").arg(u); + model.setData(model.index(u, 0), col1); + model.setData(model.index(u, 1), is[u]); + model.setData(model.index(u, 2), is[rowCount - u -1]); + } + tableView->setModel(&model); + + tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + spinPrecision->setValue(tableView->horizontalHeader()->resizeContentsPrecision()); + connect(spinPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int))); + } // setupUi +protected slots: + void slotValueChanged(int newval); +protected: + QGridLayout *gridLayout; + QTableView *tableView; + QSpinBox *spinPrecision; + QSpacerItem *verticalSpacer; + QStandardItemModel model; +}; + +void TableDialog::slotValueChanged(int newval) +{ + tableView->horizontalHeader()->setResizeContentsPrecision(newval, true); +} + + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + TableDialog d1; + d1.show(); + app.exec(); +} + +#include "testtable1.moc" diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro new file mode 100644 index 0000000000..e07f40bc2f --- /dev/null +++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablehorz/testtable1.pro @@ -0,0 +1,2 @@ +SOURCES = testtable1.cpp +QT += widgets diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp new file mode 100644 index 0000000000..027801d528 --- /dev/null +++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QtWidgets> + +const int columnCount = 1500; + +class TableDialog : public QDialog +{ + Q_OBJECT +public: + TableDialog() : model(2, columnCount) { create(); } + void create() + { + resize(1200, 400); + gridLayout = new QGridLayout(this); + tableView = new QTableView(this); + + gridLayout->addWidget(tableView, 0, 0, 2, 1); + spinPrecision = new QSpinBox(this); + gridLayout->addWidget(spinPrecision, 0, 1, 1, 1); + verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding); + gridLayout->addItem(verticalSpacer, 1, 1, 1, 1); + + QString ii = QString::fromLatin1("ii"); + QStringList is; + spinPrecision->setMinimum(-1); + spinPrecision->setMaximum(columnCount + 2); + + QFont f = QApplication::font(); + for (int u = 0; u < columnCount; ++u) { + int size = 10 + (u % 63); + f.setPixelSize(size); + QString col; + if (u % 50 < 25) + col = QChar::fromLatin1('a' + (u % 25)); + else + col = QChar::fromLatin1('A' + (u % 25)); + + int v = columnCount - u - 1; + model.setData(model.index(0, u), col); + model.setData(model.index(1, v), col); + + model.setData(model.index(0, u), f, Qt::FontRole); + model.setData(model.index(1, v), f, Qt::FontRole); + } + tableView->setModel(&model); + + for (int u = 0; u < columnCount; ++ u) + tableView->horizontalHeader()->resizeSection(u, 60); + + // Make last index in first row a bit special + f.setPixelSize(96); + model.setData(model.index(0, columnCount - 1), f, Qt::FontRole); + model.setData(model.index(0, columnCount - 1), QString::fromLatin1("qI")); + tableView->horizontalHeader()->resizeSection(columnCount - 1, 140); + + tableView->verticalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + tableView->verticalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + spinPrecision->setValue(tableView->verticalHeader()->resizeContentsPrecision()); + connect(spinPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int))); + } // setupUi +protected slots: + void slotValueChanged(int newval); +protected: + QGridLayout *gridLayout; + QTableView *tableView; + QSpinBox *spinPrecision; + QSpacerItem *verticalSpacer; + QStandardItemModel model; +}; + +void TableDialog::slotValueChanged(int newval) +{ + tableView->verticalHeader()->setResizeContentsPrecision(newval, true); +} + + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + TableDialog d1; + d1.show(); + app.exec(); +} + +#include "testtable2.moc" diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro new file mode 100644 index 0000000000..b887fcb14b --- /dev/null +++ b/tests/manual/widgets/itemviews/autoResizePrecision/tablevert/testtable2.pro @@ -0,0 +1,2 @@ +SOURCES = testtable2.cpp +QT += widgets diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp new file mode 100644 index 0000000000..c48d933fcd --- /dev/null +++ b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets/QtWidgets> + +class TreeDialog : public QDialog +{ + Q_OBJECT +public: + TreeDialog() { create(); } +protected: + void create() + { + resize(1000, 233); + gridLayout = new QGridLayout(this); + treeWidget = new QTreeWidget(this); + + gridLayout->addWidget(treeWidget, 0, 0, 2, 1); + spinPrecision = new QSpinBox(this); + gridLayout->addWidget(spinPrecision, 0, 1, 1, 1); + verticalSpacer = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding); + gridLayout->addItem(verticalSpacer, 1, 1, 1, 1); + + QStringList itemInfo("Col1"); + itemInfo.append("Col2"); + itemInfo.append("Col3"); + itemInfo.append("Dummy"); + // Developer no. could also have been social security number og some other id. + treeWidget->setHeaderLabels(itemInfo); + + QStringList sl1("This is Root Item"); + sl1.append("i"); + QTreeWidgetItem *rootitem = new QTreeWidgetItem(treeWidget, sl1); + + QStringList sl2("This is Child1 Item"); + sl2.append("WW"); + QTreeWidgetItem *child1 = new QTreeWidgetItem(rootitem, sl2); + + QString ii = QString::fromLatin1("ii"); + QStringList is; + const int rowCount = 3000; + spinPrecision->setMinimum(-1); + spinPrecision->setMaximum(rowCount + 5); + for (int u = 0; u < rowCount; ++u) { + if (u % 25 == 0) + ii += QString::fromLatin1("i"); + else + ii[ii.length() - 1] = QChar::fromLatin1('a' + (u % 25)); + ii[ii.length() - 2] = QChar::fromLatin1('i'); + is.append(ii); + } + + for (int u = 0; u < rowCount - 2; ++u) { // -2 since we have rootitem and child1 + QString col1; + col1 = QString::fromLatin1("This is child item %1").arg(u + 2); + + QStringList sl(col1); + sl.append(is[u]); + sl.append(is[rowCount - u - 1]); + + if (u > 500) + new QTreeWidgetItem(rootitem, sl); + else + new QTreeWidgetItem(child1, sl); + } + treeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + treeWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + treeWidget->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + spinPrecision->setValue(treeWidget->header()->resizeContentsPrecision()); + connect(spinPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int))); + } // setupUi +protected slots: + void slotValueChanged(int newval); +protected: + QGridLayout *gridLayout; + QTreeWidget *treeWidget; + QSpinBox *spinPrecision; + QSpacerItem *verticalSpacer; +}; + +void TreeDialog::slotValueChanged(int newval) +{ + treeWidget->header()->setResizeContentsPrecision(newval, true); +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + TreeDialog d1; + d1.show(); + app.exec(); +} + +#include "testtree.moc" diff --git a/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro new file mode 100644 index 0000000000..c062586eac --- /dev/null +++ b/tests/manual/widgets/itemviews/autoResizePrecision/treeview/testtree.pro @@ -0,0 +1,2 @@ +SOURCES = testtree.cpp +QT += widgets diff --git a/tests/manual/widgets/itemviews/itemviews.pro b/tests/manual/widgets/itemviews/itemviews.pro index 58b02bfc0d..6b91531a87 100644 --- a/tests/manual/widgets/itemviews/itemviews.pro +++ b/tests/manual/widgets/itemviews/itemviews.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS = delegate qheaderview qtreeview +SUBDIRS = delegate qheaderview qtreeview qtreewidget diff --git a/tests/manual/widgets/itemviews/qtreeview/main.cpp b/tests/manual/widgets/itemviews/qtreeview/main.cpp index 296ba6bcbf..22b4e07f75 100644 --- a/tests/manual/widgets/itemviews/qtreeview/main.cpp +++ b/tests/manual/widgets/itemviews/qtreeview/main.cpp @@ -39,17 +39,34 @@ ** ****************************************************************************/ - -#include <QtWidgets/QFileSystemModel> -#include <QtWidgets/QtWidgets> +#include <QtWidgets> int main(int argc, char *argv[]) { QApplication app(argc, argv); - QFileSystemModel *model = new QFileSystemModel; - model->setRootPath(QDir::currentPath()); - QTreeView *tree = new QTreeView(); - tree->setModel(model); - tree->show(); - app.exec(); + QFileSystemModel model; + QWidget window; + QTreeView *tree = new QTreeView(&window); + tree->setMaximumSize(1000, 600); + + QHBoxLayout *layout = new QHBoxLayout; + layout->setSizeConstraint(QLayout::SetFixedSize); + layout->addWidget(tree); + + window.setLayout(layout); + model.setRootPath(""); + tree->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); + tree->setModel(&model); + + tree->setAnimated(false); + tree->setIndentation(20); + tree->setSortingEnabled(true); + tree->header()->setStretchLastSection(false); + + window.setWindowTitle(QObject::tr("Dir View")); + tree->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + + window.show(); + + return app.exec(); } diff --git a/tests/manual/widgets/itemviews/qtreewidget/main.cpp b/tests/manual/widgets/itemviews/qtreewidget/main.cpp new file mode 100644 index 0000000000..9428113250 --- /dev/null +++ b/tests/manual/widgets/itemviews/qtreewidget/main.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QVBoxLayout> +#include <QTreeWidget> +#include <QGroupBox> +#include <QRadioButton> +#include <QDialog> +#include <QApplication> +#include <QHeaderView> + +class ExampleDlg : public QDialog +{ + Q_OBJECT +public: + QVBoxLayout *groupLayout; + QVBoxLayout *dialogLayout; + QTreeWidget *treeWidget; + QGroupBox *groupBox; + QRadioButton *radioFirstName; + QRadioButton *radioLastName; + QRadioButton *radioDeveloperNo; + QRadioButton *radioTitle; + + ExampleDlg() : QDialog(0) + { + dialogLayout = new QVBoxLayout(this); + treeWidget = new QTreeWidget(this); + dialogLayout->addWidget(treeWidget); + + groupBox = new QGroupBox(this); + groupLayout = new QVBoxLayout(groupBox); + radioFirstName = new QRadioButton("First Name", groupBox); + groupLayout->addWidget(radioFirstName); + radioLastName = new QRadioButton("Last Name", groupBox); + groupLayout->addWidget(radioLastName); + radioDeveloperNo = new QRadioButton("Developer No.", groupBox); + groupLayout->addWidget(radioDeveloperNo); + radioTitle = new QRadioButton("Title", groupBox); + groupLayout->addWidget(radioTitle); + dialogLayout->addWidget(groupBox); + + QStringList item1sl("Barry"); + item1sl.append("Butter"); + item1sl.append("12199"); + item1sl.append("Key Maintainer"); + QTreeWidgetItem *item1 = new QTreeWidgetItem(treeWidget, item1sl); + + QStringList item2sl("Cordon"); + item2sl.append("Rampsey"); + item2sl.append("59299"); + item2sl.append("Maintainer"); + QTreeWidgetItem *item2 = new QTreeWidgetItem(item1, item2sl); + + QStringList item3sl("Samuel le"); + item3sl.append("Smackson"); + item3sl.append("708"); + item3sl.append("Contributer"); + /* QTreeWidgetItem *item3 = */ new QTreeWidgetItem(item2, item3sl); + + QStringList item4sl("Georg"); + item4sl.append("Ambush"); + item4sl.append("86999"); + item4sl.append("Area Maintainer"); + QTreeWidgetItem *item4 = new QTreeWidgetItem(item1, item4sl); + + QStringList item5sl("Arne"); + item5sl.append("Strassenleger"); + item5sl.append("338999"); + item5sl.append("Approver"); + /* QTreeWidgetItem *item4 =*/ new QTreeWidgetItem(item4, item5sl); + + treeWidget->setColumnCount(item2sl.size()); + QStringList itemInfo("First Name"); + itemInfo.append("Last Name"); + itemInfo.append("Developer No."); + // Developer no. could also have been social security number og some other id. + itemInfo.append("Title"); + treeWidget->setHeaderLabels(itemInfo); + radioFirstName->setChecked(true); + + connect(radioFirstName, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); + connect(radioLastName, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); + connect(radioDeveloperNo, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); + connect(radioTitle, SIGNAL(toggled(bool)), this, SLOT(fixDataInTree(bool))); + treeWidget->setTreePosition(-1); + } + + protected slots: + void fixDataInTree(bool checked) + { + if (!checked) + return; + int colInTree = 0; // first Name + if (radioLastName->isChecked()) + colInTree = 1; + if (radioDeveloperNo->isChecked()) + colInTree = 2; + if (radioTitle->isChecked()) + colInTree = 3; + treeWidget->header()->swapSections(0, treeWidget->header()->visualIndex(colInTree)); + } +}; + + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + ExampleDlg d; + d.show(); + app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro b/tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro new file mode 100644 index 0000000000..4b1da9be38 --- /dev/null +++ b/tests/manual/widgets/itemviews/qtreewidget/qtreewidgettest.pro @@ -0,0 +1,4 @@ +TEMPLATE = app +SOURCES = main.cpp +QT += widgets core-private +DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/manual/widgets/kernel/kernel.pro b/tests/manual/widgets/kernel/kernel.pro new file mode 100644 index 0000000000..968d71724f --- /dev/null +++ b/tests/manual/widgets/kernel/kernel.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = qtooltip sizeonhide diff --git a/tests/manual/widgets/kernel/qtooltip/main.cpp b/tests/manual/widgets/kernel/qtooltip/main.cpp new file mode 100644 index 0000000000..a7a2b9915c --- /dev/null +++ b/tests/manual/widgets/kernel/qtooltip/main.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Lund Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTest> +#include <QDialog> +#include <QToolTip> +#include <QLabel> +#include <QPushButton> +#include <QVBoxLayout> +#include <QProxyStyle> +#include <QSpinBox> + +class QToolTipTest : public QProxyStyle +{ + Q_OBJECT +public: + QToolTipTest() : QProxyStyle() + { + wakeTime = QApplication::style()->styleHint(SH_ToolTip_WakeUpDelay); + sleepTime = QApplication::style()->styleHint(SH_ToolTip_FallAsleepDelay); + } + + int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, + QStyleHintReturn *returnData = 0) const + { + switch (hint) { + case SH_ToolTip_WakeUpDelay: + return wakeTime; + case SH_ToolTip_FallAsleepDelay: + return sleepTime; + default: + return QProxyStyle::styleHint(hint, option, widget, returnData); + } + } + +public slots: + void setWakeTime(int wake) { wakeTime = wake; } + void setSleepTime(int sleep) { sleepTime = sleep; } +protected: + int wakeTime; + int sleepTime; +}; + +class TestDialog : public QDialog +{ + Q_OBJECT +public: + TestDialog(QToolTipTest *s); + QToolTipTest *style; +protected slots: + void showSomeToolTips(); +}; + +void TestDialog::showSomeToolTips() +{ + QPoint p(100 + 20, 100 + 20); + + for (int u = 1; u < 20; u += 5) { + QString s = tr("Seconds: ") + QString::number(u); + QToolTip::showText(p, s, 0, QRect(), 1000 * u); + QTest::qWait((u + 1) * 1000); + } + + QToolTip::showText(p, tr("Seconds: 2"), 0, QRect(), 2000); + QTest::qWait(3000); + + QToolTip::showText(p, tr("Standard label"), 0, QRect()); + QTest::qWait(12000); +} + +TestDialog::TestDialog(QToolTipTest *s) : style(s) +{ + // Notice that these tool tips will disappear if another tool tip is shown. + QLabel *label1 = new QLabel(tr("Tooltip - Only two seconds display")); + label1->setToolTip(tr("2 seconds display")); + label1->setToolTipDuration(2000); + Q_ASSERT(label1->toolTipDuration() == 2000); + + QLabel *label2 = new QLabel(tr("Tooltip - 30 seconds display time")); + label2->setToolTip(tr("30 seconds display")); + label2->setToolTipDuration(30000); + + QPushButton *pb = new QPushButton(tr("&Test")); + pb->setToolTip(tr("Show some tool tips.")); + Q_ASSERT(pb->toolTipDuration() == -1); + connect(pb, SIGNAL(clicked()), this, SLOT(showSomeToolTips())); + + QLabel *wakeLabel = new QLabel(tr("Wake Delay:")); + QSpinBox *wakeSpinBox = new QSpinBox(); + wakeSpinBox->setRange(0, 100000); + wakeSpinBox->setValue(style->styleHint(QStyle::SH_ToolTip_WakeUpDelay)); + connect(wakeSpinBox, SIGNAL(valueChanged(int)), style, SLOT(setWakeTime(int))); + + QLabel *sleepLabel = new QLabel(tr("Sleep Delay:")); + QSpinBox *sleepSpinBox = new QSpinBox(); + sleepSpinBox->setRange(0, 100000); + sleepSpinBox->setValue(style->styleHint(QStyle::SH_ToolTip_FallAsleepDelay)); + connect(sleepSpinBox, SIGNAL(valueChanged(int)), style, SLOT(setSleepTime(int))); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(label1); + layout->addWidget(label2); + layout->addWidget(pb); + layout->addWidget(wakeLabel); + layout->addWidget(wakeSpinBox); + layout->addWidget(wakeLabel); + layout->addWidget(sleepLabel); + layout->addWidget(sleepSpinBox); + + setLayout(layout); +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QToolTipTest *style = new QToolTipTest(); + QApplication::setStyle(style); + TestDialog dlg(style); + dlg.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/widgets/kernel/qtooltip/main.pro b/tests/manual/widgets/kernel/qtooltip/main.pro new file mode 100644 index 0000000000..dac880a10e --- /dev/null +++ b/tests/manual/widgets/kernel/qtooltip/main.pro @@ -0,0 +1,2 @@ +SOURCES = main.cpp +QT += widgets testlib diff --git a/tests/manual/widgets/kernel/sizeonhide/main.cpp b/tests/manual/widgets/kernel/sizeonhide/main.cpp new file mode 100644 index 0000000000..e8b95dfe28 --- /dev/null +++ b/tests/manual/widgets/kernel/sizeonhide/main.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Thorbjørn Martsum - tmartsum[at]gmail.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, 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, Digia gives you certain additional +** rights. These rights are described in the Digia 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. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWidgets> + +class KeepSizeExampleDlg : public QDialog +{ + Q_OBJECT +public: + QGridLayout *gridLayout; + QHBoxLayout *horizontalLayout; + QVBoxLayout *verticalLayout; + QCheckBox *checkBox; + QCheckBox *checkBox2; + QCheckBox *checkBox3; + QCheckBox *checkBox4; + QGroupBox *groupBox; + QVBoxLayout *verticalLayout2; + QRadioButton *radioButton; + QRadioButton *radioButton2; + QRadioButton *radioButton3; + QTableView *tableView; + QPushButton *pushButton; + QSpacerItem *horizontalSpacer; + + KeepSizeExampleDlg() + { + QWidget *form = this; + form->resize(408, 295); + gridLayout = new QGridLayout(form); + horizontalLayout = new QHBoxLayout(); + verticalLayout = new QVBoxLayout(); + checkBox = new QCheckBox(form); + verticalLayout->addWidget(checkBox); + checkBox2 = new QCheckBox(form); + verticalLayout->addWidget(checkBox2); + checkBox3 = new QCheckBox(form); + verticalLayout->addWidget(checkBox3); + checkBox4 = new QCheckBox(form); + verticalLayout->addWidget(checkBox4); + horizontalLayout->addLayout(verticalLayout); + groupBox = new QGroupBox(form); + verticalLayout2 = new QVBoxLayout(groupBox); + radioButton = new QRadioButton(groupBox); + verticalLayout2->addWidget(radioButton); + radioButton2 = new QRadioButton(groupBox); + verticalLayout2->addWidget(radioButton2); + radioButton3 = new QRadioButton(groupBox); + verticalLayout2->addWidget(radioButton3); + horizontalLayout->addWidget(groupBox); + gridLayout->addLayout(horizontalLayout, 0, 0, 1, 2); + tableView = new QTableView(form); + gridLayout->addWidget(tableView, 1, 0, 1, 2); + pushButton = new QPushButton(form); + gridLayout->addWidget(pushButton, 2, 0, 1, 1); + horizontalSpacer = new QSpacerItem(340, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + gridLayout->addItem(horizontalSpacer, 2, 1, 1, 1); + checkBox->setText(QString::fromUtf8("CheckBox1")); + checkBox2->setText(QString::fromUtf8("CheckBox2")); + checkBox3->setText(QString::fromUtf8("CheckBox - for client A only")); + checkBox4->setText(QString::fromUtf8("CheckBox - also for client A")); + groupBox->setTitle(QString::fromUtf8("Mode")); + radioButton->setText(QString::fromUtf8("Mode 1")); + radioButton2->setText(QString::fromUtf8("Mode 2")); + radioButton3->setText(QString::fromUtf8("Mode 3")); + pushButton->setText(QString::fromUtf8("&Hide/Show")); + + QObject::connect(pushButton, SIGNAL(clicked()), this, SLOT(showOrHide())); + } + + protected slots: + void showOrHide() + { + if (checkBox3->isVisible()) { + checkBox3->hide(); + checkBox4->hide(); + } else { + checkBox3->show(); + checkBox4->show(); + } + } +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + KeepSizeExampleDlg d; + QSizePolicy policyKeepSpace = d.checkBox3->sizePolicy(); + policyKeepSpace.setRetainSizeWhenHidden(true); + d.checkBox3->setSizePolicy(policyKeepSpace); + d.checkBox4->setSizePolicy(policyKeepSpace); + d.show(); + app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro b/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro new file mode 100644 index 0000000000..1969392ab3 --- /dev/null +++ b/tests/manual/widgets/kernel/sizeonhide/sizeonhide.pro @@ -0,0 +1,3 @@ +TEMPLATE = app +SOURCES = main.cpp +QT += widgets core-private diff --git a/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp b/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp index aec2479239..bb05570f18 100644 --- a/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp +++ b/tests/manual/widgets/qgraphicsview/rubberband/rubberbandtest.cpp @@ -49,7 +49,7 @@ public: setFlags(QGraphicsItem::ItemIsSelectable); } - void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option*/, QWidget * /*widget*/) + void paint(QPainter *painter, const QStyleOptionGraphicsItem * /* option*/, QWidget * /*widget*/) Q_DECL_OVERRIDE { if (isSelected()) painter->fillRect(rect(), QColor(255, 0, 0)); @@ -68,7 +68,7 @@ public: connect(this, SIGNAL(rubberBandChanged(QRect, QPointF, QPointF)), this, SLOT(updateRubberbandInfo(QRect, QPointF, QPointF))); } protected: - void mouseMoveEvent(QMouseEvent *event) + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE { QGraphicsView::mouseMoveEvent(event); diff --git a/tests/manual/widgets/widgets.pro b/tests/manual/widgets/widgets.pro index 4e2e4c7cee..e9dcdf39e7 100644 --- a/tests/manual/widgets/widgets.pro +++ b/tests/manual/widgets/widgets.pro @@ -1,2 +1,3 @@ TEMPLATE = subdirs -SUBDIRS = itemviews qgraphicsview +SUBDIRS = itemviews qgraphicsview kernel + |