1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
34 #include <QtCore/QStringList>
35 #include <QtCore/QLinkedList>
36 #include <QtCore/QVector>
37 #include <QtCore/QSharedPointer>
38 #include <QtCore/QTimer>
39 #include <QtCore/QMap>
40 #include <QtCore/QSet>
41 #include <QtCore/QVariant>
42 #include <QtCore/QFileInfo>
43 #include <QtCore/QCoreApplication>
44 #include <QtGui/QAction>
55 // Test uninitialized variables allocing memory
56 bool optTestUninitialized = false;
57 bool optTestAll = false;
58 bool optEmptyContainers = false;
59 unsigned optVerbose = 0;
60 const char *appPath = 0;
62 // Provide address of type of be tested.
63 // When testing uninitialized memory, allocate at random.
65 inline T* testAddress(T* in)
67 unsigned char *mem = 0;
68 if (optTestUninitialized) {
69 mem = new unsigned char[sizeof(T)];
70 for (unsigned int i = 0; i < sizeof(T); i++) {
71 mem[i] = char(rand() % 255u);
74 mem = reinterpret_cast<unsigned char*>(in);
77 for (unsigned int i = 0; i < sizeof(T); i++) {
78 unsigned int b = mem[i];
79 printf("%2d %2x %3d\n", i, b, b);
83 return reinterpret_cast<T*>(mem);
86 /* Test program for Dumper development/porting.
87 * Takes the type as first argument. */
89 // --------------- Dumper symbols
90 extern char qDumpInBuffer[10000];
91 extern char qDumpOutBuffer[100000];
93 extern "C" void *qDumpObjectData440(
97 #ifdef Q_CC_MSVC // CDB cannot handle boolean parameters
102 int extraInt0, int extraInt1, int extraInt2, int extraInt3);
104 static void prepareInBuffer(const char *outerType,
107 const char *innerType)
109 // Leave trailing '\0'
110 char *ptr = qDumpInBuffer;
111 strcpy(ptr, outerType);
112 ptr += strlen(outerType);
115 ptr += strlen(iname);
120 strcpy(ptr, innerType);
121 ptr += strlen(innerType);
126 // --------------- Qt types
127 static int dumpQString()
129 QString test = QLatin1String("hallo");
130 prepareInBuffer("QString", "local.qstring", "local.qstring", "");
131 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0);
132 fputs(qDumpOutBuffer, stdout);
134 QString uninitialized;
138 static int dumpQSharedPointerQString()
140 QSharedPointer<QString> test(new QString(QLatin1String("hallo")));
141 prepareInBuffer("QSharedPointer", "local.sharedpointerqstring", "local.local.sharedpointerqstring", "QString");
142 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0);
143 fputs(qDumpOutBuffer, stdout);
145 QString uninitialized;
149 static int dumpQStringList()
151 QStringList test = QStringList() << QLatin1String("item1") << QLatin1String("item2");
152 prepareInBuffer("QList", "local.qstringlist", "local.qstringlist", "QString");
153 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0);
154 fputs(qDumpOutBuffer, stdout);
159 static int dumpQIntList()
161 QList<int> test = QList<int>() << 1 << 2;
162 prepareInBuffer("QList", "local.qintlist", "local.qintlist", "int");
163 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0);
164 fputs(qDumpOutBuffer, stdout);
169 static int dumpQIntLinkedList()
171 QLinkedList<int> test = QLinkedList<int>() << 1 << 2;
172 prepareInBuffer("QLinkedList", "local.qintlinkedlist", "local.qlinkedintlist", "int");
173 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0);
174 fputs(qDumpOutBuffer, stdout);
179 static int dumpQIntVector()
181 QVector<int> test = QVector<int>() << 42 << 43;
182 prepareInBuffer("QVector", "local.qintvector", "local.qintvector", "int");
183 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0);
184 fputs(qDumpOutBuffer, stdout);
189 static int dumpQQStringVector()
191 QVector<QString> test = QVector<QString>() << "42s" << "43s";
192 prepareInBuffer("QVector", "local.qstringvector", "local.qstringvector", "QString");
193 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), 0, 0, 0);
194 fputs(qDumpOutBuffer, stdout);
199 static int dumpQMapIntInt()
202 QMapNode<int,int> mapNode;
203 const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode;
204 if (!optEmptyContainers) {
208 prepareInBuffer("QMap", "local.qmapintint", "local.qmapintint", "int@int");
209 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(int), sizeof(mapNode), valueOffset);
210 fputs(qDumpOutBuffer, stdout);
215 static int dumpQMapIntString()
217 QMap<int,QString> test;
218 QMapNode<int,QString> mapNode;
219 const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode;
220 if (!optEmptyContainers) {
221 test.insert(42, QLatin1String("fortytwo"));
222 test.insert(43, QLatin1String("fortytree"));
224 prepareInBuffer("QMap", "local.qmapintqstring", "local.qmapintqstring", "int@QString");
225 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(QString), sizeof(mapNode), valueOffset);
226 fputs(qDumpOutBuffer, stdout);
231 static int dumpQSetInt()
234 if (!optEmptyContainers) {
238 prepareInBuffer("QSet", "local.qsetint", "local.qsetint", "int");
239 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), 0, 0, 0);
240 fputs(qDumpOutBuffer, stdout);
246 static int dumpQMapQStringString()
248 QMap<QString,QString> test;
249 QMapNode<QString,QString> mapNode;
250 const int valueOffset = (char*)&(mapNode.value) - (char*)&mapNode;
251 if (!optEmptyContainers) {
252 test.insert(QLatin1String("42s"), QLatin1String("fortytwo"));
253 test.insert(QLatin1String("423"), QLatin1String("fortytree"));
255 prepareInBuffer("QMap", "local.qmapqstringqstring", "local.qmapqstringqstring", "QString@QString");
256 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), sizeof(QString), sizeof(mapNode), valueOffset);
257 fputs(qDumpOutBuffer, stdout);
262 static int dumpQVariant()
264 QVariant test = QLatin1String("item");
265 prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
266 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
267 fputs(qDumpOutBuffer, stdout);
268 fputs("\n\n", stdout);
269 test = QVariant(int(42));
270 prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
271 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
272 fputs(qDumpOutBuffer, stdout);
273 fputs("\n\n", stdout);
274 test = QVariant(double(3.141));
275 prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
276 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
277 fputs(qDumpOutBuffer, stdout);
278 fputs("\n\n", stdout);
279 test = QVariant(QStringList(QLatin1String("item1")));
280 prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
281 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
282 fputs(qDumpOutBuffer, stdout);
283 test = QVariant(QRect(1,2, 3, 4));
284 prepareInBuffer("QVariant", "local.qvariant", "local.qvariant", "");
285 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
286 fputs(qDumpOutBuffer, stdout);
290 static int dumpQVariantList()
293 if (!optEmptyContainers) {
294 test.push_back(QVariant(QLatin1String("hallo")));
295 test.push_back(QVariant(42));
296 test.push_back(QVariant(3.141));
299 prepareInBuffer("QList", "local.qvariantlist", "local.qvariantlist", "QVariant");
300 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QVariant), 0,0 ,0);
301 fputs(qDumpOutBuffer, stdout);
303 fputs("\n\n", stdout);
304 prepareInBuffer("QVariantList", "local.qvariantlist", "local.qvariantlist", "");
305 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0,0 ,0);
306 fputs(qDumpOutBuffer, stdout);
311 // --------------- std types
313 static int dumpStdString()
315 std::string test = "hallo";
316 prepareInBuffer("std::string", "local.string", "local.string", "");
317 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0);
318 fputs(qDumpOutBuffer, stdout);
323 static int dumpStdWString()
325 std::wstring test = L"hallo";
326 prepareInBuffer("std::wstring", "local.wstring", "local.wstring", "");
327 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0);
328 fputs(qDumpOutBuffer, stdout);
333 static int dumpStdStringList()
335 std::list<std::string> test;
336 if (!optEmptyContainers) {
337 test.push_back("item1");
338 test.push_back("item2");
340 prepareInBuffer("std::list", "local.stringlist", "local.stringlist", "std::string");
341 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::list<std::string>::allocator_type), 0, 0);
342 fputs(qDumpOutBuffer, stdout);
347 static int dumpStdStringQList()
349 QList<std::string> test;
350 if (!optEmptyContainers) {
351 test.push_back("item1");
352 test.push_back("item2");
354 prepareInBuffer("QList", "local.stringqlist", "local.stringqlist", "std::string");
355 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), 0, 0, 0);
356 fputs(qDumpOutBuffer, stdout);
361 static int dumpStdIntList()
364 if (!optEmptyContainers) {
368 prepareInBuffer("std::list", "local.intlist", "local.intlist", "int");
369 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0);
370 fputs(qDumpOutBuffer, stdout);
375 static int dumpStdIntVector()
377 std::vector<int> test;
378 if (!optEmptyContainers) {
382 prepareInBuffer("std::vector", "local.intvector", "local.intvector", "int");
383 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0);
384 fputs(qDumpOutBuffer, stdout);
389 static int dumpStdStringVector()
391 std::vector<std::string> test;
392 if (!optEmptyContainers) {
393 test.push_back("item1");
394 test.push_back("item2");
396 prepareInBuffer("std::vector", "local.stringvector", "local.stringvector", "std::string");
397 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0);
398 fputs(qDumpOutBuffer, stdout);
403 static int dumpStdWStringVector()
405 std::vector<std::wstring> test;
406 if (!optEmptyContainers) {
407 test.push_back(L"item1");
408 test.push_back(L"item2");
410 prepareInBuffer("std::vector", "local.wstringvector", "local.wstringvector", "std::wstring");
411 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::wstring), sizeof(std::list<int>::allocator_type), 0, 0);
412 fputs(qDumpOutBuffer, stdout);
417 static int dumpStdIntSet()
420 if (!optEmptyContainers) {
424 prepareInBuffer("std::set", "local.intset", "local.intset", "int");
425 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0);
426 fputs(qDumpOutBuffer, stdout);
431 static int dumpStdStringSet()
433 std::set<std::string> test;
434 if (!optEmptyContainers) {
435 test.insert("item1");
436 test.insert("item2");
438 prepareInBuffer("std::set", "local.stringset", "local.stringset", "std::string");
439 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0);
440 fputs(qDumpOutBuffer, stdout);
445 static int dumpStdQStringSet()
447 std::set<QString> test;
448 if (!optEmptyContainers) {
449 test.insert(QLatin1String("item1"));
450 test.insert(QLatin1String("item2"));
452 prepareInBuffer("std::set", "local.stringset", "local.stringset", "QString");
453 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(QString), sizeof(std::list<int>::allocator_type), 0, 0);
454 fputs(qDumpOutBuffer, stdout);
459 static int dumpStdMapIntString()
461 std::map<int,std::string> test;
462 std::map<int,std::string>::value_type entry(42, std::string("fortytwo"));
463 if (!optEmptyContainers) {
466 const int valueOffset = (char*)&(entry.second) - (char*)&entry;
467 prepareInBuffer("std::map", "local.stdmapintstring", "local.stdmapintstring",
468 "int@std::basic_string<char,std::char_traits<char>,std::allocator<char> >@std::less<int>@std::allocator<std::pair<const int,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >");
469 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(int), sizeof(std::string), valueOffset, 0);
470 fputs(qDumpOutBuffer, stdout);
475 static int dumpStdMapStringString()
477 typedef std::map<std::string,std::string> TestType;
479 const TestType::value_type entry("K", "V");
480 if (!optEmptyContainers) {
483 const int valueOffset = (char*)&(entry.second) - (char*)&entry;
484 prepareInBuffer("std::map", "local.stdmapstringstring", "local.stdmapstringstring",
485 "std::basic_string<char,std::char_traits<char>,std::allocator<char> >@std::basic_string<char,std::char_traits<char>,std::allocator<char> >@std::less<int>@std::allocator<std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >");
486 qDumpObjectData440(2, 42, testAddress(&test), 1, sizeof(std::string), sizeof(std::string), valueOffset, 0);
487 fputs(qDumpOutBuffer, stdout);
492 static int dumpQObject()
494 // Requires the childOffset to be know, but that is not critical
497 QAction *a2= new QAction(&action);
498 a2->setObjectName(QLatin1String("a2"));
499 action.setObjectName(QLatin1String("action"));
500 QObject::connect(&action, SIGNAL(triggered()), &x, SLOT(deleteLater()));
501 prepareInBuffer("QObject", "local.qobject", "local.qobject", "");
502 qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0);
503 fputs(qDumpOutBuffer, stdout);
504 fputs("\n\n", stdout);
506 prepareInBuffer("QObjectPropertyList", "local.qobjectpropertylist", "local.qobjectpropertylist", "");
507 qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0);
508 fputs(qDumpOutBuffer, stdout);
509 fputs("\n\n", stdout);
511 prepareInBuffer("QObjectSignalList", "local.qobjectsignallist", "local.qobjectsignallist", "");
512 qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0);
513 fputs(qDumpOutBuffer, stdout);
515 prepareInBuffer("QObjectSlotList", "local.qobjectslotlist", "local.qobjectslotlist", "");
516 qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0);
517 fputs(qDumpOutBuffer, stdout);
518 fputs("\n\n", stdout);
520 prepareInBuffer("QObjectChildList", "local.qobjectchildlist", "local.qobjectchildlist", "");
521 qDumpObjectData440(2, 42, testAddress(&action), 1, 0, 0, 0, 0);
522 fputs(qDumpOutBuffer, stdout);
526 static int dumpQFileInfo()
528 QFileInfo test(QString::fromLatin1(appPath));
529 prepareInBuffer("QFileInfo", "local.qfileinfo", "local.qfileinfo","");
530 qDumpObjectData440(2, 42, testAddress(&test), 1, 0, 0, 0, 0);
531 fputs(qDumpOutBuffer, stdout);
536 static int dumpQObjectList()
538 // Requires the childOffset to be know, but that is not critical
539 QObject *root = new QObject;
540 root ->setObjectName("root");
541 QTimer *t1 = new QTimer;
542 t1 ->setObjectName("t1");
543 QTimer *t2 = new QTimer;
544 t2 ->setObjectName("t2");
546 test << root << t1 << t2;
547 prepareInBuffer("QList", "local.qobjectlist", "local.qobjectlist", "QObject *");
548 qDumpObjectData440(2, 42, testAddress(&test), sizeof(QObject*), 0, 0, 0, 0);
549 fputs(qDumpOutBuffer, stdout);
555 typedef int (*DumpFunction)();
556 typedef QMap<QString, DumpFunction> TypeDumpFunctionMap;
558 static TypeDumpFunctionMap registerTypes()
560 TypeDumpFunctionMap rc;
561 rc.insert("QString", dumpQString);
562 rc.insert("QSharedPointer<QString>", dumpQSharedPointerQString);
563 rc.insert("QStringList", dumpQStringList);
564 rc.insert("QList<int>", dumpQIntList);
565 rc.insert("QLinkedList<int>", dumpQIntLinkedList);
566 rc.insert("QList<std::string>", dumpStdStringQList);
567 rc.insert("QVector<int>", dumpQIntVector);
568 rc.insert("QVector<QString>", dumpQQStringVector);
569 rc.insert("QMap<int,QString>", dumpQMapIntString);
570 rc.insert("QMap<QString,QString>", dumpQMapQStringString);
571 rc.insert("QMap<int,int>", dumpQMapIntInt);
572 rc.insert("QSet<int>", dumpQSetInt);
573 rc.insert("string", dumpStdString);
574 rc.insert("wstring", dumpStdWString);
575 rc.insert("list<int>", dumpStdIntList);
576 rc.insert("list<string>", dumpStdStringList);
577 rc.insert("vector<int>", dumpStdIntVector);
578 rc.insert("vector<string>", dumpStdStringVector);
579 rc.insert("vector<wstring>", dumpStdWStringVector);
580 rc.insert("set<int>", dumpStdIntSet);
581 rc.insert("set<string>", dumpStdStringSet);
582 rc.insert("set<QString>", dumpStdQStringSet);
583 rc.insert("map<int,string>", dumpStdMapIntString);
584 rc.insert("map<string,string>", dumpStdMapStringString);
585 rc.insert("QFileInfo", dumpQFileInfo);
586 rc.insert("QObject", dumpQObject);
587 rc.insert("QObjectList", dumpQObjectList);
588 rc.insert("QVariant", dumpQVariant);
589 rc.insert("QVariantList", dumpQVariantList);
593 static void usage(const char *b, const TypeDumpFunctionMap &tdm)
595 printf("Usage: %s [-v][-u][-e] <type1> <type2..>\n", b);
596 printf("Usage: %s [-v][-u][-e] -a excluded_type1 <excluded_type2...>\n", b);
597 printf("Options: -u Test uninitialized memory\n");
598 printf(" -e Empty containers\n");
599 printf(" -v Verbose\n");
600 printf(" -a Test all available types\n");
601 printf("Supported types: ");
602 const TypeDumpFunctionMap::const_iterator cend = tdm.constEnd();
603 for (TypeDumpFunctionMap::const_iterator it = tdm.constBegin(); it != cend; ++it) {
604 fputs(qPrintable(it.key()), stdout);
610 int main(int argc, char *argv[])
613 printf("\nQt Creator Debugging Helper testing tool\n\n");
614 printf("Running query protocol\n");
615 qDumpObjectData440(1, 42, 0, 1, 0, 0, 0, 0);
616 fputs(qDumpOutBuffer, stdout);
620 const TypeDumpFunctionMap tdm = registerTypes();
621 const TypeDumpFunctionMap::const_iterator cend = tdm.constEnd();
629 for (int a = 1; a < argc; a++) {
630 const char *arg = argv[a];
637 optTestUninitialized = true;
643 optEmptyContainers = true;
646 fprintf(stderr, "Invalid option %s\n", arg);
651 tests.push_back(QLatin1String(arg));
657 for (TypeDumpFunctionMap::const_iterator it = tdm.constBegin(); it != cend; ++it) {
658 const QString test = it.key();
659 if (tests.contains(test)) {
660 printf("\nSkipping: %s\n", qPrintable(test));
662 printf("\nTesting: %s\n", qPrintable(test));
663 rc += (*it.value())();
664 if (optTestUninitialized)
665 printf("Survived: %s\n", qPrintable(test));
669 foreach(const QString &test, tests) {
670 printf("\nTesting: %s\n", qPrintable(test));
671 const TypeDumpFunctionMap::const_iterator it = tdm.constFind(test);
674 fprintf(stderr, "\nUnhandled type: %s\n", qPrintable(test));
676 rc = (*it.value())();