PageRenderTime 62ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/auto/debugger/tst_gdb.cpp

https://bitbucket.org/kpozn/qt-creator-py-reborn
C++ | 3719 lines | 2936 code | 372 blank | 411 comment | 137 complexity | 4e3b2455dc03faaf2beea2fa3d6b9a5c MD5 | raw file
Possible License(s): LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /**************************************************************************
  2. **
  3. ** This file is part of Qt Creator
  4. **
  5. ** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
  6. **
  7. ** Contact: Nokia Corporation (qt-info@nokia.com)
  8. **
  9. **
  10. ** GNU Lesser General Public License Usage
  11. **
  12. ** This file may be used under the terms of the GNU Lesser General Public
  13. ** License version 2.1 as published by the Free Software Foundation and
  14. ** appearing in the file LICENSE.LGPL included in the packaging of this file.
  15. ** Please review the following information to ensure the GNU Lesser General
  16. ** Public License version 2.1 requirements will be met:
  17. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  18. **
  19. ** In addition, as a special exception, Nokia gives you certain additional
  20. ** rights. These rights are described in the Nokia Qt LGPL Exception
  21. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  22. **
  23. ** Other Usage
  24. **
  25. ** Alternatively, this file may be used in accordance with the terms and
  26. ** conditions contained in a signed written agreement between you and Nokia.
  27. **
  28. ** If you have questions regarding the use of this file, please contact
  29. ** Nokia at qt-info@nokia.com.
  30. **
  31. **************************************************************************/
  32. // Note: Keep the strange formating of closing braces in the void dump*()
  33. // functions as this reduces the risk of gdb reporting 'wrong' line numbers
  34. // when stopping and therefore the risk of the autotest to fail.
  35. //bool checkUninitialized = true;
  36. bool checkUninitialized = false;
  37. #define DO_DEBUG 1
  38. //TESTED_COMPONENT=src/plugins/debugger/gdb
  39. #include "gdb/gdbmi.h"
  40. #ifdef QT_GUI_LIB
  41. #include <QBitmap>
  42. #include <QBrush>
  43. #include <QColor>
  44. #include <QCursor>
  45. #include <QFont>
  46. #include <QIcon>
  47. #include <QKeySequence>
  48. #include <QMatrix4x4>
  49. #include <QPen>
  50. #include <QQuaternion>
  51. #include <QStandardItemModel>
  52. #include <QStringListModel>
  53. #include <QTextFormat>
  54. #include <QTextLength>
  55. #include <QVector2D>
  56. #include <QWidget>
  57. #endif
  58. #include <QtTest>
  59. #include <deque>
  60. #include <map>
  61. #include <set>
  62. #include <vector>
  63. #ifdef Q_OS_WIN
  64. #include <windows.h>
  65. #endif
  66. #undef NS
  67. #ifdef QT_NAMESPACE
  68. # define STRINGIFY0(s) #s
  69. # define STRINGIFY1(s) STRINGIFY0(s)
  70. # define NS STRINGIFY1(QT_NAMESPACE) "::"
  71. # define NSX "'" STRINGIFY1(QT_NAMESPACE) "::"
  72. # define NSY "'"
  73. #else
  74. # define NS ""
  75. # define NSX ""
  76. # define NSY ""
  77. #endif
  78. #undef DEBUG
  79. #if DO_DEBUG
  80. # define DEBUG(s) qDebug() << s
  81. #else
  82. # define DEBUG(s)
  83. #endif
  84. #define DEBUGX(s) qDebug() << s
  85. #define gettid() QString("0x%1").arg((qulonglong)(void *)currentGdbWrapper(), 0, 16)
  86. #ifdef Q_OS_WIN
  87. QString gdbBinary = "c:\\MinGw\\bin\\gdb.exe";
  88. #else
  89. QString gdbBinary = "gdb";
  90. #endif
  91. void nothing() {}
  92. template <typename T> QByteArray N(T v) { return QByteArray::number(v); }
  93. class Foo
  94. {
  95. public:
  96. Foo(int i = 0)
  97. : a(i), b(2)
  98. {}
  99. ~Foo()
  100. {
  101. }
  102. void doit()
  103. {
  104. static QObject ob;
  105. m["1"] = "2";
  106. h[&ob] = m.begin();
  107. a += 1;
  108. --b;
  109. //s += 'x';
  110. }
  111. struct Bar {
  112. Bar() : ob(0) {}
  113. QObject *ob;
  114. };
  115. public:
  116. int a, b;
  117. char x[6];
  118. private:
  119. //QString s;
  120. typedef QMap<QString, QString> Map;
  121. Map m;
  122. QHash<QObject *, Map::iterator> h;
  123. };
  124. /////////////////////////////////////////////////////////////////////////
  125. //
  126. // Helper stuff
  127. //
  128. /////////////////////////////////////////////////////////////////////////
  129. typedef QList<QByteArray> QByteArrayList;
  130. struct Int3
  131. {
  132. Int3(int base = 0) { i1 = 42 + base; i2 = 43 + base; i3 = 44 + base; }
  133. int i1, i2, i3;
  134. };
  135. uint qHash(const Int3 &i)
  136. {
  137. return (i.i1 ^ i.i2) ^ i.i3;
  138. }
  139. bool operator==(const Int3 &a, const Int3 &b)
  140. {
  141. return a.i1 == b.i1 && a.i2 == b.i2 && a.i3 == b.i3;
  142. }
  143. bool operator<(const Int3 &a, const Int3 &b)
  144. {
  145. return a.i1 < b.i1;
  146. }
  147. struct QString3
  148. {
  149. QString3() { s1 = "a"; s2 = "b"; s3 = "c"; }
  150. QString s1, s2, s3;
  151. };
  152. class tst_Gdb;
  153. class GdbWrapper : public QObject
  154. {
  155. Q_OBJECT
  156. public:
  157. GdbWrapper(tst_Gdb *test);
  158. ~GdbWrapper();
  159. void startup(QProcess *proc);
  160. void run();
  161. QString errorString() const { return m_errorString; }
  162. public slots:
  163. void readStandardOutput();
  164. bool parseOutput(const QByteArray &ba);
  165. void readStandardError();
  166. void handleGdbStarted();
  167. void handleGdbError(QProcess::ProcessError);
  168. void handleGdbFinished(int, QProcess::ExitStatus);
  169. QByteArray writeToGdbRequested(const QByteArray &ba)
  170. {
  171. DEBUG("GDB IN: " << ba);
  172. m_proc.write(ba);
  173. m_proc.write("\n");
  174. while (true) {
  175. m_proc.waitForReadyRead();
  176. QByteArray output = m_proc.readAllStandardOutput();
  177. if (parseOutput(output))
  178. break;
  179. }
  180. return m_buffer;
  181. }
  182. public:
  183. QByteArray m_lastStopped; // last seen "*stopped" message
  184. int m_line; // line extracted from last "*stopped" message
  185. QProcess m_proc;
  186. tst_Gdb *m_test; // not owned
  187. QString m_errorString;
  188. QByteArray m_buffer;
  189. };
  190. class tst_Gdb : public QObject
  191. {
  192. Q_OBJECT
  193. public:
  194. tst_Gdb();
  195. void prepare(const QByteArray &function);
  196. void check(const QByteArray &label, const QByteArray &expected,
  197. const QByteArray &expanded = QByteArray(), bool fancy = true);
  198. void next(int n = 1);
  199. QByteArray writeToGdb(const QByteArray &ba)
  200. {
  201. return m_gdb->writeToGdbRequested(ba);
  202. }
  203. private slots:
  204. void initTestCase();
  205. void cleanupTestCase();
  206. void dump_array();
  207. void dump_misc();
  208. void dump_typedef();
  209. void dump_std_deque();
  210. void dump_std_list();
  211. void dump_std_map_int_int();
  212. void dump_std_map_string_string();
  213. void dump_std_set_Int3();
  214. void dump_std_set_int();
  215. void dump_std_string();
  216. void dump_std_vector();
  217. void dump_std_wstring();
  218. void dump_Foo();
  219. //void dump_QImageData();
  220. void dump_QAbstractItemAndModelIndex();
  221. void dump_QAbstractItemModel();
  222. void dump_QByteArray();
  223. void dump_QChar();
  224. void dump_QDateTime();
  225. void dump_QDir();
  226. void dump_QFile();
  227. void dump_QFileInfo();
  228. void dump_QHash_QString_QString();
  229. void dump_QHash_int_int();
  230. void dump_QImage();
  231. void dump_QLinkedList_int();
  232. void dump_QList_Int3();
  233. void dump_QList_QString();
  234. void dump_QList_QString3();
  235. void dump_QList_char();
  236. void dump_QList_char_star();
  237. void dump_QList_int();
  238. void dump_QList_int_star();
  239. void dump_QLocale();
  240. void dump_QMap_QString_QString();
  241. void dump_QMap_int_int();
  242. void dump_QObject();
  243. void dump_QPixmap();
  244. void dump_QPoint();
  245. void dump_QRect();
  246. void dump_QSet_Int3();
  247. void dump_QSet_int();
  248. void dump_QSharedPointer();
  249. void dump_QSize();
  250. void dump_QStack();
  251. void dump_QString();
  252. void dump_QStringList();
  253. void dump_QTextCodec();
  254. void dump_QVariant();
  255. void dump_QVector();
  256. void dump_QWeakPointer_11();
  257. void dump_QWeakPointer_12();
  258. void dump_QWeakPointer_13();
  259. void dump_QWeakPointer_2();
  260. void dump_QWidget();
  261. public slots:
  262. void dumperCompatibility();
  263. private:
  264. #if 0
  265. void dump_QAbstractItemModelHelper(QAbstractItemModel &m);
  266. void dump_QObjectChildListHelper(QObject &o);
  267. void dump_QObjectSignalHelper(QObject &o, int sigNum);
  268. #endif
  269. QHash<QByteArray, int> m_lineForLabel;
  270. QByteArray m_function;
  271. GdbWrapper *m_gdb;
  272. };
  273. //
  274. // Dumpers
  275. //
  276. QByteArray str(const void *p)
  277. {
  278. char buf[100];
  279. sprintf(buf, "%p", p);
  280. return buf;
  281. }
  282. void tst_Gdb::dumperCompatibility()
  283. {
  284. // Ensure that no arbitrary padding is introduced by QVectorTypedData.
  285. const size_t qVectorDataSize = 16;
  286. QCOMPARE(sizeof(QVectorData), qVectorDataSize);
  287. QVectorTypedData<int> *v = 0;
  288. QCOMPARE(size_t(&v->array), qVectorDataSize);
  289. }
  290. static const QByteArray utfToHex(const QString &string)
  291. {
  292. return QByteArray(reinterpret_cast<const char *>(string.utf16()),
  293. 2 * string.size()).toHex();
  294. }
  295. static const QByteArray specQString(const QString &str)
  296. {
  297. return "valueencoded='7',value='" + utfToHex(str) + "'";
  298. }
  299. static const QByteArray specQChar(QChar ch)
  300. {
  301. return QByteArray("value=''") + char(ch.unicode()) + "' ("
  302. + QByteArray::number(ch.unicode()) + ")'";
  303. //return "valueencoded='7',value='" +
  304. // utfToHex(QString(QLatin1String("'%1' (%2)")).
  305. // arg(ch).arg(ch.unicode())) + "'";
  306. }
  307. /////////////////////////////////////////////////////////////////////////
  308. //
  309. // GdbWrapper
  310. //
  311. /////////////////////////////////////////////////////////////////////////
  312. GdbWrapper::GdbWrapper(tst_Gdb *test) : m_test(test)
  313. {
  314. qWarning() << "SETUP START\n\n";
  315. #ifndef Q_CC_GNU
  316. QSKIP("gdb test not applicable for compiler", SkipAll);
  317. #endif
  318. //qDebug() << "\nRUN" << getpid() << gettid();
  319. QStringList args;
  320. args << QLatin1String("-i")
  321. << QLatin1String("mi") << QLatin1String("--args")
  322. << qApp->applicationFilePath();
  323. qWarning() << "Starting" << gdbBinary << args;
  324. m_proc.start(gdbBinary, args);
  325. if (!m_proc.waitForStarted()) {
  326. const QString msg = QString::fromLatin1("Unable to run %1: %2")
  327. .arg(gdbBinary, m_proc.errorString());
  328. QSKIP(msg.toLatin1().constData(), SkipAll);
  329. }
  330. connect(&m_proc, SIGNAL(error(QProcess::ProcessError)),
  331. this, SLOT(handleGdbError(QProcess::ProcessError)));
  332. connect(&m_proc, SIGNAL(finished(int,QProcess::ExitStatus)),
  333. this, SLOT(handleGdbFinished(int,QProcess::ExitStatus)));
  334. connect(&m_proc, SIGNAL(started()),
  335. this, SLOT(handleGdbStarted()));
  336. connect(&m_proc, SIGNAL(readyReadStandardOutput()),
  337. this, SLOT(readStandardOutput()));
  338. connect(&m_proc, SIGNAL(readyReadStandardError()),
  339. this, SLOT(readStandardError()));
  340. m_proc.write("python execfile('../../../share/qtcreator/dumper/bridge.py')\n");
  341. m_proc.write("python execfile('../../../share/qtcreator/dumper/dumper.py')\n");
  342. m_proc.write("python execfile('../../../share/qtcreator/dumper/qttypes.py')\n");
  343. m_proc.write("bbsetup\n");
  344. m_proc.write("break breaker\n");
  345. m_proc.write("handle SIGSTOP stop pass\n");
  346. m_proc.write("run\n");
  347. }
  348. GdbWrapper::~GdbWrapper()
  349. {
  350. }
  351. void GdbWrapper::handleGdbError(QProcess::ProcessError error)
  352. {
  353. qDebug() << "GDB ERROR: " << error;
  354. }
  355. void GdbWrapper::handleGdbFinished(int code, QProcess::ExitStatus st)
  356. {
  357. qDebug() << "GDB FINISHED: " << code << st;
  358. }
  359. void GdbWrapper::readStandardOutput()
  360. {
  361. //parseOutput(m_proc.readAllStandardOutput());
  362. }
  363. bool GdbWrapper::parseOutput(const QByteArray &ba0)
  364. {
  365. if (ba0.isEmpty())
  366. return false;
  367. QByteArray ba = ba0;
  368. DEBUG("GDB OUT: " << ba);
  369. // =library-loaded...
  370. if (ba.startsWith("=")) {
  371. DEBUG("LIBRARY LOADED");
  372. return false;
  373. }
  374. if (ba.startsWith("*stopped")) {
  375. m_lastStopped = ba;
  376. DEBUG("GDB OUT 2: " << ba);
  377. if (!ba.contains("func=\"breaker\"")) {
  378. int pos1 = ba.indexOf(",line=\"") + 7;
  379. int pos2 = ba.indexOf("\"", pos1);
  380. m_line = ba.mid(pos1, pos2 - pos1).toInt();
  381. DEBUG(" LINE 1: " << m_line);
  382. }
  383. }
  384. // The "call" is always aborted with a message like:
  385. // "~"2321\t /* A */ QString s;\n" "
  386. // "&"The program being debugged stopped while in a function called ..."
  387. // "^error,msg="The program being debugged stopped ..."
  388. // Extract the "2321" from this
  389. static QByteArray lastText;
  390. if (ba.startsWith("~")) {
  391. lastText = ba;
  392. if (ba.size() > 8
  393. && (ba.at(2) < 'a' || ba.at(2) > 'z')
  394. && (ba.at(2) < '0' || ba.at(2) > '9')
  395. && !ba.startsWith("~\"Breakpoint ")
  396. && !ba.startsWith("~\" at ")
  397. && !ba.startsWith("~\" locals=")
  398. && !ba.startsWith("~\"XXX:")) {
  399. QByteArray ba1 = ba.mid(2, ba.size() - 6);
  400. if (ba1.startsWith(" File "))
  401. ba1 = ba1.replace(2, ba1.indexOf(','), "");
  402. //qWarning() << "OUT: " << ba1;
  403. }
  404. }
  405. if (ba.startsWith("&\"The program being debugged")) {
  406. int pos1 = 2;
  407. int pos2 = lastText.indexOf("\\", pos1);
  408. m_line = lastText.mid(pos1, pos2 - pos1).toInt();
  409. DEBUG(" LINE 2: " << m_line);
  410. }
  411. if (ba.startsWith("^error,msg=")) {
  412. if (!ba.startsWith("^error,msg=\"The program being debugged stopped"))
  413. qWarning() << "ERROR: " << ba.mid(1, ba.size() - 3);
  414. }
  415. if (ba.startsWith("~\"XXX: ")) {
  416. QByteArray ba1 = ba.mid(7, ba.size() - 11);
  417. qWarning() << "MESSAGE: " << ba.mid(7, ba.size() - 12);
  418. }
  419. ba = ba.replace("\\\"", "\"");
  420. // No interesting output before 'locals=...'
  421. int pos = ba.indexOf("locals={iname=");
  422. if (pos == -1 && ba.isEmpty())
  423. return true;
  424. QByteArray output;
  425. if (output.isEmpty())
  426. output = ba.mid(pos);
  427. else
  428. output += ba;
  429. // Up to ^done\n(gdb)
  430. pos = output.indexOf("(gdb)");
  431. if (pos == -1)
  432. return true;
  433. output = output.left(pos);
  434. pos = output.indexOf("^done");
  435. if (pos >= 4)
  436. output = output.left(pos - 4);
  437. if (output.isEmpty())
  438. return true;
  439. m_buffer += output;
  440. return true;
  441. }
  442. void GdbWrapper::readStandardError()
  443. {
  444. QByteArray ba = m_proc.readAllStandardError();
  445. qDebug() << "GDB ERR: " << ba;
  446. }
  447. void GdbWrapper::handleGdbStarted()
  448. {
  449. //qDebug() << "\n\nGDB STARTED" << getpid() << gettid() << "\n\n";
  450. }
  451. /////////////////////////////////////////////////////////////////////////
  452. //
  453. // Test Class Framework Implementation
  454. //
  455. /////////////////////////////////////////////////////////////////////////
  456. tst_Gdb::tst_Gdb()
  457. : m_gdb(0)
  458. {
  459. }
  460. void tst_Gdb::initTestCase()
  461. {
  462. const QString fileName = "tst_gdb.cpp";
  463. QFile file(fileName);
  464. if (!file.open(QIODevice::ReadOnly)) {
  465. const QString msg = QString::fromLatin1("Unable to open %1: %2")
  466. .arg(fileName, file.errorString());
  467. QSKIP(msg.toLatin1().constData(), SkipAll);
  468. }
  469. QByteArray funcName;
  470. const QByteArrayList bal = file.readAll().split('\n');
  471. Q_ASSERT(bal.size() > 100);
  472. for (int i = 0; i != bal.size(); ++i) {
  473. const QByteArray &ba = bal.at(i);
  474. if (ba.startsWith("void dump")) {
  475. int pos = ba.indexOf('(');
  476. funcName = ba.mid(5, pos - 5) + '@';
  477. } else if (ba.startsWith(" /*")) {
  478. int pos = ba.indexOf('*', 7);
  479. m_lineForLabel[QByteArray(funcName + ba.mid(7, pos - 8)).trimmed()] = i + 1;
  480. }
  481. }
  482. Q_ASSERT(!m_gdb);
  483. m_gdb = new GdbWrapper(this);
  484. }
  485. void tst_Gdb::prepare(const QByteArray &function)
  486. {
  487. Q_ASSERT(m_gdb);
  488. m_function = function;
  489. writeToGdb("b " + function);
  490. writeToGdb("call " + function + "()");
  491. }
  492. static bool isJoker(const QByteArray &ba)
  493. {
  494. return ba.endsWith("'-'") || ba.contains("'-'}");
  495. }
  496. void tst_Gdb::check(const QByteArray &label, const QByteArray &expected0,
  497. const QByteArray &expanded, bool fancy)
  498. {
  499. //qDebug() << "\nABOUT TO RUN TEST: " << expanded;
  500. qWarning() << label << "...";
  501. QByteArray options = "pe";
  502. if (fancy)
  503. options += ",fancy";
  504. options += ",autoderef";
  505. QByteArray ba = writeToGdb("bb options:" + options
  506. + " vars: expanded:" + expanded
  507. + " typeformats: formats: watchers:\n");
  508. //bb options:fancy,autoderef vars: expanded: typeformats:63686172202a=1
  509. //formats: watchers:
  510. //locals.fromString("{" + ba + "}");
  511. QByteArray received = ba.replace("\"", "'");
  512. QByteArray actual = received.trimmed();
  513. int pos = actual.indexOf("^done");
  514. if (pos != -1)
  515. actual = actual.left(pos);
  516. if (actual.endsWith("\n"))
  517. actual.chop(1);
  518. if (actual.endsWith("\\n"))
  519. actual.chop(2);
  520. QByteArray expected = "locals={iname='local',name='Locals',value=' ',type=' ',"
  521. "children=[" + expected0 + "]}";
  522. int line = m_gdb->m_line;
  523. QByteArrayList l1_0 = actual.split(',');
  524. QByteArrayList l1;
  525. for (int i = 0; i != l1_0.size(); ++i) {
  526. const QByteArray &ba = l1_0.at(i);
  527. if (ba.startsWith("watchers={iname"))
  528. break;
  529. if (!ba.startsWith("addr"))
  530. l1.append(ba);
  531. }
  532. QByteArrayList l2 = expected.split(',');
  533. bool ok = l1.size() == l2.size();
  534. if (ok) {
  535. for (int i = 0 ; i < l1.size(); ++i) {
  536. // Use "-" as joker.
  537. if (l1.at(i) != l2.at(i) && !isJoker(l2.at(i)))
  538. ok = false;
  539. }
  540. } else {
  541. qWarning() << "!= size: " << l1.size() << l2.size();
  542. }
  543. if (!ok) {
  544. int i = 0;
  545. for ( ; i < l1.size() && i < l2.size(); ++i) {
  546. if (l1.at(i) == l2.at(i) || isJoker(l2.at(i))) {
  547. qWarning() << "== " << l1.at(i);
  548. } else {
  549. //qWarning() << "!= " << l1.at(i).right(30) << l2.at(i).right(30);
  550. qWarning() << "!= " << l1.at(i) << l2.at(i);
  551. ok = false;
  552. }
  553. }
  554. for ( ; i < l2.size(); ++i)
  555. qWarning() << "!= " << "-----" << l2.at(i);
  556. for ( ; i < l1.size(); ++i)
  557. qWarning() << "!= " << l1.at(i) << "-----";
  558. if (l1.size() != l2.size()) {
  559. ok = false;
  560. qWarning() << "!= size: " << l1.size() << l2.size();
  561. }
  562. qWarning() << "RECEIVED: " << received;
  563. qWarning() << "ACTUAL : " << actual;
  564. }
  565. QCOMPARE(ok, true);
  566. //qWarning() << "LINE: " << line << "ACT/EXP" << m_function + '@' + label;
  567. //QCOMPARE(actual, expected);
  568. int expline = m_lineForLabel.value(m_function + '@' + label);
  569. int actline = line;
  570. if (actline != expline) {
  571. qWarning() << "LAST STOPPED: " << m_gdb->m_lastStopped;
  572. }
  573. QCOMPARE(actline, expline);
  574. }
  575. void tst_Gdb::next(int n)
  576. {
  577. for (int i = 0; i != n; ++i)
  578. writeToGdb("next");
  579. }
  580. void tst_Gdb::cleanupTestCase()
  581. {
  582. Q_ASSERT(m_gdb);
  583. writeToGdb("kill");
  584. writeToGdb("quit");
  585. //m_gdb.m_proc.waitForFinished();
  586. //m_gdb.wait();
  587. delete m_gdb;
  588. m_gdb = 0;
  589. }
  590. /////////////////////////////////////////////////////////////////////////
  591. //
  592. // Dumper Tests
  593. //
  594. /////////////////////////////////////////////////////////////////////////
  595. ///////////////////////////// Foo structure /////////////////////////////////
  596. /*
  597. Foo:
  598. int a, b;
  599. char x[6];
  600. typedef QMap<QString, QString> Map;
  601. Map m;
  602. QHash<QObject *, Map::iterator> h;
  603. */
  604. void dump_Foo()
  605. {
  606. /* A */ Foo f;
  607. /* B */ f.doit();
  608. /* D */ (void) 0;
  609. }
  610. void tst_Gdb::dump_Foo()
  611. {
  612. prepare("dump_Foo");
  613. next();
  614. check("B","{iname='local.f',name='f',type='Foo',"
  615. "value='-',numchild='5'}", "", 0);
  616. check("B","{iname='local.f',name='f',type='Foo',"
  617. "value='-',numchild='5',children=["
  618. "{name='a',type='int',value='0',numchild='0'},"
  619. "{name='b',type='int',value='2',numchild='0'},"
  620. "{name='x',type='char [6]',"
  621. "value='{...}',numchild='1'},"
  622. "{name='m',type='" NS "QMap<" NS "QString, " NS "QString>',"
  623. "value='{...}',numchild='1'},"
  624. "{name='h',type='" NS "QHash<" NS "QObject*, "
  625. "" NS "QMap<" NS "QString, " NS "QString>::iterator>',"
  626. "value='{...}',numchild='1'}]}",
  627. "local.f", 0);
  628. }
  629. ///////////////////////////// Array ///////////////////////////////////////
  630. void dump_array_char()
  631. {
  632. /* A */ const char s[] = "XYZ";
  633. /* B */ (void) &s; }
  634. void dump_array_int()
  635. {
  636. /* A */ int s[] = {1, 2, 3};
  637. /* B */ (void) s; }
  638. void tst_Gdb::dump_array()
  639. {
  640. prepare("dump_array_char");
  641. next();
  642. // FIXME: numchild should be '4', not '1'
  643. check("B","{iname='local.s',name='s',type='char [4]',"
  644. "value='-',numchild='1'}", "");
  645. check("B","{iname='local.s',name='s',type='char [4]',"
  646. "value='-',numchild='1',childtype='char',childnumchild='0',"
  647. "children=[{value='88 'X''},{value='89 'Y''},{value='90 'Z''},"
  648. "{value='0 '\\\\000''}]}",
  649. "local.s");
  650. prepare("dump_array_int");
  651. next();
  652. // FIXME: numchild should be '3', not '1'
  653. check("B","{iname='local.s',name='s',type='int [3]',"
  654. "value='-',numchild='1'}", "");
  655. check("B","{iname='local.s',name='s',type='int [3]',"
  656. "value='-',numchild='1',childtype='int',childnumchild='0',"
  657. "children=[{value='1'},{value='2'},{value='3'}]}",
  658. "local.s");
  659. }
  660. ///////////////////////////// Misc stuff /////////////////////////////////
  661. void dump_misc()
  662. {
  663. #if 1
  664. /* A */ int *s = new int(1);
  665. /* B */ *s += 1;
  666. /* D */ (void) 0;
  667. #else
  668. QVariant v1(QLatin1String("hallo"));
  669. QVariant v2(QStringList(QLatin1String("hallo")));
  670. QVector<QString> vec;
  671. vec.push_back("Hallo");
  672. vec.push_back("Hallo2");
  673. std::set<std::string> stdSet;
  674. stdSet.insert("s1");
  675. # ifdef QT_GUI_LIB
  676. QWidget *ww = 0; //this;
  677. QWidget &wwr = *ww;
  678. Q_UNUSED(wwr);
  679. # endif
  680. QSharedPointer<QString> sps(new QString("hallo"));
  681. QList<QSharedPointer<QString> > spsl;
  682. spsl.push_back(sps);
  683. QMap<QString,QString> stringmap;
  684. QMap<int,int> intmap;
  685. std::map<std::string, std::string> stdstringmap;
  686. stdstringmap[std::string("A")] = std::string("B");
  687. int xxx = 45;
  688. if (1 == 1) {
  689. int xxx = 7;
  690. qDebug() << xxx;
  691. }
  692. QLinkedList<QString> lls;
  693. lls << "link1" << "link2";
  694. # ifdef QT_GUI_LIB
  695. QStandardItemModel *model = new QStandardItemModel;
  696. model->appendRow(new QStandardItem("i1"));
  697. # endif
  698. QList <QList<int> > nestedIntList;
  699. nestedIntList << QList<int>();
  700. nestedIntList.front() << 1 << 2;
  701. QVariantList vList;
  702. vList.push_back(QVariant(42));
  703. vList.push_back(QVariant("HALLO"));
  704. stringmap.insert("A", "B");
  705. intmap.insert(3,4);
  706. QSet<QString> stringSet;
  707. stringSet.insert("S1");
  708. stringSet.insert("S2");
  709. qDebug() << *(spsl.front()) << xxx;
  710. #endif
  711. }
  712. void tst_Gdb::dump_misc()
  713. {
  714. prepare("dump_misc");
  715. next();
  716. check("B","{iname='local.s',name='s',type='int *',"
  717. "value='-',numchild='1'}", "", 0);
  718. //check("B","{iname='local.s',name='s',type='int *',"
  719. // "value='1',numchild='0'}", "local.s,local.model", 0);
  720. check("B","{iname='local.s',name='s',type='int *',"
  721. "value='-',numchild='1',children=["
  722. "{name='*',type='int',value='1',numchild='0'}]}",
  723. "local.s,local.model", 0);
  724. }
  725. ///////////////////////////// typedef ////////////////////////////////////
  726. void dump_typedef()
  727. {
  728. /* A */ typedef QMap<uint, double> T;
  729. /* B */ T t;
  730. /* C */ t[11] = 13.0;
  731. /* D */ (void) 0;
  732. }
  733. void tst_Gdb::dump_typedef()
  734. {
  735. prepare("dump_typedef");
  736. next(2);
  737. check("D","{iname='local.t',name='t',type='T',"
  738. //"basetype='" NS "QMap<unsigned int, double>',"
  739. "value='-',numchild='1',"
  740. "childtype='double',childnumchild='0',"
  741. "children=[{name='11',value='13'}]}", "local.t");
  742. }
  743. #if 0
  744. void tst_Gdb::dump_QAbstractItemHelper(QModelIndex &index)
  745. {
  746. const QAbstractItemModel *model = index.model();
  747. const QString &rowStr = N(index.row());
  748. const QString &colStr = N(index.column());
  749. const QByteArray &internalPtrStrSymbolic = ptrToBa(index.internalPointer());
  750. const QByteArray &internalPtrStrValue = ptrToBa(index.internalPointer(), false);
  751. const QByteArray &modelPtrStr = ptrToBa(model);
  752. QByteArray indexSpecSymbolic = QByteArray().append(rowStr + "," + colStr + ",").
  753. append(internalPtrStrSymbolic + "," + modelPtrStr);
  754. QByteArray indexSpecValue = QByteArray().append(rowStr + "," + colStr + ",").
  755. append(internalPtrStrValue + "," + modelPtrStr);
  756. QByteArray expected = QByteArray("tiname='iname',addr='").append(ptrToBa(&index)).
  757. append("',type='" NS "QAbstractItem',addr='$").append(indexSpecSymbolic).
  758. append("',value='").append(valToString(model->data(index).toString())).
  759. append("',numchild='1',children=[");
  760. int rowCount = model->rowCount(index);
  761. int columnCount = model->columnCount(index);
  762. for (int row = 0; row < rowCount; ++row) {
  763. for (int col = 0; col < columnCount; ++col) {
  764. const QModelIndex &childIndex = model->index(row, col, index);
  765. expected.append("{name='[").append(valToString(row)).append(",").
  766. append(N(col)).append("]',numchild='1',addr='$").
  767. append(N(childIndex.row())).append(",").
  768. append(N(childIndex.column())).append(",").
  769. append(ptrToBa(childIndex.internalPointer())).append(",").
  770. append(modelPtrStr).append("',type='" NS "QAbstractItem',value='").
  771. append(valToString(model->data(childIndex).toString())).append("'}");
  772. if (col < columnCount - 1 || row < rowCount - 1)
  773. expected.append(",");
  774. }
  775. }
  776. expected.append("]");
  777. testDumper(expected, &index, NS"QAbstractItem", true, indexSpecValue);
  778. }
  779. #endif
  780. class PseudoTreeItemModel : public QAbstractItemModel
  781. {
  782. public:
  783. PseudoTreeItemModel() : QAbstractItemModel(), parent1(0),
  784. parent1Child(1), parent2(10), parent2Child1(11), parent2Child2(12)
  785. {}
  786. int columnCount(const QModelIndex &parent = QModelIndex()) const
  787. {
  788. Q_UNUSED(parent);
  789. return 1;
  790. }
  791. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
  792. {
  793. return !index.isValid() || role != Qt::DisplayRole ?
  794. QVariant() : *static_cast<int *>(index.internalPointer());
  795. }
  796. QModelIndex index(int row, int column,
  797. const QModelIndex & parent = QModelIndex()) const
  798. {
  799. QModelIndex index;
  800. if (column == 0) {
  801. if (!parent.isValid()) {
  802. if (row == 0)
  803. index = createIndex(row, column, &parent1);
  804. else if (row == 1)
  805. index = createIndex(row, column, &parent2);
  806. } else if (parent.internalPointer() == &parent1 && row == 0) {
  807. index = createIndex(row, column, &parent1Child);
  808. } else if (parent.internalPointer() == &parent2) {
  809. index = createIndex(row, column,
  810. row == 0 ? &parent2Child1 : &parent2Child2);
  811. }
  812. }
  813. return index;
  814. }
  815. QModelIndex parent(const QModelIndex & index) const
  816. {
  817. QModelIndex parent;
  818. if (index.isValid()) {
  819. if (index.internalPointer() == &parent1Child)
  820. parent = createIndex(0, 0, &parent1);
  821. else if (index.internalPointer() == &parent2Child1 ||
  822. index.internalPointer() == &parent2Child2)
  823. parent = createIndex(1, 0, &parent2);
  824. }
  825. return parent;
  826. }
  827. int rowCount(const QModelIndex &parent = QModelIndex()) const
  828. {
  829. int rowCount;
  830. if (!parent.isValid() || parent.internalPointer() == &parent2)
  831. rowCount = 2;
  832. else if (parent.internalPointer() == &parent1)
  833. rowCount = 1;
  834. else
  835. rowCount = 0;
  836. return rowCount;
  837. }
  838. private:
  839. mutable int parent1;
  840. mutable int parent1Child;
  841. mutable int parent2;
  842. mutable int parent2Child1;
  843. mutable int parent2Child2;
  844. };
  845. ///////////////////////////// QAbstractItemAndModelIndex //////////////////////////
  846. // /* A */ QStringListModel m(QStringList() << "item1" << "item2" << "item3");
  847. // /* B */ index = m.index(2, 0);
  848. void dump_QAbstractItemAndModelIndex()
  849. {
  850. /* A */ PseudoTreeItemModel m2; QModelIndex index;
  851. /* C */ index = m2.index(0, 0);
  852. /* D */ index = m2.index(1, 0);
  853. /* E */ index = m2.index(0, 0, index);
  854. /* F */ (void) index.row();
  855. }
  856. void tst_Gdb::dump_QAbstractItemAndModelIndex()
  857. {
  858. prepare("dump_QAbstractItemAndModelIndex");
  859. if (checkUninitialized)
  860. check("A", "");
  861. next();
  862. check("C", "{iname='local.m2',name='m2',type='PseudoTreeItemModel',"
  863. "value='{...}',numchild='6'},"
  864. "{iname='local.index',name='index',type='" NS "QModelIndex',"
  865. "value='(invalid)',numchild='0'}",
  866. "local.index");
  867. next();
  868. check("D", "{iname='local.m2',name='m2',type='PseudoTreeItemModel',"
  869. "value='{...}',numchild='6'},"
  870. "{iname='local.index',name='index',type='" NS "QModelIndex',"
  871. "value='(0, 0)',numchild='5',children=["
  872. "{name='row',value='0',type='int',numchild='0'},"
  873. "{name='column',value='0',type='int',numchild='0'},"
  874. "{name='parent',type='" NS "QModelIndex',value='(invalid)',numchild='0'},"
  875. "{name='model',value='-',type='" NS "QAbstractItemModel*',numchild='1'}]}",
  876. "local.index");
  877. next();
  878. check("E", "{iname='local.m2',name='m2',type='PseudoTreeItemModel',"
  879. "value='{...}',numchild='6'},"
  880. "{iname='local.index',name='index',type='" NS "QModelIndex',"
  881. "value='(1, 0)',numchild='5',children=["
  882. "{name='row',value='1',type='int',numchild='0'},"
  883. "{name='column',value='0',type='int',numchild='0'},"
  884. "{name='parent',type='" NS "QModelIndex',value='(invalid)',numchild='0'},"
  885. "{name='model',value='-',type='" NS "QAbstractItemModel*',numchild='1'}]}",
  886. "local.index");
  887. next();
  888. check("F", "{iname='local.m2',name='m2',type='PseudoTreeItemModel',"
  889. "value='{...}',numchild='6'},"
  890. "{iname='local.index',name='index',type='" NS "QModelIndex',"
  891. "value='(0, 0)',numchild='5',children=["
  892. "{name='row',value='0',type='int',numchild='0'},"
  893. "{name='column',value='0',type='int',numchild='0'},"
  894. "{name='parent',type='" NS "QModelIndex',value='(1, 0)',numchild='5'},"
  895. "{name='model',value='-',type='" NS "QAbstractItemModel*',numchild='1'}]}",
  896. "local.index");
  897. }
  898. /*
  899. QByteArray dump_QAbstractItemModelHelper(QAbstractItemModel &m)
  900. {
  901. QByteArray address = ptrToBa(&m);
  902. QByteArray expected = QByteArray("tiname='iname',"
  903. "type='" NS "QAbstractItemModel',value='(%,%)',numchild='1',children=["
  904. "{numchild='1',name='" NS "QObject',value='%',"
  905. "valueencoded='2',type='" NS "QObject',displayedtype='%'}")
  906. << address
  907. << N(m.rowCount())
  908. << N(m.columnCount())
  909. << address
  910. << utfToHex(m.objectName())
  911. << m.metaObject()->className();
  912. for (int row = 0; row < m.rowCount(); ++row) {
  913. for (int column = 0; column < m.columnCount(); ++column) {
  914. QModelIndex mi = m.index(row, column);
  915. expected.append(QByteArray(",{name='[%,%]',value='%',"
  916. "valueencoded='2',numchild='1',%,%,%',"
  917. "type='" NS "QAbstractItem'}")
  918. << N(row)
  919. << N(column)
  920. << utfToHex(m.data(mi).toString())
  921. << N(mi.row())
  922. << N(mi.column())
  923. << ptrToBa(mi.internalPointer())
  924. << ptrToBa(mi.model()));
  925. }
  926. }
  927. expected.append("]");
  928. return expected;
  929. }
  930. */
  931. void dump_QAbstractItemModel()
  932. {
  933. # ifdef QT_GUI_LIB
  934. /* A */ QStringList strList;
  935. strList << "String 1";
  936. QStringListModel model1(strList);
  937. QStandardItemModel model2(0, 2);
  938. /* B */ model1.setStringList(strList);
  939. /* C */ strList << "String 2";
  940. /* D */ model1.setStringList(strList);
  941. /* E */ model2.appendRow(QList<QStandardItem *>() << (new QStandardItem("Item (0,0)")) << (new QStandardItem("Item (0,1)")));
  942. /* F */ model2.appendRow(QList<QStandardItem *>() << (new QStandardItem("Item (1,0)")) << (new QStandardItem("Item (1,1)")));
  943. /* G */ (void) (model1.rowCount() + model2.rowCount() + strList.size());
  944. # endif
  945. }
  946. void tst_Gdb::dump_QAbstractItemModel()
  947. {
  948. # ifdef QT_GUI_LIB
  949. /* A */ QStringList strList;
  950. QString template_ =
  951. "{iname='local.strList',name='strList',type='" NS "QStringList',"
  952. "value='<%1 items>',numchild='%1'},"
  953. "{iname='local.model1',name='model1',type='" NS "QStringListModel',"
  954. "value='{...}',numchild='3'},"
  955. "{iname='local.model2',name='model2',type='" NS "QStandardItemModel',"
  956. "value='{...}',numchild='2'}";
  957. prepare("dump_QAbstractItemModel");
  958. if (checkUninitialized)
  959. check("A", template_.arg("1").toAscii());
  960. next(4);
  961. check("B", template_.arg("1").toAscii());
  962. # endif
  963. }
  964. ///////////////////////////// QByteArray /////////////////////////////////
  965. void dump_QByteArray()
  966. {
  967. /* A */ QByteArray ba; // Empty object.
  968. /* B */ ba.append('a'); // One element.
  969. /* C */ ba.append('b'); // Two elements.
  970. /* D */ ba = QByteArray(101, 'a'); // > 100 elements.
  971. /* E */ ba = QByteArray("abc\a\n\r\033\'\"?"); // Mixed.
  972. /* F */ (void) 0;
  973. }
  974. void tst_Gdb::dump_QByteArray()
  975. {
  976. prepare("dump_QByteArray");
  977. if (checkUninitialized)
  978. check("A","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  979. "value='<invalid>',numchild='0'}");
  980. next();
  981. check("B","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  982. "valueencoded='6',value='',numchild='0'}");
  983. next();
  984. check("C","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  985. "valueencoded='6',value='61',numchild='1'}");
  986. next();
  987. check("D","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  988. "valueencoded='6',value='6162',numchild='2'}");
  989. next();
  990. check("E","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  991. "valueencoded='6',value='616161616161616161616161616161616161"
  992. "616161616161616161616161616161616161616161616161616161616161"
  993. "616161616161616161616161616161616161616161616161616161616161"
  994. "6161616161616161616161616161616161616161616161',numchild='101'}");
  995. next();
  996. check("F","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  997. "valueencoded='6',value='616263070a0d1b27223f',numchild='10'}");
  998. check("F","{iname='local.ba',name='ba',type='" NS "QByteArray',"
  999. "valueencoded='6',value='616263070a0d1b27223f',numchild='10',"
  1000. "childtype='char',childnumchild='0',"
  1001. "children=[{value='97 'a''},{value='98 'b''},"
  1002. "{value='99 'c''},{value='7 '\\\\a''},"
  1003. "{value='10 '\\\\n''},{value='13 '\\\\r''},"
  1004. "{value='27 '\\\\033''},{value='39 '\\\\'''},"
  1005. "{value='34 ''''},{value='63 '?''}]}",
  1006. "local.ba");
  1007. }
  1008. ///////////////////////////// QChar /////////////////////////////////
  1009. void dump_QChar()
  1010. {
  1011. /* A */ QChar c('X'); // Printable ASCII character.
  1012. /* B */ c = QChar(0x600); // Printable non-ASCII character.
  1013. /* C */ c = QChar::fromAscii('\a'); // Non-printable ASCII character.
  1014. /* D */ c = QChar(0x9f); // Non-printable non-ASCII character.
  1015. /* E */ c = QChar::fromAscii('?'); // The replacement character.
  1016. /* F */ (void) 0; }
  1017. void tst_Gdb::dump_QChar()
  1018. {
  1019. prepare("dump_QChar");
  1020. next();
  1021. // Case 1: Printable ASCII character.
  1022. check("B","{iname='local.c',name='c',type='" NS "QChar',"
  1023. "value=''X' (88)',numchild='0'}");
  1024. next();
  1025. // Case 2: Printable non-ASCII character.
  1026. check("C","{iname='local.c',name='c',type='" NS "QChar',"
  1027. "value=''?' (1536)',numchild='0'}");
  1028. next();
  1029. // Case 3: Non-printable ASCII character.
  1030. check("D","{iname='local.c',name='c',type='" NS "QChar',"
  1031. "value=''?' (7)',numchild='0'}");
  1032. next();
  1033. // Case 4: Non-printable non-ASCII character.
  1034. check("E","{iname='local.c',name='c',type='" NS "QChar',"
  1035. "value=''?' (159)',numchild='0'}");
  1036. next();
  1037. // Case 5: Printable ASCII Character that looks like the replacement character.
  1038. check("F","{iname='local.c',name='c',type='" NS "QChar',"
  1039. "value=''?' (63)',numchild='0'}");
  1040. }
  1041. ///////////////////////////// QDateTime /////////////////////////////////
  1042. void dump_QDateTime()
  1043. {
  1044. # ifndef QT_NO_DATESTRING
  1045. /* A */ QDateTime d;
  1046. /* B */ d = QDateTime::fromString("M5d21y7110:31:02", "'M'M'd'd'y'yyhh:mm:ss");
  1047. /* C */ (void) d.isNull();
  1048. # endif
  1049. }
  1050. void tst_Gdb::dump_QDateTime()
  1051. {
  1052. # ifndef QT_NO_DATESTRING
  1053. prepare("dump_QDateTime");
  1054. if (checkUninitialized)
  1055. check("A","{iname='local.d',name='d',"
  1056. "type='" NS "QDateTime',value='<invalid>',"
  1057. "numchild='0'}");
  1058. next();
  1059. check("B", "{iname='local.d',name='d',type='" NS "QDateTime',"
  1060. "valueencoded='7',value='-',numchild='3',children=["
  1061. "{name='isNull',type='bool',value='true',numchild='0'},"
  1062. "{name='toTime_t',type='unsigned int',value='4294967295',numchild='0'},"
  1063. "{name='toString',type='myns::QString',valueencoded='7',"
  1064. "value='',numchild='0'},"
  1065. "{name='(ISO)',type='myns::QString',valueencoded='7',"
  1066. "value='',numchild='0'},"
  1067. "{name='(SystemLocale)',type='myns::QString',valueencoded='7',"
  1068. "value='',numchild='0'},"
  1069. "{name='(Locale)',type='myns::QString',valueencoded='7',"
  1070. "value='',numchild='0'},"
  1071. "{name='toUTC',type='myns::QDateTime',valueencoded='7',"
  1072. "value='',numchild='3'},"
  1073. "{name='toLocalTime',type='myns::QDateTime',valueencoded='7',"
  1074. "value='',numchild='3'}"
  1075. "]}",
  1076. "local.d");
  1077. next();
  1078. check("C", "{iname='local.d',name='d',type='" NS "QDateTime',"
  1079. "valueencoded='7',value='-',"
  1080. "numchild='3',children=["
  1081. "{name='isNull',type='bool',value='false',numchild='0'},"
  1082. "{name='toTime_t',type='unsigned int',value='43666262',numchild='0'},"
  1083. "{name='toString',type='myns::QString',valueencoded='7',"
  1084. "value='-',numchild='0'},"
  1085. "{name='(ISO)',type='myns::QString',valueencoded='7',"
  1086. "value='-',numchild='0'},"
  1087. "{name='(SystemLocale)',type='myns::QString',valueencoded='7',"
  1088. "value='-',numchild='0'},"
  1089. "{name='(Locale)',type='myns::QString',valueencoded='7',"
  1090. "value='-',numchild='0'},"
  1091. "{name='toUTC',type='myns::QDateTime',valueencoded='7',"
  1092. "value='-',numchild='3'},"
  1093. "{name='toLocalTime',type='myns::QDateTime',valueencoded='7',"
  1094. "value='-',numchild='3'}"
  1095. "]}",
  1096. "local.d");
  1097. # endif
  1098. }
  1099. ///////////////////////////// QDir /////////////////////////////////
  1100. void dump_QDir()
  1101. {
  1102. /* A */ QDir dir = QDir::current(); // Case 1: Current working directory.
  1103. /* B */ dir = QDir::root(); // Case 2: Root directory.
  1104. /* C */ (void) dir.absolutePath(); }
  1105. void tst_Gdb::dump_QDir()
  1106. {
  1107. prepare("dump_QDir");
  1108. if (checkUninitialized)
  1109. check("A","{iname='local.dir',name='dir',"
  1110. "type='" NS "QDir',value='<invalid>',"
  1111. "numchild='0'}");
  1112. next();
  1113. check("B", "{iname='local.dir',name='dir',type='" NS "QDir',"
  1114. "valueencoded='7',value='-',numchild='2',children=["
  1115. "{name='absolutePath',type='" NS "QString',"
  1116. "valueencoded='7',value='-',numchild='0'},"
  1117. "{name='canonicalPath',type='" NS "QString',"
  1118. "valueencoded='7',value='-',numchild='0'}]}",
  1119. "local.dir");
  1120. next();
  1121. check("C", "{iname='local.dir',name='dir',type='" NS "QDir',"
  1122. "valueencoded='7',value='-',numchild='2',children=["
  1123. "{name='absolutePath',type='" NS "QString',"
  1124. "valueencoded='7',value='-',numchild='0'},"
  1125. "{name='canonicalPath',type='" NS "QString',"
  1126. "valueencoded='7',value='-',numchild='0'}]}",
  1127. "local.dir");
  1128. }
  1129. ///////////////////////////// QFile /////////////////////////////////
  1130. void dump_QFile()
  1131. {
  1132. /* A */ QFile file1(""); // Case 1: Empty file name => Does not exist.
  1133. /* B */ QTemporaryFile file2; // Case 2: File that is known to exist.
  1134. file2.open();
  1135. /* C */ QFile file3("jfjfdskjdflsdfjfdls");
  1136. /* D */ (void) (file1.fileName() + file2.fileName() + file3.fileName()); }
  1137. void tst_Gdb::dump_QFile()
  1138. {
  1139. prepare("dump_QFile");
  1140. next(4);
  1141. check("D", "{iname='local.file1',name='file1',type='" NS "QFile',"
  1142. "valueencoded='7',value='',numchild='2',children=["
  1143. "{name='fileName',type='" NS "QString',"
  1144. "valueencoded='7',value='',numchild='0'},"
  1145. "{name='exists',type='bool',value='false',numchild='0'}"
  1146. "]},"
  1147. "{iname='local.file2',name='file2',type='" NS "QTemporaryFile',"
  1148. "valueencoded='7',value='-',numchild='2',children=["
  1149. "{name='fileName',type='" NS "QString',"
  1150. "valueencoded='7',value='-',numchild='0'},"
  1151. "{name='exists',type='bool',value='true',numchild='0'}"
  1152. "]},"
  1153. "{iname='local.file3',name='file3',type='" NS "QFile',"
  1154. "valueencoded='7',value='-',numchild='2',children=["
  1155. "{name='fileName',type='" NS "QString',"
  1156. "valueencoded='7',value='-',numchild='0'},"
  1157. "{name='exists',type='bool',value='false',numchild='0'}"
  1158. "]}",
  1159. "local.file1,local.file2,local.file3");
  1160. }
  1161. ///////////////////////////// QFileInfo /////////////////////////////////
  1162. void dump_QFileInfo()
  1163. {
  1164. /* A */ QFileInfo fi(".");
  1165. /* B */ (void) fi.baseName().size();
  1166. }
  1167. void tst_Gdb::dump_QFileInfo()
  1168. {
  1169. QFileInfo fi(".");
  1170. prepare("dump_QFileInfo");
  1171. next();
  1172. check("B", "{iname='local.fi',name='fi',type='" NS "QFileInfo',"
  1173. "valueencoded='7',value='" + utfToHex(fi.filePath()) + "',numchild='3',"
  1174. "childtype='" NS "QString',childnumchild='0',children=["
  1175. "{name='absolutePath'," + specQString(fi.absolutePath()) + "},"
  1176. "{name='absoluteFilePath'," + specQString(fi.absoluteFilePath()) + "},"
  1177. "{name='canonicalPath'," + specQString(fi.canonicalPath()) + "},"
  1178. "{name='canonicalFilePath'," + specQString(fi.canonicalFilePath()) + "},"
  1179. "{name='completeBaseName'," + specQString(fi.completeBaseName()) + "},"
  1180. "{name='completeSuffix'," + specQString(fi.completeSuffix()) + "},"
  1181. "{name='baseName'," + specQString(fi.baseName()) + "},"
  1182. #if 0
  1183. "{name='isBundle'," + specBool(fi.isBundle()) + "},"
  1184. "{name='bundleName'," + specQString(fi.bundleName()) + "},"
  1185. #endif
  1186. "{name='fileName'," + specQString(fi.fileName()) + "},"
  1187. "{name='filePath'," + specQString(fi.filePath()) + "},"
  1188. //"{name='group'," + specQString(fi.group()) + "},"
  1189. //"{name='owner'," + specQString(fi.owner()) + "},"
  1190. "{name='path'," + specQString(fi.path()) + "},"
  1191. "{name='groupid',type='unsigned int',value='" + N(fi.groupId()) + "'},"
  1192. "{name='ownerid',type='unsigned int',value='" + N(fi.ownerId()) + "'},"
  1193. "{name='permissions',value=' ',type='" NS "QFile::Permissions',numchild='10'},"
  1194. "{name='caching',type='bool',value='true'},"
  1195. "{name='exists',type='bool',value='true'},"
  1196. "{name='isAbsolute',type='bool',value='false'},"
  1197. "{name='isDir',type='bool',value='true'},"
  1198. "{name='isExecutable',type='bool',value='true'},"
  1199. "{name='isFile',type='bool',value='false'},"
  1200. "{name='isHidden',type='bool',value='false'},"
  1201. "{name='isReadable',type='bool',value='true'},"
  1202. "{name='isRelative',type='bool',value='true'},"
  1203. "{name='isRoot',type='bool',value='false'},"
  1204. "{name='isSymLink',type='bool',value='false'},"
  1205. "{name='isWritable',type='bool',value='true'},"
  1206. "{name='created',type='" NS "QDateTime',"
  1207. + specQString(fi.created().toString()) + ",numchild='3'},"
  1208. "{name='lastModified',type='" NS "QDateTime',"
  1209. + specQString(fi.lastModified().toString()) + ",numchild='3'},"
  1210. "{name='lastRead',type='" NS "QDateTime',"
  1211. + specQString(fi.lastRead().toString()) + ",numchild='3'}]}",
  1212. "local.fi");
  1213. }
  1214. #if 0
  1215. void tst_Gdb::dump_QImageDataHelper(QImage &img)
  1216. {
  1217. const QByteArray ba(QByteArray::fromRawData((const char*) img.bits(), img.numBytes()));
  1218. QByteArray expected = QByteArray("tiname='$I',addr='$A',type='" NS "QImageData',").
  1219. append("numchild='0',value='<hover here>',valuetooltipencoded='1',").
  1220. append("valuetooltipsize='").append(N(ba.size())).append("',").
  1221. append("valuetooltip='").append(ba.toBase64()).append("'");
  1222. testDumper(expected, &img, NS"QImageData", false);
  1223. }
  1224. #endif // 0
  1225. ///////////////////////////// QImage /////////////////////////////////
  1226. void dump_QImage()
  1227. {
  1228. # ifdef QT_GUI_LIB
  1229. /* A */ QImage image; // Null image.
  1230. /* B */ image = QImage(30, 700, QImage::Format_RGB555); // Normal image.
  1231. /* C */ image = QImage(100, 0, QImage::Format_Invalid); // Invalid image.
  1232. /* D */ (void) image.size();
  1233. /* E */ (void) image.size();
  1234. # endif
  1235. }
  1236. void tst_Gdb::dump_QImage()
  1237. {
  1238. # ifdef QT_GUI_LIB
  1239. prepare("dump_QImage");
  1240. next();
  1241. check("B", "{iname='local.image',name='image',type='" NS "QImage',"
  1242. "value='(null)',numchild='0'}");
  1243. next();
  1244. check("C", "{iname='local.image',name='image',type='" NS "QImage',"
  1245. "value='(30x700)',numchild='0'}");
  1246. next(2);
  1247. // FIXME:
  1248. //check("E", "{iname='local.image',name='image',type='" NS "QImage',"
  1249. // "value='(100x0)',numchild='0'}");
  1250. # endif
  1251. }
  1252. #if 0
  1253. void tst_Gdb::dump_QImageData()
  1254. {
  1255. // Case 1: Null image.
  1256. QImage img;
  1257. dump_QImageDataHelper(img);
  1258. // Case 2: Normal image.
  1259. img = QImage(3, 700, QImage::Format_RGB555);
  1260. dump_QImageDataHelper(img);
  1261. // Case 3: Invalid image.
  1262. img = QImage(100, 0, QImage::Format_Invalid);
  1263. dump_QImageDataHelper(img);
  1264. }
  1265. #endif
  1266. void dump_QLocale()
  1267. {
  1268. /* A */ QLocale german(QLocale::German);
  1269. QLocale chinese(QLocale::Chinese);
  1270. QLocale swahili(QLocale::Swahili);
  1271. /* C */ (void) (german.name() + chinese.name() + swahili.name());
  1272. }
  1273. QByteArray dump_QLocaleHelper(const QLocale &loc)
  1274. {
  1275. return "type='" NS "QLocale',valueencoded='7',value='" + utfToHex(loc.name()) +
  1276. "',numchild='8',childtype='" NS "QChar',childnumchild='0',children=["
  1277. "{name='country',type='" NS "QLocale::Country',value='-'},"
  1278. "{name='language',type='" NS "QLocale::Language',value='-'},"
  1279. "{name='measurementSystem',type='" NS "QLocale::MeasurementSystem',"
  1280. "value='-'},"
  1281. "{name='numberOptions',type='" NS "QFlags<myns::QLocale::NumberOption>',"
  1282. "value='-'},"
  1283. "{name='timeFormat_(short)',type='" NS "QString',"
  1284. + specQString(loc.timeFormat(QLocale::ShortFormat)) + "},"
  1285. "{name='timeFormat_(long)',type='" NS "QString',"
  1286. + specQString(loc.timeFormat()) + "},"
  1287. "{name='decimalPoint'," + specQChar(loc.decimalPoint()) + "},"
  1288. "{name='exponential'," + specQChar(loc.exponential()) + "},"
  1289. "{name='percent'," + specQChar(loc.percent()) + "},"
  1290. "{name='zeroDigit'," + specQChar(loc.zeroDigit()) + "},"
  1291. "{name='groupSeparator'," + specQChar(loc.groupSeparator()) + "},"
  1292. "{name='negativeSign'," + specQChar(loc.negativeSign()) + "}]";
  1293. }
  1294. void tst_Gdb::dump_QLocale()
  1295. {
  1296. QLocale german(QLocale::German);
  1297. QLocale chinese(QLocale::Chinese);
  1298. QLocale swahili(QLocale::Swahili);
  1299. prepare("dump_QLocale");
  1300. if (checkUninitialized)
  1301. check("A","{iname='local.english',name='english',"
  1302. "type='" NS "QLocale',value='<invalid>',"
  1303. "numchild='0'}");
  1304. next(3);
  1305. check("C", "{iname='local.german',name='german',"
  1306. + dump_QLocaleHelper(german) + "},"
  1307. "{iname='local.chinese',name='chinese',"
  1308. + dump_QLocaleHelper(chinese) + "},"
  1309. "{iname='local.swahili',name='swahili',"
  1310. + dump_QLocaleHelper(swahili) + "}",
  1311. "local.german,local.chinese,local.swahili");
  1312. }
  1313. ///////////////////////////// QHash<int, int> //////////////////////////////
  1314. void dump_QHash_int_int()
  1315. {
  1316. /* A */ QHash<int, int> h;
  1317. /* B */ h[43] = 44;
  1318. /* C */ h[45] = 46;
  1319. /* D */ (void) 0;
  1320. }
  1321. void tst_Gdb::dump_QHash_int_int()
  1322. {
  1323. // Need to check the following combinations:
  1324. // int-key optimization, small value
  1325. //struct NodeOS { void *next; uint k; uint v; } nodeOS
  1326. // int-key optimiatzion, large value
  1327. //struct NodeOL { void *next; uint k; void *v; } nodeOL
  1328. // no optimization, small value
  1329. //struct NodeNS + { void *next; uint h; uint k; uint v; } nodeNS
  1330. // no optimization, large value
  1331. //struct NodeNL { void *next; uint h; uint k; void *v; } nodeNL
  1332. // complex key
  1333. //struct NodeL { void *next; uint h; void *k; void *v; } nodeL
  1334. prepare("dump_QHash_int_int");
  1335. if (checkUninitialized)
  1336. check("A","{iname='local.h',name='h',"
  1337. "type='" NS "QHash<int, int>',value='<invalid>',"
  1338. "numchild='0'}");
  1339. next(3);
  1340. check("D","{iname='local.h',name='h',"
  1341. "type='" NS "QHash<int, int>',value='<2 items>',numchild='2',"
  1342. "childtype='int',childnumchild='0',children=["
  1343. "{name='43',value='44'},"
  1344. "{name='45',value='46'}]}",
  1345. "local.h");
  1346. }
  1347. ///////////////////////////// QHash<QString, QString> //////////////////////////////
  1348. void dump_QHash_QString_QString()
  1349. {
  1350. /* A */ QHash<QString, QString> h;
  1351. /* B */ h["hello"] = "world";
  1352. /* C */ h["foo"] = "bar…

Large files files are truncated, but you can click here to view the full file