/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** 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. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Test uninitialized variables allocing memory bool optTestUninitialized = false; bool optTestAll = false; bool optEmptyContainers = false; unsigned optVerbose = 0; const char *appPath = 0; // Provide address of type of be tested. // When testing uninitialized memory, allocate at random. template inline T* testAddress(T* in) { unsigned char *mem = 0; if (optTestUninitialized) { mem = new unsigned char[sizeof(T)]; for (unsigned int i = 0; i < sizeof(T); i++) { mem[i] = char(rand() % 255u); } } else { mem = reinterpret_cast(in); } if (optVerbose) { for (unsigned int i = 0; i < sizeof(T); i++) { unsigned int b = mem[i]; printf("%2d %2x %3d\n", i, b, b); } fflush(stdout); } return reinterpret_cast(mem); } /* Test program for Dumper development/porting. * Takes the type as first argument. */ // --------------- Dumper symbols extern char qDumpInBuffer[10000]; extern char qDumpOutBuffer[100000]; extern "C" void *qDumpObjectData440( int protocolVersion, int token, void *data, #ifdef Q_CC_MSVC // CDB cannot handle boolean parameters int dumpChildren, #else bool dumpChildren, #endif int extraInt0, int extraInt1, int extraInt2, int extraInt3); static void prepareInBuffer(const char *outerType, const char *iname, const char *expr, const char *innerType) { // Leave trailing '\0' char *ptr = qDumpInBuffer; strcpy(ptr, outerType); ptr += strlen(outerType); ptr++; strcpy(ptr, iname); ptr += strlen(iname); ptr++; strcpy(ptr, expr); ptr += strlen(expr); ptr++; strcpy(ptr, innerType); ptr += strlen(innerType); ptr++; strcpy(ptr, iname); } // --------------- Qt types static int dumpQString() { QString test = QLatin1String("hallo"); prepareInBuffer("QString", "local.qstring", "local.qstring", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); QString uninitialized; return 0; } static int dumpQSharedPointerQString() { QSharedPointer test(new QString(QLatin1String("hallo"))); prepareInBuffer("QSharedPointer", "local.sharedpointerqstring", "local.local.sharedpointerqstring", "QString"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); QString uninitialized; return 0; } static int dumpQStringList() { QStringList test = QStringList() << QLatin1String("item1") << QLatin1String("item2"); prepareInBuffer("QList", "local.qstringlist", "local.qstringlist", "QString"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQIntList() { QList test = QList() << 1 << 2; prepareInBuffer("QList", "local.qintlist", "local.qintlist", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQIntLinkedList() { QLinkedList test = QLinkedList() << 1 << 2; prepareInBuffer("QLinkedList", "local.qintlinkedlist", "local.qlinkedintlist", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQIntVector() { QVector test = QVector() << 42 << 43; prepareInBuffer("QVector", "local.qintvector", "local.qintvector", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQQStringVector() { QVector test = QVector() << "42s" << "43s"; prepareInBuffer("QVector", "local.qstringvector", "local.qstringvector", "QString"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQMapIntInt() { QMap test; QMapNode mapNode; const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode; if (!optEmptyContainers) { test.insert(42, 43); test.insert(43, 44); } prepareInBuffer("QMap", "local.qmapintint", "local.qmapintint", "int@int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(int), sizeof(mapNode), valueOffset); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQMapIntString() { QMap test; QMapNode mapNode; const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode; if (!optEmptyContainers) { test.insert(42, QLatin1String("fortytwo")); test.insert(43, QLatin1String("fortytree")); } prepareInBuffer("QMap", "local.qmapintqstring", "local.qmapintqstring", "int@QString"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(QString), sizeof(mapNode), valueOffset); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQSetInt() { QSet test; if (!optEmptyContainers) { test.insert(42); test.insert(43); } prepareInBuffer("QSet", "local.qsetint", "local.qsetint", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQMapQStringString() { QMap test; QMapNode mapNode; const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode; if (!optEmptyContainers) { test.insert(QLatin1String("42s"), QLatin1String("fortytwo")); test.insert(QLatin1String("423"), QLatin1String("fortytree")); } prepareInBuffer("QMap", "local.qmapqstringqstring", "local.qmapqstringqstring", "QString@QString"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), sizeof(QString), sizeof(mapNode), valueOffset); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQVariant() { QVariant test = QLatin1String("item"); prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); fputs(qDumpOutBuffer, stdout); fputs("\n\n", stdout); test = QVariant(int(42)); prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); fputs(qDumpOutBuffer, stdout); fputs("\n\n", stdout); test = QVariant(double(3.141)); prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); fputs(qDumpOutBuffer, stdout); fputs("\n\n", stdout); test = QVariant(QStringList(QLatin1String("item1"))); prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); fputs(qDumpOutBuffer, stdout); test = QVariant(QRect(1,2, 3, 4)); prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); fputs(qDumpOutBuffer, stdout); return 0; } static int dumpQVariantList() { QVariantList test; if (!optEmptyContainers) { test.push_back(QVariant(QLatin1String("hallo"))); test.push_back(QVariant(42)); test.push_back(QVariant(3.141)); } // As a list prepareInBuffer("QList", "local.qvariantlist", "local.qvariantlist", "QVariant"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QVariant), 0,0 ,0); fputs(qDumpOutBuffer, stdout); // As typedef fputs("\n\n", stdout); prepareInBuffer("QVariantList", "local.qvariantlist", "local.qvariantlist", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } // --------------- std types static int dumpStdString() { std::string test = "hallo"; prepareInBuffer("std::string", "local.string", "local.string", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdWString() { std::wstring test = L"hallo"; prepareInBuffer("std::wstring", "local.wstring", "local.wstring", ""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdStringList() { std::list test; if (!optEmptyContainers) { test.push_back("item1"); test.push_back("item2"); } prepareInBuffer("std::list", "local.stringlist", "local.stringlist", "std::string"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdStringQList() { QList test; if (!optEmptyContainers) { test.push_back("item1"); test.push_back("item2"); } prepareInBuffer("QList", "local.stringqlist", "local.stringqlist", "std::string"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdIntList() { std::list test; if (!optEmptyContainers) { test.push_back(1); test.push_back(2); } prepareInBuffer("std::list", "local.intlist", "local.intlist", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdIntVector() { std::vector test; if (!optEmptyContainers) { test.push_back(1); test.push_back(2); } prepareInBuffer("std::vector", "local.intvector", "local.intvector", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdStringVector() { std::vector test; if (!optEmptyContainers) { test.push_back("item1"); test.push_back("item2"); } prepareInBuffer("std::vector", "local.stringvector", "local.stringvector", "std::string"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdWStringVector() { std::vector test; if (!optEmptyContainers) { test.push_back(L"item1"); test.push_back(L"item2"); } prepareInBuffer("std::vector", "local.wstringvector", "local.wstringvector", "std::wstring"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::wstring), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdIntSet() { std::set test; if (!optEmptyContainers) { test.insert(1); test.insert(2); } prepareInBuffer("std::set", "local.intset", "local.intset", "int"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdStringSet() { std::set test; if (!optEmptyContainers) { test.insert("item1"); test.insert("item2"); } prepareInBuffer("std::set", "local.stringset", "local.stringset", "std::string"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdQStringSet() { std::set test; if (!optEmptyContainers) { test.insert(QLatin1String("item1")); test.insert(QLatin1String("item2")); } prepareInBuffer("std::set", "local.stringset", "local.stringset", "QString"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), sizeof(std::list::allocator_type), 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdMapIntString() { std::map test; std::map::value_type entry(42, std::string("fortytwo")); if (!optEmptyContainers) { test.insert(entry); } const int valueOffset = (char*)&(entry.second) - (char*)&entry; prepareInBuffer("std::map", "local.stdmapintstring", "local.stdmapintstring", "int@std::basic_string,std::allocator >@std::less@std::allocator,std::allocator > > >"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::string), valueOffset, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpStdMapStringString() { typedef std::map TestType; TestType test; const TestType::value_type entry("K", "V"); if (!optEmptyContainers) { test.insert(entry); } const int valueOffset = (char*)&(entry.second) - (char*)&entry; prepareInBuffer("std::map", "local.stdmapstringstring", "local.stdmapstringstring", "std::basic_string,std::allocator >@std::basic_string,std::allocator >@std::less@std::allocator,std::allocator >,std::basic_string,std::allocator > > >"); qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::string), valueOffset, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQObject() { // Requires the childOffset to be know, but that is not critical QAction action(0); QObject x; QAction *a2= new QAction(&action); a2->setObjectName(QLatin1String("a2")); action.setObjectName(QLatin1String("action")); QObject::connect(&action, SIGNAL(triggered()), &x, SLOT(deleteLater())); prepareInBuffer("QObject", "local.qobject", "local.qobject", ""); qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputs("\n\n", stdout); // Property list prepareInBuffer("QObjectPropertyList", "local.qobjectpropertylist", "local.qobjectpropertylist", ""); qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputs("\n\n", stdout); // Signal list prepareInBuffer("QObjectSignalList", "local.qobjectsignallist", "local.qobjectsignallist", ""); qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); // Slot list prepareInBuffer("QObjectSlotList", "local.qobjectslotlist", "local.qobjectslotlist", ""); qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputs("\n\n", stdout); // Signal list prepareInBuffer("QObjectChildList", "local.qobjectchildlist", "local.qobjectchildlist", ""); qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); return 0; } static int dumpQFileInfo() { QFileInfo test(QString::fromLatin1(appPath)); prepareInBuffer("QFileInfo", "local.qfileinfo", "local.qfileinfo",""); qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; } static int dumpQObjectList() { // Requires the childOffset to be know, but that is not critical QObject *root = new QObject; root ->setObjectName("root"); QTimer *t1 = new QTimer; t1 ->setObjectName("t1"); QTimer *t2 = new QTimer; t2 ->setObjectName("t2"); QObjectList test; test << root << t1 << t2; prepareInBuffer("QList", "local.qobjectlist", "local.qobjectlist", "QObject *"); qDumpObjectData440(2, 42, testAddress(&test), sizeof(QObject*), 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); delete root; return 0; } typedef int (*DumpFunction)(); typedef QMap TypeDumpFunctionMap; static TypeDumpFunctionMap registerTypes() { TypeDumpFunctionMap rc; rc.insert("QString", dumpQString); rc.insert("QSharedPointer", dumpQSharedPointerQString); rc.insert("QStringList", dumpQStringList); rc.insert("QList", dumpQIntList); rc.insert("QLinkedList", dumpQIntLinkedList); rc.insert("QList", dumpStdStringQList); rc.insert("QVector", dumpQIntVector); rc.insert("QVector", dumpQQStringVector); rc.insert("QMap", dumpQMapIntString); rc.insert("QMap", dumpQMapQStringString); rc.insert("QMap", dumpQMapIntInt); rc.insert("QSet", dumpQSetInt); rc.insert("string", dumpStdString); rc.insert("wstring", dumpStdWString); rc.insert("list", dumpStdIntList); rc.insert("list", dumpStdStringList); rc.insert("vector", dumpStdIntVector); rc.insert("vector", dumpStdStringVector); rc.insert("vector", dumpStdWStringVector); rc.insert("set", dumpStdIntSet); rc.insert("set", dumpStdStringSet); rc.insert("set", dumpStdQStringSet); rc.insert("map", dumpStdMapIntString); rc.insert("map", dumpStdMapStringString); rc.insert("QFileInfo", dumpQFileInfo); rc.insert("QObject", dumpQObject); rc.insert("QObjectList", dumpQObjectList); rc.insert("QVariant", dumpQVariant); rc.insert("QVariantList", dumpQVariantList); return rc; } static void usage(const char *b, const TypeDumpFunctionMap &tdm) { printf("Usage: %s [-v][-u][-e] \n", b); printf("Usage: %s [-v][-u][-e] -a excluded_type1 \n", b); printf("Options: -u Test uninitialized memory\n"); printf(" -e Empty containers\n"); printf(" -v Verbose\n"); printf(" -a Test all available types\n"); printf("Supported types: "); const TypeDumpFunctionMap::const_iterator cend = tdm.constEnd(); for (TypeDumpFunctionMap::const_iterator it = tdm.constBegin(); it != cend; ++it) { fputs(qPrintable(it.key()), stdout); fputc(' ', stdout); } fputc('\n', stdout); } int main(int argc, char *argv[]) { appPath = argv[0]; printf("\nQt Creator Debugging Helper testing tool\n\n"); printf("Running query protocol\n"); qDumpObjectData440(1, 42, 0, 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); fputc('\n', stdout); const TypeDumpFunctionMap tdm = registerTypes(); const TypeDumpFunctionMap::const_iterator cend = tdm.constEnd(); if (argc < 2) { usage(argv[0], tdm); return 0; } // Parse args QStringList tests; for (int a = 1; a < argc; a++) { const char *arg = argv[a]; if (arg[0] == '-') { switch (arg[1]) { case 'a': optTestAll = true; break; case 'u': optTestUninitialized = true; break; case 'v': optVerbose++; break; case 'e': optEmptyContainers = true; break; default: fprintf(stderr, "Invalid option %s\n", arg); usage(argv[0], tdm); return -1; } } else { tests.push_back(QLatin1String(arg)); } } // Go int rc = 0; if (optTestAll) { for (TypeDumpFunctionMap::const_iterator it = tdm.constBegin(); it != cend; ++it) { const QString test = it.key(); if (tests.contains(test)) { printf("\nSkipping: %s\n", qPrintable(test)); } else { printf("\nTesting: %s\n", qPrintable(test)); rc += (*it.value())(); if (optTestUninitialized) printf("Survived: %s\n", qPrintable(test)); } } } else { foreach(const QString &test, tests) { printf("\nTesting: %s\n", qPrintable(test)); const TypeDumpFunctionMap::const_iterator it = tdm.constFind(test); if (it == cend) { rc = -1; fprintf(stderr, "\nUnhandled type: %s\n", qPrintable(test)); } else { rc = (*it.value())(); } } } return rc; }