diff --git a/dist/changes-1.3.0 b/dist/changes-1.3.0 index 578ce887b70..fd55ce90a72 100644 --- a/dist/changes-1.3.0 +++ b/dist/changes-1.3.0 @@ -22,6 +22,7 @@ General * Reworked the projects pane * Made the welcome screen tabs into plugins, reimplement IWelcomePage to add your own welcome screen page + * Overhauled the project pane. Editing * Added support for text editor color schemes @@ -38,13 +39,17 @@ Editing * Added left/right arrow buttons for "Go back/forward" in navigation history * Added smart indentation for pasted text blocks +Refactoring + * Added rename symbol under cursor + * Find usages of a symbol + Project support * Added support for adding and removing files from a generic Makefile-based project * Added better control over the environment used for running. - * Add all cmake files to the project tree (only works with a cvs cmake) - * Support cmake with Microsoft Visual Studio Compiler (only works with cvs - cmake) + * Add all cmake files to the project tree (only works with a cmake 2.8) + * Support cmake with Microsoft Visual Studio Compiler (only works with + cmake 2.8 ) * Fix a few cmake wizard bugs, where canceling left creator in a strange state * The qmake and make steps can now be removed. @@ -54,6 +59,9 @@ Project support * Show subdirectory structure below .pro/.pri files in project tree * Add "Show file in Finder/Explorer" (Mac/Windows) to context menu. On Linux it opens the containing directory. + * The qmake step and make step can be removed from qt projects now. + * Made importing build settings for qt projects more robust + * Only run qmake, if it needs to be run. Compilation * Support multi-core compilation on Windows/MSVC via jom @@ -95,6 +103,9 @@ Platform Specific Mac * Make use of system's language settings +Symbian Target + * Preliminary support for targeting Qt for Symbian applications + Additional credits go to: * Christian Hoenig (Locator filter for symbols in current document) * Henrik Abelsson (Configure what to do with externally modified files) diff --git a/doc/addressbook-sdk.qdoc b/doc/addressbook-sdk.qdoc index 49195e9a8e8..7d7734bea78 100644 --- a/doc/addressbook-sdk.qdoc +++ b/doc/addressbook-sdk.qdoc @@ -348,7 +348,7 @@ \snippet examples/addressbook-sdk/part2/addressbook.h members We also declare two private QString objects, \c oldName and \c oldAddress. - These objects are needed to hold the name and address of hte contact that + These objects are needed to hold the name and address of the contact that was last displayed, before the user clicked \gui Add. So, when the user clicks \gui Cancel, we can revert to displaying the details of the last contact. @@ -529,7 +529,7 @@ \snippet examples/addressbook-sdk/part3/addressbook.cpp enable navigation - We also include these lins of code in the \c cancel() function. + We also include these lines of code in the \c cancel() function. Recall that we intend to emulate a circularly-linked list with our QMap object, \c contacts. So in the \c next() function, we obtain an iterator @@ -735,7 +735,7 @@ In this chapter, we look at ways to locate contacts and addresses in the address book application. - # image + \image addressbook-tutorial-part5-screenshot.png As we keep adding contacts to our address book, it becomes tedious to navigate them with the \gui Next and \gui Previous buttons. In this case, @@ -750,13 +750,14 @@ \section1 Designing The FindDialog - #image + \image addressbook-tutorial-part5-finddialog-in-designer.png - We begin by adding a new \c{.ui} file to our project. Right click on your + We begin by adding a new \c{.ui} file and a corresponding class to our project. Right click on your project and select \gui{Add New...}. In the \gui{New File} dialog, select - \gui{Qt Designer Form}. In the \gui{Qt Designer Form} dialog, select - \e{Dialog without buttons}. Name it \c{finddialog.ui} and add it to your - project. The \QD plugin within Qt Creator will now display your new form. + \gui{Qt Designer Form Class}. In the \gui{Qt Designer Form Class} dialog, select + \e{Dialog without buttons}. Name the class \c{FindDialog} and add the files it to your + project. Open your new form in the \QD form editor within Qt Creator by + double-clicking on the \c{finddialog.ui} file in the \gui{Project Sidebar}. To replicate the screenshot above, we need a label, a line edit, and a push button. Drag these onto your form. Set their text accordingly and name them @@ -781,17 +782,6 @@ \snippet examples/addressbook-sdk/part5/finddialog.cpp constructor - We connect our signals to their respective slots. Notice that - \c{findButton}'s \l{QPushButton:}{clicked()} signal is connected to - \c findClicked() and \l{QDialog::}{accept()}. The \l{QDialog::}{accept()} - slot provided by QDialog hides the dialog and sets the result code to - \l{QDialog::}{Accepted}. We use this function to help \c{AddressBook}'s - \c findContact() function know when the \c FindDialog object has been - closed. We will explain this logic in further detail when discussing the - \c findContact() function. - - \image addressbook-tutorial-part5-signals-and-slots.png - In \c findClicked(), we validate to ensure that the user did not click the \gui Find button without entering a contact's name. Then, we set \c findText to the search string, extracted from \c lineEdit. After that, @@ -799,15 +789,24 @@ \snippet examples/addressbook-sdk/part5/finddialog.cpp findClicked - The \c findText variable has a public getter function, \c getFindText(), - associated with it. Since we only ever set \c findText directly in both - the constructor and in hte \c findClicked() function, we do not create a - setter function to accompany \c getFindText(). Because \c getFindText() is - public, classes instantiating and using \c FindDialog can always access the - search string that the user has entered and accepted. + \c findText() is public, which makes it easy for classes instantiating + and using \c FindDialog to access the search string that the user has entered + and accepted. \snippet examples/addressbook-sdk/part5/finddialog.cpp findText + Finally, we connect our signals to their respective slots. Notice that + \c{findButton}'s \l{QPushButton::}{clicked()} signal is connected to + \c findClicked(), which calls \l{QDialog::}{accept()} or \l{QDialog::}{reject()}. + The \l{QDialog::}{accept()} slot provided by QDialog hides the dialog + and sets the result code to \l{QDialog::}{Accepted}, while \l{QDialog::}{reject()} + sets it to \l{QDialog::}{Rejected} accordingly. We use this function to help + \c{AddressBook}'s \c findContact() function know when the \c FindDialog object has been + closed. We will explain this logic in further detail when discussing the + \c findContact() function. + + \image addressbook-tutorial-part5-signals-and-slots.png + \section1 The AddressBook Class @@ -818,7 +817,7 @@ So far, all our address book features have a QPushButton and a corresponding slot. Similarly, for the \gui Find feature, we have - \c findButton and \c findContact(). + \c{ui->findButton} and \c findContact(). \snippet examples/addressbook-sdk/part5/addressbook.h slot definition @@ -838,15 +837,17 @@ We start out by displaying the \c FindDialog instance, \c dialog. This is when the user enters a contact name to look up. Once the user clicks the dialog's \c findButton, the dialog is hidden and the result code is set to - QDialog::Accepted. THis ensures that our \c if statement is always true. + either QDialog::Accepted or QDialog::Rejected by the FindDialog's + \c findClicked() method. This ensures that we only search for a contact + if the user typed something in the FindDialog's line edit. We then proceed to extract the search string, which in this case is - \c contactName, using \c{FindDialog}'s \c getFindText() function. If the + \c contactName, using \c{FindDialog}'s \c findText() function. If the contact exists in our address book, we display it immediately. Otherwise, we display the QMessageBox shown below to indicate that their search failed. - # image + \image addressbook-tutorial-part5-dialogbox.png The concept behind finding a contact only applies for cases where we have more than two contacts in our address book. Hence, we implement this @@ -870,7 +871,7 @@ This chapter covers the file handling features of Qt that we used to write loading and saving routines for the address book application. - # screenshot + \image addressbook-tutorial-part6-screenshot.png Although browsing and searching for contacts are useful features, our address book is not really ready for use until we can save existing @@ -910,7 +911,7 @@ the push buttons. - # screenshot of property editor + \image addressbook-tutorial-part6-propertyeditor.png \section1 The AddressBook Class @@ -935,7 +936,7 @@ The file dialog that pops up is displayed in the screenshot below: - #screenshot + \image addressbook-tutorial-part6-savedialog.png If \c fileName is not empty, we create a QFile object, \c file, with \c fileName. The QFile object works with QDataStream as QFile is a @@ -967,7 +968,7 @@ On Windows, for example, this function pops up a native file dialog, as shown in the following screenshot. - # screenshot + \image addressbook-tutorial-part6-opendialog.png If \c fileName is not empty, again, we use a QFile object, \c file, and attempt to open it in \l{QIODevice::}{ReadOnly} mode. Similar to our @@ -989,8 +990,10 @@ validate the data obtained to ensure that the file we read from actually contains address book contacts. If it does, we display the first contact; otherwise, we display a QMessageBox to inform the user about the problem. - Lastly, we update the interface to enable and disable the push buttons - accordingly. + Lastly, we connect the \c clicked() signal of the push buttons + with the \c loadFromFile() and \c saveToFile(): + + \snippet examples/addressbook-sdk/part6/addressbook.cpp connectSlots */ @@ -1014,7 +1017,7 @@ \c exportButton as its \c objectName. The \c toolTip property is set to \gui{Export as vCard}. - # screenshot + \image addressbook-tutorial-part7-screenshot.png \section1 The AddressBook Class diff --git a/doc/eike_doc.patch b/doc/eike_doc.patch new file mode 100644 index 00000000000..f23c589de23 --- /dev/null +++ b/doc/eike_doc.patch @@ -0,0 +1,138 @@ +diff --git a/doc/addressbook-sdk.qdoc b/doc/addressbook-sdk.qdoc +index 0441666..7012ea6 100644 +--- a/doc/addressbook-sdk.qdoc ++++ b/doc/addressbook-sdk.qdoc +@@ -139,7 +139,7 @@ + \section1 Placing Widgets on The Form + + In the \gui{Project Sidebar}, double-click on the \c{addressbook.ui} file. +- The \QD plugin will be launched, allowing you to design your program's user ++ The \QD form editor will be launched, allowing you to design your program's user + interface. + + We require two \l{QLabel}s to label the input fields as well as a QLineEdit +@@ -156,6 +156,7 @@ + diagram below shows the layout cells and the position of our widgets. Place + your widgets accordingly and save the form by choosing + \gui{File | Save} or using the \key{Ctrl+S} shortcut. ++ (We have to actually layout the widgets in a grid layout, this step seems to be missing to me?) + + \image addressbook-tutorial-part1-labeled-screenshot.png + +@@ -311,7 +312,7 @@ + \snippet examples/addressbook-sdk/part2/addressbook.h slot definition + + Since the \c AddressBook class is a subclass of QWidget, Qt Creator +- includes QWidget in the hedaer file. ++ includes QWidget in the header file. + + \snippet examples/addressbook-sdk/part2/addressbook.h include + +@@ -323,7 +324,7 @@ + \snippet examples/addressbook-sdk/part2/addressbook.h members + + We also declare two private QString objects, \c oldName and \c oldAddress. +- These objects are needed to hold the name and address of hte contact that ++ These objects are needed to hold the name and address of the contact that + was last displayed, before the user clicked \gui Add. So, when the user + clicks \gui Cancel, we can revert to displaying the details of the last + contact. +@@ -499,7 +500,7 @@ + + \snippet examples/addressbook-sdk/part3/addressbook.cpp enable navigation + +- We also include these lins of code in the \c cancel() function. ++ We also include these lines of code in the \c cancel() function. + + Recall that we intend to emulate a circularly-linked list with our QMap + object, \c contacts. So in the \c next() function, we obtain an iterator +@@ -722,11 +723,12 @@ + + #image + +- We begin by adding a new \c{.ui} file to our project. Right click on your ++ We begin by adding a new \c{.ui} file and a corresponding class to our project. Right click on your + project and select \gui{Add New...}. In the \gui{New File} dialog, select +- \gui{Qt Designer Form}. In the \gui{Qt Designer Form} dialog, select +- \e{Dialog without buttons}. Name it \c{finddialog.ui} and add it to your +- project. The \QD plugin within Qt Creator will now display your new form. ++ \gui{Qt Designer Form Class}. In the \gui{Qt Designer Form Class} dialog, select ++ \e{Dialog without buttons}. Name the class \c{FindDialog} and add the files it to your ++ project. Open your new form in the \QD form editor within Qt Creator by ++ double-clicking on the \c{finddialog.ui} file in the \gui{Project Sidebar}. + + To replicate the screenshot above, we need a label, a line edit, and a push + button. Drag these onto your form. Set their text accordingly and name them +@@ -759,6 +761,9 @@ + \c findContact() function know when the \c FindDialog object has been + closed. We will explain this logic in further detail when discussing the + \c findContact() function. ++ (The above paragraph is not up to date, since clicked() is not connected ++ to accept(). The description of accept() can move below to the implementation ++ of findClicked().) + + \image addressbook-tutorial-part5-signals-and-slots.png + +@@ -766,17 +771,17 @@ + \gui Find button without entering a contact's name. Then, we set + \c findText to the search string, extracted from \c lineEdit. After that, + we clear the contents of \c lineEdit and hide the dialog. ++ (There is no findText member. The description of accept() should move here, together ++ with words about reject.) + + \snippet examples/addressbook-sdk/part5/finddialog.cpp findClicked + +- The \c findText variable has a public getter function, \c getFindText(), +- associated with it. Since we only ever set \c findText directly in both +- the constructor and in hte \c findClicked() function, we do not create a +- setter function to accompany \c getFindText(). Because \c getFindText() is ++ The \c text of the find dialog's line edit has a public getter function, \c findText(), ++ associated with it. Because \c findText() is + public, classes instantiating and using \c FindDialog can always access the + search string that the user has entered and accepted. + +- \snippet examples/addressbook-sdk/part5/finddialog.cpp getFindText ++ \snippet examples/addressbook-sdk/part5/finddialog.cpp findText + + + \section1 The AddressBook Class +@@ -788,23 +793,9 @@ + + So far, all our address book features have a QPushButton and a + corresponding slot. Similarly, for the \gui Find feature, we have +- \c findButton and \c findContact(). ++ \c {ui->findButton} and \c findContact(). + + \snippet examples/addressbook-sdk/part5/addressbook.h slot definition +- \dots +- \snippet examples/addressbook-sdk/part5/addressbook.h private members +- +- Lastly, we declare the private variable, \c dialog, which we will use to +- refer to an instance of \c FindDialog. +- +- Once we have instantiated a dialog, we might want to use it more than once; +- using a private variable allows us to refer to it from more than one place +- in the class. +- +- Within the \c AddressBook class's constructor, we insantiate our private +- objects, \c findButton and \c dialog: +- +- \snippet examples/addressbook-sdk/part5/addressbook.cpp private members + + Next, we connect the \c{findButton}'s \l{QPushButton::}{clicked()} signal + to \c findContact(). +@@ -818,10 +809,12 @@ + We start out by displaying the \c FindDialog instance, \c dialog. This is + when the user enters a contact name to look up. Once the user clicks the + dialog's \c findButton, the dialog is hidden and the result code is set to +- QDialog::Accepted. THis ensures that our \c if statement is always true. ++ either QDialog::Accepted or QDialog::Rejected by the FindDialog's ++ \c findClicked() method. This ensures that we only search for a contact ++ if the user typed something in the FindDialog's line edit. + + We then proceed to extract the search string, which in this case is +- \c contactName, using \c{FindDialog}'s \c getFindText() function. If the ++ \c contactName, using \c{FindDialog}'s \c findText() function. If the + contact exists in our address book, we display it immediately. Otherwise, + we display the QMessageBox shown below to indicate that their search + failed. diff --git a/doc/examples/addressbook-sdk/part6/addressbook.cpp b/doc/examples/addressbook-sdk/part6/addressbook.cpp index 6d8a15bc24d..4927eae297d 100644 --- a/doc/examples/addressbook-sdk/part6/addressbook.cpp +++ b/doc/examples/addressbook-sdk/part6/addressbook.cpp @@ -1,3 +1,5 @@ +#include + #include "addressbook.h" #include "ui_addressbook.h" @@ -31,6 +33,12 @@ AddressBook::AddressBook(QWidget *parent) SLOT(removeContact())); connect(ui->findButton, SIGNAL(clicked()), this, SLOT(findContact())); + //! [connectSlots] + connect(ui->loadButton, SIGNAL(clicked()), this, + SLOT(loadFromFile())); + connect(ui->saveButton, SIGNAL(clicked()), this, + SLOT(saveToFile())); + //! [connectSlots] setWindowTitle(tr("Simple Address Book")); } @@ -292,7 +300,7 @@ void AddressBook::loadFromFile() //! [loadFromFile part3] if (contacts.isEmpty()) { - QMessagebox::information(this, tr("No contacts in file"), + QMessageBox::information(this, tr("No contacts in file"), tr("The file you are attempting to open contains no contacts.")); } else { QMap::iterator i = contacts.begin(); diff --git a/doc/examples/addressbook-sdk/part7/addressbook.cpp b/doc/examples/addressbook-sdk/part7/addressbook.cpp index 5761030f4ab..f70fbda4844 100644 --- a/doc/examples/addressbook-sdk/part7/addressbook.cpp +++ b/doc/examples/addressbook-sdk/part7/addressbook.cpp @@ -1,3 +1,6 @@ +#include +#include + #include "addressbook.h" #include "ui_addressbook.h" @@ -348,5 +351,5 @@ void AddressBook::exportAsVCard() out << "END;VCARD" << "\n"; QMessageBox::information(this, tr("Export Successful"), - tr("\%1\" has been exported as a vCard.").arg(name)); + tr("\"%1\" has been exported as a vCard.").arg(name)); } diff --git a/doc/images/addressbook-tutorial-part5-dialogbox.png b/doc/images/addressbook-tutorial-part5-dialogbox.png new file mode 100644 index 00000000000..ad7378ccf28 Binary files /dev/null and b/doc/images/addressbook-tutorial-part5-dialogbox.png differ diff --git a/doc/images/addressbook-tutorial-part5-finddialog-in-designer.png b/doc/images/addressbook-tutorial-part5-finddialog-in-designer.png new file mode 100644 index 00000000000..2ffa61e36df Binary files /dev/null and b/doc/images/addressbook-tutorial-part5-finddialog-in-designer.png differ diff --git a/doc/images/addressbook-tutorial-part5-screenshot.png b/doc/images/addressbook-tutorial-part5-screenshot.png new file mode 100644 index 00000000000..f9c1e6ff7f1 Binary files /dev/null and b/doc/images/addressbook-tutorial-part5-screenshot.png differ diff --git a/doc/images/addressbook-tutorial-part6-opendialog.png b/doc/images/addressbook-tutorial-part6-opendialog.png new file mode 100644 index 00000000000..4f281faca5b Binary files /dev/null and b/doc/images/addressbook-tutorial-part6-opendialog.png differ diff --git a/doc/images/addressbook-tutorial-part6-propertyeditor.png b/doc/images/addressbook-tutorial-part6-propertyeditor.png new file mode 100644 index 00000000000..949c0be68d2 Binary files /dev/null and b/doc/images/addressbook-tutorial-part6-propertyeditor.png differ diff --git a/doc/images/addressbook-tutorial-part6-savedialog.png b/doc/images/addressbook-tutorial-part6-savedialog.png new file mode 100644 index 00000000000..0c1b0bbbdef Binary files /dev/null and b/doc/images/addressbook-tutorial-part6-savedialog.png differ diff --git a/doc/images/addressbook-tutorial-part6-screenshot.png b/doc/images/addressbook-tutorial-part6-screenshot.png new file mode 100644 index 00000000000..39c33a77f0c Binary files /dev/null and b/doc/images/addressbook-tutorial-part6-screenshot.png differ diff --git a/doc/images/addressbook-tutorial-part7-screenshot.png b/doc/images/addressbook-tutorial-part7-screenshot.png new file mode 100644 index 00000000000..e2f0cf47c09 Binary files /dev/null and b/doc/images/addressbook-tutorial-part7-screenshot.png differ diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index 3407b3645c1..f68a1cf6cc9 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -1618,9 +1618,11 @@ static void qDumpQList(QDumper &d) const QListData &ldata = *reinterpret_cast(d.data); const QListData::Data *pdata = *reinterpret_cast(d.data); - int nn = ldata.size(); + const int nn = ldata.size(); if (nn < 0) return; + const bool innerTypeIsPointer = isPointerType(d.innerType); + const int n = qMin(nn, 1000); if (nn > 0) { if (ldata.d->begin < 0) return; @@ -1631,18 +1633,19 @@ static void qDumpQList(QDumper &d) return; #endif qCheckAccess(ldata.d->array); - //qCheckAccess(ldata.d->array[0]); - //qCheckAccess(ldata.d->array[nn - 1]); + // Additional checks on pointer arrays + if (innerTypeIsPointer) + for (int i = 0; i != n; ++i) + if (const void *p = ldata.d->array + i + pdata->begin) + qCheckAccess(deref(p)); } qCheckAccess(pdata); - int n = nn; d.putItemCount("value", n); d.putItem("valueeditable", "false"); d.putItem("numchild", n); if (d.dumpChildren) { - unsigned innerSize = d.extraInt[0]; - bool innerTypeIsPointer = isPointerType(d.innerType); + const unsigned innerSize = d.extraInt[0]; QByteArray strippedInnerType = stripPointerType(d.innerType); // The exact condition here is: @@ -1653,8 +1656,6 @@ static void qDumpQList(QDumper &d) bool isInternal = innerSize <= int(sizeof(void*)) && isMovableType(d.innerType); d.putItem("internal", (int)isInternal); - if (n > 1000) - n = 1000; d.beginChildren(n ? d.innerType : 0); for (int i = 0; i != n; ++i) { d.beginHash(); @@ -2917,23 +2918,21 @@ static void qDumpQVector(QDumper &d) int nn = v->size; if (nn < 0) return; - if (nn > 0) { - //qCheckAccess(&vec.front()); - //qCheckAccess(&vec.back()); - } - + const bool innerIsPointerType = isPointerType(d.innerType); const unsigned innersize = d.extraInt[0]; + const int n = qMin(nn, 1000); + // Check pointers + if (innerIsPointerType && nn > 0) + for (int i = 0; i != n; ++i) + if (const void *p = addOffset(v, i * innersize + typeddatasize)) + qCheckAccess(deref(p)); - int n = nn; d.putItemCount("value", n); d.putItem("valueeditable", "false"); d.putItem("numchild", n); if (d.dumpChildren) { QByteArray strippedInnerType = stripPointerType(d.innerType); - const char *stripped = - isPointerType(d.innerType) ? strippedInnerType.data() : 0; - if (n > 1000) - n = 1000; + const char *stripped = innerIsPointerType ? strippedInnerType.data() : 0; d.beginChildren(d.innerType); for (int i = 0; i != n; ++i) { d.beginHash(); diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 1d348113c52..ca905d5a1f4 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -23,10 +23,6 @@ Qt Creator - Plugin loader messages Qt Creator - Meldungen der Plugin-Verwaltung - - Couldn't find 'Core.pluginspec' in %1 - Die Datei 'Core.pluginspec' konnte in %1 nicht gefunden werden - AttachCoreDialog @@ -69,29 +65,6 @@ Löschen - - AttachTcfDialog - - Start Debugger - Debugger starten - - - Host and port: - Host und Portnummer: - - - Architecture: - Architektur: - - - Use server start script: - Server-Startskript benutzen: - - - Server start script: - Server-Startskript: - - BINEditor::Internal::BinEditorPlugin @@ -616,12 +589,12 @@ "%1" hinzufügen - + Alt+C,Alt+A Alt+C,Alt+A - + Delete Löschen @@ -656,12 +629,12 @@ Diff für "%1" - + Alt+C,Alt+D Alt+C,Alt+D - + Commit All Files Alle Dateien abgeben @@ -676,12 +649,12 @@ "%1" abgeben - + Alt+C,Alt+C Alt+C,Alt+C - + Filelog Current File Filelog für Datei @@ -806,13 +779,7 @@ Executing in %1: %2 %3 - Kommando [%1]: %2 %3 - - - - Executing in %1: %2 %2 - - Kommando [%1]: %2 %3 + Kommando [%1]: %2 %3 @@ -940,7 +907,7 @@ CVSPlugin - + Cannot find repository for '%1' Das Repository der Datei '%1' konnte nicht gefunden werden @@ -1010,12 +977,12 @@ <Unknown Type> - + <Unbekannter Typ> <Unknown Value> - + <Unbekannter Wert> @@ -1076,22 +1043,22 @@ Ausschnitt einfügen... - + Alt+C,Alt+P Alt+C,Alt+P - + Fetch Snippet... Ausschnitt holen... - + Alt+C,Alt+F Alt+C,Alt+F - + This protocol supports no listing Dieses Protokoll stellt keine Liste zur Verfügung @@ -1187,10 +1154,6 @@ Skip known frames when stepping Bekannte Stellen beim Einzelschritt überspringen - - Use tooltips while debugging - Tooltips beim Debuggen benutzen - Maximal stack depth: @@ -1206,10 +1169,6 @@ Use alternating row colors in debug views Alternierende Farben für Debugansichten benutzen - - Checking this will enable tooltips for variable values during debugging. Since this can slow down debugging and does not provide reliable information as it does not use scope information, it is switched off by default. - Diese Option aktiviert Tooltips für Variablen beim Debuggen. Das es das Debuggen verlangsamt und wegen der fehlenden Scope-Information nicht zuverlässig ist, ist es per Vorgabe deaktiviert. - Enable reverse debugging @@ -1223,7 +1182,7 @@ Use tooltips in main editor while debugging - + Tooltips beim Debuggen benutzen @@ -1349,12 +1308,12 @@ Sollen sie überschrieben werden? Core::EditorManager - + Revert to Saved Wiederherstellen - + Close Schließen @@ -1366,12 +1325,12 @@ Sollen sie überschrieben werden? - + Close Others Andere schließen - + Open in External Editor Öffne in externem Editor @@ -1431,57 +1390,42 @@ Sollen sie überschrieben werden? Alt+Right - + + Meta+E + Meta+E + + + + Ctrl+E + Ctrl+E + + + Split Teilen - - Ctrl+E,2 - Ctrl+E,2 - - - + Split Side by Side Nebeneinander teilen - - Ctrl+E,3 - Ctrl+E,3 - - - + Remove Current Split Teilung aufheben - - Ctrl+E,0 - Ctrl+E,0 - - - + Remove All Splits Alle Teilungen aufheben - - Ctrl+E,1 - Ctrl+E,1 - - - + Goto Other Split Gehe zu anderer Teilung - - Ctrl+E,o - Ctrl+E,o - - - + &Advanced &Weitere @@ -1559,7 +1503,7 @@ Sollen sie überschrieben werden? Schreibbar machen - + Next Open Document in History Nächstes geöffnetes Dokument im Verlauf @@ -1579,7 +1523,32 @@ Sollen sie überschrieben werden? Nächstes - + + %1,2 + %1,2 + + + + %1,3 + %1,3 + + + + %1,0 + %1,0 + + + + %1,1 + %1,1 + + + + %1,o + %1,o + + + Save %1 As... Speicher '%1' unter... @@ -1626,23 +1595,15 @@ Sollen sie überschrieben werden? Core::FileManager - - Can't save file - Die Datei kann nicht gespeichert werden - - - Can't save changes to '%1'. Do you want to continue and loose your changes? - Die Datei '%1' kann nicht gespeichert werden. Wollen Sie trotzdem fortsetzen und Ihre Änderungen aufgeben? - Cannot save file - Die Datei kann nicht gespeichert werden + Die Datei kann nicht gespeichert werden Cannot save changes to '%1'. Do you want to continue and lose your changes? - Die Datei '%1' kann nicht gespeichert werden. Wollen Sie trotzdem fortsetzen und Ihre Änderungen aufgeben? + Die Datei '%1' kann nicht gespeichert werden. Wollen Sie trotzdem fortsetzen und Ihre Änderungen aufgeben? @@ -1833,7 +1794,7 @@ Sollen sie überschrieben werden? External editor: - 'Externer Editor: + Externer Editor: @@ -1864,7 +1825,7 @@ Sollen sie überschrieben werden? Core::Internal::MainWindow - + Qt Creator Qt Creator @@ -2044,6 +2005,11 @@ Sollen sie überschrieben werden? Title of dialog Neu... + + + Settings... + Einstellungen... + Core::Internal::MessageOutputWindow @@ -2218,14 +2184,10 @@ Sollen sie überschrieben werden? Core::Internal::SaveItemsDialog - - Don't Save - Nicht speichern - Do not Save - Nicht speichern + Nicht speichern @@ -2352,19 +2314,19 @@ Sollen sie überschrieben werden? CppEditor::Internal::CPPEditor - + Sort alphabetically Alphabetisch sortieren - + This change cannot be undone. - + Diese Änderung kann nicht rückgängig gemacht werden. Yes, I know what I am doing. - + Ja, Ich bin mir dessen bewußt. @@ -2459,12 +2421,12 @@ Sollen sie überschrieben werden? Find Usages - + Verwendung suchen Ctrl+Shift+U - Ctrl+Shift+U + Ctrl+Shift+U @@ -2503,7 +2465,7 @@ Sollen sie überschrieben werden? CppPreprocessor - + %1: No such file or directory %1: Es existiert keine Datei oder kein Verzeichnis dieses Namens @@ -2593,7 +2555,7 @@ Sollen sie überschrieben werden? CppTools::Internal::CppFindReferences - + Searching... Suche... @@ -2609,7 +2571,7 @@ Sollen sie überschrieben werden? CppTools::Internal::CppModelManager - + Scanning Suche @@ -2630,7 +2592,7 @@ Sollen sie überschrieben werden? CppTools::Internal::CppToolsPlugin - + &C++ &C++ @@ -2640,32 +2602,6 @@ Sollen sie überschrieben werden? Zwischen Header- und Quelldatei wechseln - - CppTools::Internal::FindClassDeclarations - - - Search class - Suche Klasse - - - - Class Declarations - Klassendeklarationen - - - - CppTools::Internal::FindFunctionCalls - - - Search functions - Suche Funktion - - - - Function calls - Funktionsaufrufe - - CppTools::Internal::FunctionArgumentWidget @@ -2695,18 +2631,18 @@ Sollen sie überschrieben werden? Debugger::DebuggerManager - + Continue Fortsetzen - + Interrupt Anhalten - + Reset Debugger Debugger zurücksetzen @@ -2768,7 +2704,7 @@ Sollen sie überschrieben werden? Exited. - Beendet. + Beendet. @@ -2782,12 +2718,7 @@ Sollen sie überschrieben werden? Diese Anwendung erfordert den Debugger '%1', der gegenwärtig deaktiviert ist. - - Debugging VS executables is currently not enabled. - Das Debuggen von mit VS erzeugten ausführbaren Dateien ist momentan deaktiviert. - - - + Starting debugger for tool chain '%1'... Starte Debugger für Toolchain '%1'... @@ -2802,11 +2733,7 @@ Sollen sie überschrieben werden? Der Debugger kann nicht mit '%1' (Toolchain '%2') gestartet werden: %3 - Settings... - Einstellungen... - - - + Save Debugger Log Debugger Log speichern @@ -2850,19 +2777,11 @@ Sollen sie überschrieben werden? Stop Debugger Debugger anhalten - - Stop requested... - Stop angefordert... - - - Running requested... - Fortsetzung angefordert... - Debugger::Internal::AddressDialog - + Select start address Startadresse @@ -2908,37 +2827,6 @@ Sollen sie überschrieben werden? Aktualisieren - - Debugger::Internal::AttachGdbAdapter - - Cannot set up communication with child process: %1 - Die Kommunikation mit dem untergeordneten Prozesss konnte nicht hergestellt werden: %1 - - - - Attached to stopped inferior. - - - - - Inferior process could not be stopped: - - - - - - Gdb process could not be stopped: - - - - - - Debugger::Internal::AttachTcfDialog - - Select Executable - Ausführbare Datei auswählen - - Debugger::Internal::BreakHandler @@ -3039,7 +2927,7 @@ Sollen sie überschrieben werden? Address - Adresse + Adresse @@ -3149,12 +3037,27 @@ Sollen sie überschrieben werden? Der Funktionsaufruf "%1()" schlug fehl: %2 - + Unable to resolve '%1' in the debugger engine library '%2' '%1' konnte in der Debugger-Bibliothek '%2' nicht gefunden werden - + + Version: %1 + Version: %1 + + + + <html>The installed version of the <i>Debugging Tools for Windows</i> (%1) is rather old. Upgrading to version %2 is recommended for the proper display of Qt's data types.</html> + <html>Die gegenwärtig installierte Version der <i>Debugging Tools for Windows</i> (%1) ist veraltet. Es wird ein Upgrade auf Version %2 empfohlen, um die Qt-Datentypen richtig anzeigen zu können.</html> + + + + Debugger + Debugger + + + The dumper library was not found at %1. Es konnte keine Ausgabe-Hilfsbibliothek unter %1 gefunden werden. @@ -3191,52 +3094,52 @@ Sollen sie überschrieben werden? The process exited with exit code %1. - + Der Prozess wurde beendet, Rückgabewert %1. Continuing with '%1'... - + Setze mit '%1' fort... Unable to continue: %1 - + Die Ausführung des Prozesses kann nicht fortgesetzt werden: %1 Reverse stepping is not implemented. - + Die Funktionalität für 'Einzelschritt rückwärts' ist nicht implementiert. Stepping %1 - + Führe Schritt aus (%1) Running to 0x%1... - + Ausführung bis zur Adresse 0x%1... Running requested... - Fortsetzung angefordert... + Fortsetzung angefordert... Running up to %1:%2... - + Ausführung bis %1:%2... Running up to function '%1()'... - + Ausführung bis zu Funktion '%1()'... Jump to line is not implemented - + Die Funktionalität für 'Springe zu Zeile' ist nicht implementiert @@ -3262,22 +3165,22 @@ Sollen sie überschrieben werden? Stopped, current thread: %1 - + Angehalten, Thread: %1 Changing threads: %1 -> %2 - + Wechsel von Thread %1 zu %2 Thread %1: Missing debug information for top stack frame (%2). - + Thread %1: Es ist keine Debug-Information für obersten Stack-Rahmen (%2) vorhanden. Thread %1: No debug information available (%2). - + Thread %1: Es ist keine Debug-Information vorhanden (%2). @@ -3333,7 +3236,7 @@ Sollen sie überschrieben werden? Die Ausgabe-Hilfsbibliothek konnte nicht initialisiert werden: %1 - + Querying dumpers for '%1'/'%2' (%3) Abfrage der Ausgabe-Hilfsbibliothek für '%1'/'%2' (%3) @@ -3388,47 +3291,39 @@ Sollen sie überschrieben werden? Debugger::Internal::CoreGdbAdapter - - Cannot set up communication with child process: %1 - Die Kommunikation mit dem untergeordneten Prozesss konnte nicht hergestellt werden: %1 - Attached to core. - + Debugge core-Datei. Symbols found. - + Die Symbole wurden gefunden. Attached to core temporarily. - + Debugge core-Datei temporär. No binary found. - + Es konnte keine ausführbare Datei gefunden werden. Symbols not found in "%1" failed: %2 - + In "%1" konnten keine Symbole gefunden werden; Fehler: +%2 Attach to core "%1" failed: %2 - - - - - Gdb process could not be stopped: - - + Das Debuggen der core-Datei "%1" schlug fehl: +%2 @@ -3484,14 +3379,6 @@ Sollen sie überschrieben werden? Attach to Core... Debugge core-Datei - - Attach to Running Tcf Agent... - An laufenden Tcf-Agenten anhängen... - - - This attaches to a running 'Target Communication Framework' agent. - An einen laufenden 'Target Communication Framework'-Agenten anhängen. - Start and Attach to Remote Application... @@ -3570,22 +3457,23 @@ Sollen sie überschrieben werden? Attaching to core %1. - + Debugge core-Datei %1. Debugger::Internal::DebuggerRunControlFactory - + Debug Debuggen - Debugger::Internal::DebuggerRunner + Debugger::Internal::DebuggerRunControl - Debug - Debuggen + + Debugger + Debugger @@ -3620,29 +3508,25 @@ Sollen sie überschrieben werden? Log time stamps Zeitstempel loggen - - Step by instruction - Einzelschritt über Anweisung - Operate by instruction - + Auf Anweisungsebene arbeiten This switches the debugger to instruction-wise operation mode. In this mode, stepping operates on single instructions and the source location view also shows the disassembled instructions. - + Weist den Debugger an, auf Anweisungsebene zu arbeiten. In diesem Modus arbeitet die Einzelschritt-Funktion auf Maschinenanweisungen und die Quelltextanzeige zeigt die disassemblierten Anweisungen an. Dereference pointers automatically - + Zeiger automatisch dereferenzieren This switches the Locals&Watchers view to automatically derefence pointers. This saves a level in the tree view, but also loses data for the now-missing intermediate level. - + Bewirkt, dass Zeiger im Fenster "Lokale Variablen und Überwachte Ausdrücke" automatisch dereferenziert werden. Das vereinfacht die Baumanzeige, allerdings fehlt die Information über die Zwischenebene. @@ -3687,56 +3571,52 @@ Sollen sie überschrieben werden? Use tooltips in main editor when debugging - + Tooltips im Haupt-Editor beim Debuggen benutzen Checking this will enable tooltips for variable values during debugging. Since this can slow down debugging and does not provide reliable information as it does not use scope information, it is switched off by default. - Diese Option aktiviert Tooltips für Variablen beim Debuggen. Das es das Debuggen verlangsamt und wegen der fehlenden Scope-Information nicht zuverlässig ist, ist es per Vorgabe deaktiviert. + Diese Option aktiviert Tooltips für Variablen beim Debuggen. Da es das Debuggen verlangsamt und wegen der fehlenden Scope-Information nicht zuverlässig ist, ist es per Vorgabe deaktiviert. Use tooltips in locals view when debugging - + Tooltips für Anzeige der lokalen Variablen Checking this will enable tooltips in the locals view during debugging. - + Schaltet Tooltips für die Anzeige der lokalen Variablen während des Debuggens ein. Use tooltips in breakpoints view when debugging - + Tooltips im Haltepunkt-Fenster Checking this will enable tooltips in the breakpoints view during debugging. - + Schaltet Tooltips im Haltepunkt-Fenster während des Debuggens ein. Show address data in breakpoints view when debugging - + Adresse des Haltepunkts anzeigen Checking this will show a column with address information in the breakpoint view during debugging. - + Fügt eine Spalte mit den Adressen der Haltepunkte zur Anzeige während des Debuggens hinzu. Show address data in stack view when debugging - + Addressen im Stack-Fenster anzeigen Checking this will show a column with address information in the stack view during debugging. - - - - Use tooltips when debugging - Tooltips beim Debuggen benutzen + Fügt eine Spalte mit Adressinformation zur Anzeige während des Debuggens hinzu. @@ -3785,7 +3665,7 @@ Sollen sie überschrieben werden? Debugger::Internal::GdbEngine - + The Gdb process failed to start. Either the invoked program '%1' is missing, or you may have insufficient permissions to invoke the program. Der Start des Gdb-Prozesses schlug fehl. Entweder fehlt die ausführbare Datei '%1' oder die Berechtigungen sind nicht ausreichend. @@ -3810,16 +3690,12 @@ Sollen sie überschrieben werden? Ein Fehler trat beim Versuch des Lesens vom Gdb-Prozess auf. Wahrscheinlich läuft der Prozess nicht. - An unknown error in the Gdb process occurred. This is the default return value of error(). - Es trat ein unbekannter Fehler im Gdb-Prozess auf. - - - + Error Fehler - + Library %1 loaded. Bibliothek %1 geladen. @@ -3834,7 +3710,7 @@ Sollen sie überschrieben werden? Thread-Gruppe %1 erzeugt. - + Thread %1 created. Thread-Gruppe %1 erzeugt. @@ -3854,36 +3730,17 @@ Sollen sie überschrieben werden? Thread %1 ausgewählt. - Debugger Error - Debugger-Fehler - - - + Stopping temporarily. Temporär Anhalten. - - Executable failed: - - Die ausführbare Datei schlug: - - Process failed to start. Der Prozess konnte nicht gestartet werden. - - Continuing after temporary stop. - Fortsetzen nach temporären Anhalten. - - - Core file loaded. - Core-Datei geladen. - - - + <p>The inferior stopped because it received a signal from the Operating System.<p><table><tr><td>Signal name : </td><td>%1</td></tr><tr><td>Signal meaning : </td><td>%2</td></tr></table> <p>Der Prozess wurde nach Erhalt eines Signals vom Betriebssystem angehalten.<p><table><tr><td>Name des Signals : </td><td>%1</td></tr><tr><td>Bedeutung : </td><td>%2</td></tr></table> @@ -3899,32 +3756,12 @@ Sollen sie überschrieben werden? Signal erhalten - + The dumper library was not found at %1. Es konnte keine Ausgabe-Hilfsbibliothek unter %1 gefunden werden. - The upload process failed to start. Either the invoked script '%1' is missing, or you may have insufficient permissions to invoke the program. - Das Hochladen konnte nicht gestartet weden. Entweder fehlt das Skript '%1', oder die Berechtigungen sind nicht ausreichend. - - - The upload process crashed some time after starting successfully. - Das Hochladen ist nach dem Starten abgestürzt. - - - An error occurred when attempting to write to the upload process. For example, the process may not be running, or it may have closed its input channel. - Ein Fehler trat beim Versuch des Schreibens zum Hochlade-Prozess auf. Wahrscheinlich läuft der Prozess nicht, oder hat seinen Eingabekanal geschlossen. - - - An error occurred when attempting to read from the upload process. For example, the process may not be running. - Ein Fehler trat beim Versuch des Lesens vom Hochlade-Prozess auf. Wahrscheinlich läuft der Prozess nicht. - - - An unknown error in the upload process occurred. This is the default return value of error(). - Es trat ein unbekannter Fehler im Hochlade-Prozess auf. - - - + Reading %1... Lese %1... @@ -3934,29 +3771,17 @@ Sollen sie überschrieben werden? Sprung ausgeführt/ Angehalten. - + Run to Function finished. Stopped. Ausgeführung bis zu Funktion beendet. Angehalten. - Program exited with exit code %1 - Das Programm wurde beendet, Rückgabewert %1 - - - Program exited after receiving signal %1 - Das Programm wurde nach Erhalt des Signals %1 beendet - - - Program exited normally - Das Programm wurde normal beendet - - - + Loading %1... Lade %1... - + Stopped at breakpoint. An Haltepunkt angehalten. @@ -3987,40 +3812,19 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. - + Processing queued commands. Kommando-Warteschlange wird abgearbeitet. - - + Stopped. Angehalten. - Debugger Startup Failure - Fehler beim Starten des Debuggers - - - Cannot set up communication with child process: %1 - Die Kommunikation mit dem untergeordneten Prozesss konnte nicht hergestellt werden: %1 - - - Starting Debugger: - Starte Debugger: - - - Cannot start debugger: %1 - Der Debugger konnte nicht gestartet werden: %1 - - - Gdb Running... - Gdb läuft... - - - + Cannot find debugger initialization script Das Initalisierungsskript konnte nicht gefunden werden @@ -4030,19 +3834,7 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Auf die in den Debugger-Einstellungen angegebene Skriptdatei '%1' kann nicht zugegriffen werden. Wenn kein Skript benötigt wird, können Sie die Einstellung rücksetzen, um diese Warnung zu umgehen. - Attached to running process. Stopped. - An laufenden Prozess angehängt. Angehalten. - - - Connecting to remote server failed: - Die Verbindung zum Server konnte nicht hergestellt werden: - - - Debugger exited. - Debugger beendet. - - - + Unable to run '%1': %2 '%1' kann nicht ausgeführt werden: %2 @@ -4100,12 +3892,12 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. - + An unknown error in the Gdb process occurred. - + Im Gdb-Prozess trat ein unbekannter Fehler auf. - + Running... Läuft... @@ -4118,77 +3910,82 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Executable failed - + Fehler bei Ausführung Executable failed: %1 - + Fehler bei Ausführung: %1 Function reached. Stopped. - + Die Funktion wurde erreicht. Angehalten. Program exited with exit code %1. - + Das Programm wurde beendet, Rückgabewert %1. Program exited after receiving signal %1. - + Das Programm wurde nach Erhalt des Signals %1 beendet. Program exited normally. - + Das Programm wurde normal beendet. - + Starting executable failed - + Das Starten der ausführbaren Datei schlug fehl - + + Continuing after temporary stop... + Setze nach temporärem Anhalten fort... + + + Running requested... Fortsetzung angefordert... - + Step requested... - + Einzelschritt angefordert... Step by instruction requested... - + Einzelschritt über Anweisung angefordert... Finish function requested... - + Ausführung bis Funktionsende angefordert... Step next requested... - + Einzelschritt angefordert... Step next instruction requested... - + Einzelschritt über Anweisung angefordert... Run to line %1 requested... - + Ausführung bis Zeile %1 angefordert... Run to function %1 requested... - + Ausführung bis Funktion %1 angefordert... @@ -4253,52 +4050,52 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Disassembler failed: %1 - + Fehler beim Disassemblieren: %1 Adapter start failed - + Der Start des Adapters schlug fehl - + Inferior start preparation failed - + Die Vorbereitung des zu debuggenden Prozesses schlug fehl Inferior prepared for startup. - + Zu debuggender Prozess vorbereitet. Setting breakpoints... - + Setze Haltepunkte... Starting inferior... - + Starte zu debuggenden Prozess... Inferior start failed - + Der Start des zu debuggenden Prozesses schlug fehl Inferior shutdown failed - + Das Beenden des zu debuggenden Prozesses schlug fehl Adapter crashed - + Der Adapter ist abgestürzt Adapter shutdown failed - + Das Beenden des Adapter schlug fehl @@ -4465,27 +4262,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Das Starten der ausführbaren Datei schlug fehl: - - - Inferior started. - - - - - Inferior process could not be stopped: - - - - - - Gdb process could not be stopped: - - - - - Debugger Error - Debugger-Fehler - Debugger::Internal::RegisterHandler @@ -4522,10 +4298,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Reload register listing Register neu laden - - Always reload register listing - Register immer laden - Open memory editor @@ -4559,10 +4331,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Debugger::Internal::RemoteGdbAdapter - - Cannot set up communication with child process: %1 - Die Kommunikation mit dem untergeordneten Prozesss konnte nicht hergestellt werden: %1 - The upload process failed to start. Either the invoked script '%1' is missing, or you may have insufficient permissions to invoke the program. @@ -4601,36 +4369,14 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Adapter too old: does not support asynchronous mode. - + Der Adapter ist veraltet; er unterstützt den asynchronen Modus nicht. Starting remote executable failed: - - - - - Connecting to remote server failed: - - - - - - Attached to stopped inferior. - - - - - Inferior process could not be stopped: - - - - - - Gdb process could not be stopped: - - + Das Starten der ausführbaren Datei auf dem entfernten Rechner schlug fehl: + @@ -4662,17 +4408,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Angehalten. - - Debugger::Internal::SourceFilesModel - - Internal name - Interner Name - - - Full name - Vollständiger Name - - Debugger::Internal::SourceFilesWindow @@ -4839,17 +4574,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Ausführbare Datei auswählen - - Debugger::Internal::TcfEngine - - Running requested... - Fortsetzung angefordert... - - - Stopped. - Angehalten. - - Debugger::Internal::ThreadsHandler @@ -4880,12 +4604,12 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Thread: %1 at %2 (0x%3) - + Thread: %1bei %2 (0x%3) Thread: %1 at %2, %3:%4 (0x%5) - + Thread: %1 bei %2, %3:%4 (0x%5) @@ -4917,37 +4641,8 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Connecting to trk server adapter failed: - - - - - Inferior running. - - - - - Connecting to remote server failed: - Die Verbindung zum Server konnte nicht hergestellt werden: - - - - Inferior process could not be stopped: - - - - - - Gdb process could not be stopped: - - - - - - Debugger::Internal::TrkOptionsPage - - - S60 / Trk - + Die Verbindung zum Trk-Server-Adapter schlug fehl: + @@ -4965,37 +4660,32 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Symbian ARM gdb location: - - - - - Cygwin location: - + Pfad zu Symbian-ARM gdb: Communication - + Kommunkation Serial Port - + Serielle Schnittstelle Bluetooth - + Bluetooth Port: - + Port: Device: - + Gerät: @@ -5071,7 +4761,7 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Generation - + Generation @@ -5170,14 +4860,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Speicher-Editor bei %1 öffnen - - Debugger::MessageBox - - - Settings... - Einstellungen... - - DebuggerPane @@ -5494,7 +5176,7 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. Signals && Slots Editor - + Signale und Slots @@ -5545,13 +5227,6 @@ Es wird empfohlen, gdb 6.7 oder später zu benutzen. %1 - Fehler - - Designer::Internal::FormWindowEditor - - untitled - kein Titel - - Designer::Internal::FormWindowFile @@ -5621,40 +5296,6 @@ Versuchen Sie, das Projekt neu zu erstellen. Entfernen - - DuiEditor::Internal::DuiEditorPlugin - - Creates a Qt QML file. - Erzeugt eine Qt-QML-Datei. - - - Qt QML File - Qt QML-Datei - - - Qt - Qt - - - - DuiEditor::Internal::ScriptEditor - - <Select Symbol> - <Symbol auswählen> - - - Rename... - Umbenennen... - - - New id: - Neue Id: - - - Rename id '%1'... - Id '%1' Umbenennen - - EmbeddedPropertiesPage @@ -5915,14 +5556,6 @@ Grund: %3 FakeVim::Internal::FakeVimHandler - - %1,%2 - %1,%2 - - - %1 - %1 - Not implemented in FakeVim @@ -6017,84 +5650,6 @@ Grund: %3 Letzte Änderung erreicht - - FakeVim::Internal::FakeVimHandler::Private - - %1,%2 - %1,%2 - - - %1 - %1 - - - Not implemented in FakeVim - In FakeVim nicht implementiert - - - E20: Mark '%1' not set - E20: Die Marke '%1' ist nicht gesetzt - - - File '%1' exists (add ! to override) - Die '%1' existiert bereits (Fügen Sie ! an, um sie zu überschreiben) - - - Cannot open file '%1' for writing - Die Datei '%1' kann nicht zum Schreiben geöffnet werden - - - "%1" %2 %3L, %4C written - "%1" %2 %3L, %4C geschrieben - - - Cannot open file '%1' for reading - Die Datei '%1' kann nicht zum Lesen geöffnet werden - - - "%1" %2L, %3C - "%1" %2L, %3C - - - %n lines filtered - - Eine Zeile gefiltert - %n Zeilen gefiltert - - - - - %n lines >ed %1 time - - Eine Zeile >ed %1-mal - %n Zeilen >ed %1-mal - - - - E512: Unknown option: - E512: Unbekannte Option: - - - search hit BOTTOM, continuing at TOP - Die Suche hat das Ende erreicht, setze am Anfang fort - - - search hit TOP, continuing at BOTTOM - Die Suche hat den Anfang erreicht, setze am Ende fort - - - Pattern not found: - Suchmuster nicht gefunden: - - - Already at oldest change - Älteste Änderung erreicht - - - Already at newest change - Letzte Änderung erreicht - - FakeVim::Internal::FakeVimOptionPage @@ -6440,13 +5995,13 @@ Grund: %3 - Replace all occurances - + Replace all occurrences + Alle Vorkommen ersetzen Replace - + Ersetzen @@ -7046,12 +6601,12 @@ Grund: %3 Diff für "%1" - + Alt+G,Alt+D Alt+G,Alt+D - + File Status Status der Datei @@ -7061,12 +6616,12 @@ Grund: %3 Status relativ zu "%1" - + Alt+G,Alt+S Alt+G,Alt+S - + Log File Log für Datei @@ -7076,12 +6631,12 @@ Grund: %3 Log für "%1" - + Alt+G,Alt+L Alt+G,Alt+L - + Blame Blame für Datei @@ -7091,12 +6646,12 @@ Grund: %3 Blame für "%1" - + Alt+G,Alt+B Alt+G,Alt+B - + Undo Changes Änderungen rückgängig machen @@ -7106,12 +6661,12 @@ Grund: %3 Änderungen in "%1" rückgängig machen - + Alt+G,Alt+U Alt+G,Alt+U - + Stage File for Commit Datei zu Commit hinzufügen (stage) @@ -7121,12 +6676,12 @@ Grund: %3 "%1" zu Commit hinzufügen (stage) - + Alt+G,Alt+A Alt+G,Alt+A - + Unstage File from Commit Datei aus Commit entfernen (unstage) @@ -7135,14 +6690,6 @@ Grund: %3 Unstage "%1" from Commit "%1" aus Commit entfernen (unstage) - - Revert... - Änderungen in Datei rückgängig machen... - - - Revert "%1"... - Änderungen in "%1" rückgängig machen... - Diff Current Project @@ -7154,7 +6701,7 @@ Grund: %3 Diff für Projekt "%1" - + Project Status Status des Projekts (status) @@ -7174,12 +6721,12 @@ Grund: %3 Log für Projekt "%1" - + Alt+G,Alt+K Alt+G,Alt+K - + Undo Project Changes Änderungen des Projekts rückgängig machen @@ -7214,12 +6761,12 @@ Grund: %3 Commit... - + Alt+G,Alt+C Alt+G,Alt+C - + Push Push @@ -7271,7 +6818,7 @@ Grund: %3 Would you like to revert all pending changes to the project? - + Möchten Sie alle ausstehenden Änderungen des Projektes rückgängig machen? @@ -7330,7 +6877,7 @@ Grund: %3 repository - + repository @@ -8067,7 +7614,7 @@ Grund: %3 Ctrl+O - Ctrl+O + @@ -8087,7 +7634,7 @@ Grund: %3 F5 - F5 + F5 @@ -8142,7 +7689,7 @@ Grund: %3 Debug - Debuggen + Debuggen @@ -8157,7 +7704,7 @@ Grund: %3 Open File - Datei öffnen + Datei öffnen @@ -8743,12 +8290,12 @@ p, li { white-space: pre-wrap; } "%1" anfordern - + Alt+P,Alt+E Alt+P,Alt+E - + Edit File Datei zum Editieren anfordern @@ -8763,12 +8310,12 @@ p, li { white-space: pre-wrap; } "%1" hinzufügen - + Alt+P,Alt+A Alt+P,Alt+A - + Add File Datei hinzufügen @@ -8798,12 +8345,12 @@ p, li { white-space: pre-wrap; } Änderungen in "%1" rückgängig machen (revert) - + Alt+P,Alt+R Alt+P,Alt+R - + Revert File Änderungen in Datei rückgängig machen (revert) @@ -8829,12 +8376,12 @@ p, li { white-space: pre-wrap; } Diff für Projekt "%1" - + Alt+P,Alt+D Alt+P,Alt+D - + Diff Opened Files Diff für angeforderte Dateien @@ -8844,12 +8391,12 @@ p, li { white-space: pre-wrap; } Angefordert - + Alt+P,Alt+O Alt+P,Alt+O - + Submit Project Projekt abgeben @@ -8896,22 +8443,22 @@ p, li { white-space: pre-wrap; } - + Filelog Current File Filelog für Datei - + Filelog "%1" Filelog für "%1" - + Alt+P,Alt+F Alt+P,Alt+F - + Filelog... Filelog... @@ -9287,17 +8834,7 @@ p, li { white-space: pre-wrap; } Plugin is not valid (does not derive from IPlugin) - - - - -Library base name: %1 - -Basisname der Bibliothek: %1 - - - Plugin is not valid (doesn't derive from IPlugin) - Das Plugin ist ungültig (nicht von Klasse IPlugin abgeleitet) + Das Plugin ist ungültig (nicht von Klasse IPlugin abgeleitet) @@ -9529,10 +9066,6 @@ Fehler: %2 ProjectExplorer::EnvironmentWidget - - Details - Details - &Edit @@ -9574,7 +9107,7 @@ Fehler: %2 Active run configuration - + Aktive Ausführungskonfiguration @@ -9598,24 +9131,6 @@ Fehler: %2 Such&muster für Dateinamen - - ProjectExplorer::Internal::ApplicationRunConfigurationRunner - - Run - Ausführung - - - - ProjectExplorer::Internal::ApplicationRunControl - - Starting %1... - Starte %1... - - - %1 exited with code %2 - %1 beendet, Rückgabewert %2 - - ProjectExplorer::Internal::BuildSettingsPanel @@ -9627,11 +9142,7 @@ Fehler: %2 ProjectExplorer::Internal::BuildSettingsWidget - Create &New - &Neu erzeugen - - - + &Clone Selected Auswahl duplizieren @@ -9640,14 +9151,10 @@ Fehler: %2 Build Steps Erstellungsschritte - - Build Configuration: - Build-Konfiguration: - Edit Build Configuration: - + Build-Konfiguration bearbeiten: @@ -9664,10 +9171,6 @@ Fehler: %2 Clean Steps Schritte zur Bereinigung - - New configuration - Neue Konfiguration - New Configuration Name: @@ -9681,26 +9184,6 @@ Fehler: %2 ProjectExplorer::Internal::BuildStepsPage - - 1 - 1 - - - + - + - - - - - - - - - ^ - ^ - - - v - v - No Build Steps @@ -9714,7 +9197,7 @@ Fehler: %2 Add clean step - + Schritt zur Bereinigung hinzufügen @@ -9724,7 +9207,7 @@ Fehler: %2 Remove clean step - + Schritt zur Bereinigung entfernen @@ -9736,14 +9219,6 @@ Fehler: %2 Clean Steps Schritte zur Bereinigung - - Details - Details - - - No step selected - Kein Schritt ausgewählt - ProjectExplorer::Internal::CompileOutputWindow @@ -9761,10 +9236,6 @@ Fehler: %2 Cancel Build && Close Erstellen abbrechen und schließen - - Don't Close - Nicht schließen - A project is currently being built. @@ -9778,7 +9249,7 @@ Fehler: %2 Do not Close - + Nicht Schließen @@ -9862,7 +9333,8 @@ Fehler: %2 No Executable specified. - + Es wurde keine ausführbaren Datei angegeben. + @@ -9880,10 +9352,6 @@ Fehler: %2 ProjectExplorer::Internal::DependenciesWidget - - Details - Details - %1 has no dependencies. @@ -9966,7 +9434,7 @@ Fehler: %2 Run - + Ausführen @@ -10043,11 +9511,7 @@ Fehler: %2 <b>%1</b> %2 %3 %4 - - - - <b>Process Step</b> %1 %2 %3 - <b>Verarbeitungsschritt</b> %1 %2 %3 + <b>%1</b> %2 %3 %4 @@ -10095,10 +9559,6 @@ Fehler: %2 Projects Projekte - - Projectexplorer - Projekt-Explorer - ProjectExplorer::Internal::ProjectExplorerSettingsPageUi @@ -10160,12 +9620,12 @@ Fehler: %2 Edit Project Settings for Project <b>%1</b> - + Einstellungen für Projekt <b>%1</b> bearbeiten No Project loaded - + Es ist kein Projekt geladen @@ -10173,7 +9633,7 @@ Fehler: %2 Select Project - + Projekt auswählen @@ -10258,29 +9718,13 @@ Fehler: %2 No project loaded. - - - - Project Explorer - Projekt-Explorer - - - Projects - Projekte - - - Startup - Start - - - Path - Pfad + Es ist kein Projekt geladen. Active Build and Run Configurations - + Aktive Build- und Ausführungskonfigurationen @@ -10339,10 +9783,6 @@ Fehler: %2 - - - - Active run configuration: - Aktive Ausführungskonfiguration: - Edit run configuration: @@ -10545,7 +9985,7 @@ Fehler: %2 Show in Explorer... - + In Explorer anzeigen... @@ -10555,7 +9995,7 @@ Fehler: %2 Show containing folder... - + Ordner anzeigen... @@ -10772,22 +10212,22 @@ unter Versionsverwaltung (%2) gestellt werden? Launching Windows Explorer failed - + Das Starten des Windows-Explorers schlug fehl Could not find explorer.exe in path to launch Windows Explorer. - + Windows Explorer konnte nicht gestartet werden, da die Datei explorer.exe nicht im Pfad gefunden werden konnte. Launching a file explorer failed - + Das Starten des Datei-Browsers schlug fehl Could not find xdg-open to launch the native file explorer. - + Der Dateibrowser konnte nicht gestartet werden, da die Datei xdg-open nicht im Pfad gefunden werden konnte. @@ -10910,7 +10350,7 @@ unter Versionsverwaltung (%2) gestellt werden? Warning - Warnung + Warnung @@ -10979,7 +10419,7 @@ unter Versionsverwaltung (%2) gestellt werden? Qt - Qt + Qt @@ -11121,21 +10561,17 @@ unter Versionsverwaltung (%2) gestellt werden? QML Viewer QML-Betrachter - - Could not find the qmlviewer executable, please specify one. - Die ausführbare Datei des QML-Betrachters konnte nicht gefunden werden; bitte geben Sie sie an. - - + <Current File> <Aktuelle Datei> - + QML Viewer arguments: - + Kommandozeilenargumente für QML-Betrachter: @@ -11596,7 +11032,7 @@ unter Versionsverwaltung (%2) gestellt werden? Ctrl Shortcut key - + Ctrl @@ -11648,11 +11084,7 @@ unter Versionsverwaltung (%2) gestellt werden? You can quickly search methods, classes, help and more using the <a href="qthelp://com.nokia.qtcreator/doc/creator-navigation.html">Locator bar</a> (<tt>%1+K</tt>). - - - - You can quickly search methods, classes, help and more using the <a href="qthelp://com.nokia.qtcreator/doc/creator-navigation.html">Locator bar</a> (<tt>Ctrl+K</tt>). - Mit der <a href="qthelp://com.nokia.qtcreator/doc/creator-navigation.html">Locator bar</a> (<tt>Ctrl+K</tt>) können Sie schnell nach Klassen, Methoden, Hilfe und anderem suchen. + Mit der <a href="qthelp://com.nokia.qtcreator/doc/creator-navigation.html">Locator bar</a> (<tt>%1+K</tt>) können Sie schnell nach Methoden, Klassen, Hilfe und anderem suchen. @@ -11910,7 +11342,7 @@ unter Versionsverwaltung (%2) gestellt werden? Qt4ProjectManager::Internal::ProjectLoadWizard - + Import existing settings Existierende Einstellungen importieren @@ -11927,11 +11359,7 @@ unter Versionsverwaltung (%2) gestellt werden? <b>Note:</b> Importing the settings will automatically add the Qt Version identified by <br><b>%1</b> to the list of Qt versions. - - - - <b>Note:</b> Importing the settings will automatically add the Qt Version from:<br><b>%1</b> to the list of Qt versions. - <b>Hinweis:</b> Das Importieren der Einstellungen wird die Qt-Version aus:<br><b>%1</b> zur Liste der Qt-Versionen hinzufügen. + <b>Hinweis:</b> Das Importieren der Einstellungen wird die Qt-Version aus:<br><b>%1</b> zur Liste der Qt-Versionen hinzufügen. @@ -11960,27 +11388,27 @@ unter Versionsverwaltung (%2) gestellt werden? Headers - + Header-Dateien Sources - + Quelldateien Forms - + Formular-Dateien Resources - + Ressourcendateien Other files - + Andere Dateien @@ -12068,12 +11496,12 @@ unter Versionsverwaltung (%2) gestellt werden? Default Qt Version (%1) - + Vorgabe-Qt-Version (%1) No Qt Version set - + Es ist keine Qt-Version gesetzt @@ -12085,10 +11513,6 @@ unter Versionsverwaltung (%2) gestellt werden? General Allgemein - - Default Qt Version - Vorgabe-Qt-Version - Manage @@ -12099,18 +11523,6 @@ unter Versionsverwaltung (%2) gestellt werden? Tool Chain: Toolchain: - - Multi -Line -placeholder - Multi -Line -placeholder - - - Details - Details - Qt4ProjectManager::Internal::Qt4ProjectManagerPlugin @@ -12138,14 +11550,14 @@ placeholder Qt4ProjectManager::Internal::Qt4RunConfigurationWidget - - Running executable: <b>%1</b> %2 %3 - + + Running executable: <b>%1</b> %2 (in terminal) + Führe in Terminal aus: <b>%1</b> %2 - - (in terminal) - + + Running executable: <b>%1</b> %2 + Führe aus: <b>%1</b> %2 @@ -12220,32 +11632,20 @@ placeholder <specify a name> <Geben Sie einen Namen an> - - <specify a path> - <Geben Sie einenPfad an> - - - Select QTDIR - QTDIR Auswählen - - - Select the Qt Directory - Wählen Sie das Qt-Verzeichnis aus - <specify a qmake location> - + <Geben Sie den Pfad zu qmake an> Select QMake Executable - + Wählen Sie die ausführbare qmake-Datei aus Select the MinGW Directory - + Wählen Sie das MinGW-Verzeichnis aus @@ -12276,20 +11676,12 @@ placeholder The Qt Version identified by %1 is not installed. Run make install - + Die Qt-Version %1 ist nicht installiert. Führen Sie make install aus %1 does not specify a valid Qt installation - - - - The Qt Version %1 is not installed. Run make install - Die Qt-Version %1 ist nicht installiert. Führen Sie make install aus - - - %1 is not a valid Qt directory - %1 ist kein gültiges Qt-Verzeichnis + %1 ist keine gültige Qt-Installation @@ -12299,10 +11691,6 @@ placeholder Qt4ProjectManager::Internal::QtVersionManager - - Path: - Pfad: - Qt versions @@ -12323,10 +11711,6 @@ placeholder Name Name - - Path - Pfad - Debugging Helper @@ -12388,12 +11772,12 @@ p, li { white-space: pre-wrap; } QMake Location - + QMake-Pfad QMake Location: - + QMake-Pfad: @@ -12407,31 +11791,25 @@ p, li { white-space: pre-wrap; } Qt4ProjectManager::Internal::S60DeviceDebugRunControl - + Warning: Cannot locate the symbol file belonging to %1. - + Warnung: Die zu %1 gehörige Symboldatei konnte nicht gefunden werden. Launching debugger... - + Starte Debugger... Debugging finished. - + Debuggen beendet. Qt4ProjectManager::Internal::S60DeviceRunConfiguration - - %1 on Device - %1 auf Gerät - - - - + QtS60DeviceRunConfiguration QtS60DeviceRunConfiguration @@ -12441,27 +11819,17 @@ p, li { white-space: pre-wrap; } %1 konnte nicht ausgewertet werden. Die Qt S60-Ausführungskonfiguration %2 kann nicht gestartet werden. - Cannot open %1: %2 - Die Datei %1 kann nicht geöffnet werden: %2 - - - Unable to find the executable in the package file %1. - Es wurde keine ausführbare Datei in dem Installationspaket %1 gefunden. + + %1 on Symbian Device + %1 auf Symbian-Gerät Qt4ProjectManager::Internal::S60DeviceRunConfigurationFactory - - %1 on Device - %1 auf Gerät - - - - Qt4ProjectManager::Internal::S60DeviceRunConfigurationRunner - - Run on Device - Auf Gerät ausführen + + %1 on Symbian Device + %1 auf Symbian-Gerät @@ -12510,41 +11878,9 @@ p, li { white-space: pre-wrap; } Qt4ProjectManager::Internal::S60DeviceRunControl - + Could not start application: %1 - - - - Creating %1.sisx ... - Erstelle %1.sisx ... - - - Executable file: %1 - Ausführbare Datei: %1 - - - %1 %2 - %1 %2 - - - An error occurred while creating the package. - Bei der Erstellung des Installationspakets trat ein Fehler auf. - - - Package: %1 -Deploying application to '%2'... - Installationspaket: %1 -Installiere Anwendung auf '%2'... - - - Could not connect to phone on port '%1': %2 -Check if the phone is connected and the TRK application is running. - Die Verbindung zum Gerät über den Port '%1' konnte nicht hergestellt werden: %2 -Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' läuft. - - - Copying install file... - Kopiere Installationspaket... + Die Anwendung konnte nicht gestartet werden: %1 @@ -12556,37 +11892,21 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Application running with pid %1. Die Anwendung läuft mit der Prozess-Id: %1. - - An error has occurred while running %1. - Bei der Ausführung von %1 trat ein Fehler auf. - - - Installing application... - Installiere Anwendung... - Finished. Beendet. - - Failed to start %1. - %1 konnte nicht gestartet werden. - - - %1 has unexpectedly finished. - %1 ist abgestürzt. - Qt4ProjectManager::Internal::S60DeviceRunControlBase - + Could not install from package %1 on device: %2 - + Das Installation des Pakets %1 auf dem Gerät schlug fehl: %2 - + Creating %1.sisx ... Erstelle %1.sisx ... @@ -12596,23 +11916,28 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Ausführbare Datei: %1 - - + + Debugger for Symbian Platform + Debugger für Symbian-Platform + + + + %1 %2 %1 %2 - + Could not read template package file '%1' - + Die Vorlagedatei für die Paketbeschreibung ('%1') konnte nicht gelesen werden - + Could not write package file '%1' - + Die Paketbeschreibungsdatei '%1' konnte nicht geschrieben werden - + An error occurred while creating the package. Bei der Erstellung des Installationspakets trat ein Fehler auf. @@ -12634,17 +11959,17 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Could not create file %1 on device: %2 - + Die Datei %1 konnte nicht auf dem Gerät erzeugt werden: %2 Could not write to file %1 on device: %2 - + Die Datei %1 konnte nicht auf dem Gerät geschrieben werden: %2 Could not close file %1 on device: %2. It will be closed when App TRK is closed. - + Die Datei %1 konnte nicht auf dem Gerät geschlossen werden: %2. Sie wird beim Beenden der Trk-Anwendung geschlossen. @@ -12654,7 +11979,7 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' %1% copied. - + %1% kopiert. @@ -12722,17 +12047,17 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Qt4ProjectManager::Internal::S60EmulatorRunConfiguration - %1 in Emulator - %1 im Emulator + %1 in Symbian Emulator + %1 im Symbian-Emulator - QtS60EmulatorRunConfiguration - QtS60EmulatorRunConfiguration + QtSymbianEmulatorRunConfiguration + QtSymbianEmulatorRunConfiguration - Could not parse %1. The QtS60 emulator run configuration %2 can not be started. + Could not parse %1. The Qt for Symbian emulator run configuration %2 can not be started. %1 konnte nicht ausgewertet werden. Die Qt S60-Emulator-Ausführungskonfiguration %2 kann nicht gestartet werden. @@ -12740,15 +12065,8 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Qt4ProjectManager::Internal::S60EmulatorRunConfigurationFactory - %1 in Emulator - %1 im Emulator - - - - Qt4ProjectManager::Internal::S60EmulatorRunConfigurationRunner - - Run in Emulator - Im Emulator ausführen + %1 in Symbian Emulator + %1 im Symbian-Emulator @@ -12797,7 +12115,7 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Debug on Device - + Auf Gerät Debuggen @@ -12978,12 +12296,12 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' Using Default Qt Version - + Es wird die Vorgabe-Qt-Version benutzt Using Qt Version "%1" - + Es wird die Qt-Version "%1" benutzt @@ -12995,6 +12313,16 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' New Configuration Name: Name der neuen Konfiguration: + + + %1 Debug + %1 Debug + + + + %1 Release + %1 Release + Qt4ProjectManager::Qt4Manager @@ -13130,12 +12458,12 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' QtScriptTools Module - + QtScriptTools-Modul Additional Qt Script components - + Zusätzliche Qt-Skript-Komponenten @@ -13190,12 +12518,12 @@ Bitte prüfen Sie, ob das Gerät verbunden ist und die Anwendung 'TRK' QtMultimedia Module - + QtMultimedia-Modul Classes for low-level multimedia functionality - + Klassen für Multimedia-Funktionalität @@ -13947,7 +13275,7 @@ Um es abzurufen, tippen Sie das Kürzel im Locator, gefolgt von einem Leerzeich Internal name - Interner Name + Interner Name @@ -14091,12 +13419,12 @@ Um es abzurufen, tippen Sie das Kürzel im Locator, gefolgt von einem Leerzeich "%1" hinzufügen - + Alt+S,Alt+A Alt+S,Alt+A - + Delete Löschen @@ -14131,12 +13459,12 @@ Um es abzurufen, tippen Sie das Kürzel im Locator, gefolgt von einem Leerzeich Diff für "%1" - + Alt+S,Alt+D Alt+S,Alt+D - + Commit All Files Alle Dateien abgeben @@ -14151,12 +13479,12 @@ Um es abzurufen, tippen Sie das Kürzel im Locator, gefolgt von einem Leerzeich "%1" abgeben - + Alt+S,Alt+C Alt+S,Alt+C - + Filelog Current File Filelog für Datei @@ -14364,7 +13692,7 @@ Um es abzurufen, tippen Sie das Kürzel im Locator, gefolgt von einem Leerzeich TextEditor::BaseTextEditorEditable - + Line: %1, Col: %2 Zeile: %1, Spalte: %2 @@ -14548,7 +13876,7 @@ Um es abzurufen, tippen Sie das Kürzel im Locator, gefolgt von einem Leerzeich TextEditor::FontSettingsPage - + Font & Colors Zeichensatz und Farben @@ -14835,17 +14163,27 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Ctrl+I - + + Meta + Meta + + + + Ctrl + Ctrl + + + + %1+E, R + %1+E, R + + + &Visualize Whitespace &Leerzeichen anzeigen - - Ctrl+E, Ctrl+V - Ctrl+E, Ctrl+V - - - + Clean Whitespace Leerzeichen bereinigen @@ -14855,12 +14193,7 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Text&umbruch aktivieren - - Ctrl+E, Ctrl+W - Ctrl+E, Ctrl+W - - - + (Un)Comment &Selection Auswahl aus&kommentieren @@ -14880,17 +14213,22 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Shift+Del - + &Rewrap Paragraph Abschnitt neu um&brechen - - Ctrl+E, R - Ctrl+E, R + + %1+E, %2+V + %1+E, %2+V - + + %1+E, %2+W + %1+E, %2+W + + + Cut &Line &Zeile ausschneiden @@ -14994,10 +14332,6 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Select Block Down Einen Block nach unten auswählen - - Ctrl+Shift+U - Ctrl+Shift+U - Move Line Up @@ -15099,7 +14433,7 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Unused Occurrence - + Nicht verwendet @@ -15159,7 +14493,7 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Visual Whitespace - + Leerzeichen darstellen @@ -15300,17 +14634,17 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Dialog - + Dialog TextLabel - + TextLabel CheckBox - + CheckBox @@ -15399,7 +14733,7 @@ Die folgenden Encodings scheinen der Datei zu entsprechen: Show Details - + Details anzeigen @@ -16067,7 +15401,7 @@ Qt Centre - Qt for S60 at Forum Nokia + Qt for Symbian at Forum Nokia Qt für S60 im Forum Nokia @@ -16133,4 +15467,64 @@ Qt Centre + + TrkOptions + + + No Symbian gdb executable specified. + Es wurde keine ausführbaren Datei des Symbian-Gdb angegeben. + + + + The Symbian gdb executable '%1' could not be found in the search path. + Die ausführbare Datei des Symbian-Gdb ('%1') konnte nicht im Suchpfad gefunden werden. + + + + Debugger::Internal::TrkOptionsPage + + + Symbian Trk + Symbian-Trk + + + + Debugger::Internal::AbstractGdbAdapter + + + The Gdb process could not be stopped: +%1 + Der Gdb-Prozess konnte nicht angehalten werden: +%1 + + + + Inferior process could not be stopped: +%1 + Zu debuggender Prozess konnte nicht angehalten werden: +%1 + + + + Inferior started. + Zu debuggender Prozess gestartet. + + + + Inferior running. + Zu debuggender Prozess läuft. + + + + Attached to stopped inferior. + + + + + Connecting to remote server failed: +%1 + Die Verbindung zum Server konnte nicht hergestellt werden: +%1 + + diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp index d95982b881c..26a2b3a961a 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.cpp +++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp @@ -51,6 +51,7 @@ int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index) const SimpleToken &tok = tk[index - 1]; switch (tok.kind()) { + case T_COMMA: case T_LPAREN: case T_LBRACKET: case T_LBRACE: diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 0b2fd4bba26..e04ee2a1b80 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -130,6 +130,46 @@ QList LookupContext::resolveQualifiedNameId(QualifiedNameId *q, const QList &visibleScopes, ResolveMode mode) const { + QList candidates; + + if (true || mode & ResolveClass) { + for (int i = 0; i < visibleScopes.size(); ++i) { + Scope *scope = visibleScopes.at(i); + + for (Symbol *symbol = scope->lookat(q); symbol; symbol = symbol->next()) { + if (! symbol->name()) + continue; + else if (! symbol->isClass()) + continue; + + QualifiedNameId *qq = symbol->name()->asQualifiedNameId(); + + if (! qq) + continue; + else if (! maybeValidSymbol(symbol, mode, candidates)) + continue; + + if (! q->unqualifiedNameId()->isEqualTo(qq->unqualifiedNameId())) + continue; + + else if (qq->nameCount() == q->nameCount()) { + unsigned j = 0; + + for (; j < q->nameCount(); ++j) { + Name *classOrNamespaceName1 = q->nameAt(j); + Name *classOrNamespaceName2 = qq->nameAt(j); + + if (! classOrNamespaceName1->isEqualTo(classOrNamespaceName2)) + break; + } + + if (j == q->nameCount()) + candidates.append(symbol); + } + } + } + } + QList scopes; if (q->nameCount() == 1) @@ -149,7 +189,9 @@ QList LookupContext::resolveQualifiedNameId(QualifiedNameId *q, } } - return resolve(q->unqualifiedNameId(), expanded, mode); + candidates += resolve(q->unqualifiedNameId(), expanded, mode); + + return candidates; } QList LookupContext::resolveOperatorNameId(OperatorNameId *opId, @@ -198,13 +240,11 @@ QList LookupContext::resolve(Name *name, const QList &visible else if (! maybeValidSymbol(symbol, mode, candidates)) continue; // skip it, we're not looking for this kind of symbols - else if (Identifier *symbolId = symbol->identifier()) { if (! symbolId->isEqualTo(id)) continue; // skip it, the symbol's id is not compatible with this lookup. } - if (QualifiedNameId *q = symbol->name()->asQualifiedNameId()) { if (name->isDestructorNameId() != q->unqualifiedNameId()->isDestructorNameId()) diff --git a/src/plugins/coreplugin/generalsettings.ui b/src/plugins/coreplugin/generalsettings.ui index dd680aa10cf..b33497825c7 100644 --- a/src/plugins/coreplugin/generalsettings.ui +++ b/src/plugins/coreplugin/generalsettings.ui @@ -59,7 +59,7 @@ 0 - + false @@ -163,6 +163,9 @@ When files are externally modified: + + true + @@ -193,19 +196,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index f53b7aae759..a9f9ea95882 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -1751,6 +1752,13 @@ const char *CPPEditorEditable::kind() const return CppEditor::Constants::CPPEDITOR_KIND; } +bool CPPEditorEditable::open(const QString & fileName) +{ + bool b = TextEditor::BaseTextEditorEditable::open(fileName); + editor()->setMimeType(Core::ICore::instance()->mimeDatabase()->findByFile(QFileInfo(fileName)).type()); + return b; +} + void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs) { TextEditor::BaseTextEditor::setFontSettings(fs); diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 699cb9e49fa..68159ee9100 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -164,6 +164,7 @@ public: const char *kind() const; bool isTemporary() const { return false; } + virtual bool open(const QString & fileName); private: QList m_context; diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp index 3372fd336d1..f27e82bdb96 100644 --- a/src/plugins/cppeditor/cppplugin.cpp +++ b/src/plugins/cppeditor/cppplugin.cpp @@ -97,7 +97,6 @@ Core::IEditor *CppEditorFactory::createEditor(QWidget *parent) { CPPEditor *editor = new CPPEditor(parent); editor->setRevisionsVisible(true); - editor->setMimeType(CppEditor::Constants::CPP_SOURCE_MIMETYPE); m_owner->initializeEditor(editor); return editor->editableInterface(); } diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 03397a655ad..3c11479a025 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -28,7 +28,7 @@ **************************************************************************/ #include "cppfindreferences.h" -#include "cppmodelmanager.h" +#include "cppmodelmanagerinterface.h" #include "cpptoolsconstants.h" #include @@ -166,12 +166,32 @@ protected: return false; } - bool isDeclSymbol(Symbol *symbol) const + bool checkScope(Symbol *symbol, Symbol *otherSymbol) const { - if (! symbol) + if (! (symbol && otherSymbol)) return false; - else if (symbol == _declSymbol) { + else if (symbol->scope() == otherSymbol->scope()) + return true; + + else if (symbol->name() && otherSymbol->name()) { + + if (! symbol->name()->isEqualTo(otherSymbol->name())) + return false; + + } else if (symbol->name() != otherSymbol->name()) { + return false; + } + + return checkScope(symbol->enclosingSymbol(), otherSymbol->enclosingSymbol()); + } + + bool isDeclSymbol(Symbol *symbol) const + { + if (! symbol) { + return false; + + } else if (symbol == _declSymbol) { return true; } else if (symbol->line() == _declSymbol->line() && symbol->column() == _declSymbol->column()) { @@ -180,11 +200,11 @@ protected: } else if (symbol->isForwardClassDeclaration() && (_declSymbol->isClass() || _declSymbol->isForwardClassDeclaration())) { - return true; + return checkScope(symbol, _declSymbol); } else if (_declSymbol->isForwardClassDeclaration() && (symbol->isClass() || symbol->isForwardClassDeclaration())) { - return true; + return checkScope(symbol, _declSymbol); } return false; @@ -349,6 +369,20 @@ protected: return false; } + virtual bool visit(EnumeratorAST *ast) + { + Identifier *id = identifier(ast->identifier_token); + if (id == _id) { + LookupContext context = currentContext(ast); + const QList candidates = context.resolve(control()->nameId(id)); + reportResult(ast->identifier_token, candidates); + } + + accept(ast->expression); + + return false; + } + virtual bool visit(SimpleNameAST *ast) { Identifier *id = identifier(ast->identifier_token); @@ -452,7 +486,7 @@ private: } // end of anonymous namespace -CppFindReferences::CppFindReferences(CppModelManager *modelManager) +CppFindReferences::CppFindReferences(CppTools::CppModelManagerInterface *modelManager) : _modelManager(modelManager), _resultWindow(ExtensionSystem::PluginManager::instance()->getObject()) { @@ -614,7 +648,7 @@ void CppFindReferences::findAll_helper(Symbol *symbol) _resultWindow->popup(true); const Snapshot snapshot = _modelManager->snapshot(); - const QMap wl = _modelManager->buildWorkingCopyList(); + const QMap wl = _modelManager->workingCopy(); Core::ProgressManager *progressManager = Core::ICore::instance()->progressManager(); diff --git a/src/plugins/cpptools/cppfindreferences.h b/src/plugins/cpptools/cppfindreferences.h index 4b4a5a9b04b..cbddf8fb5c3 100644 --- a/src/plugins/cpptools/cppfindreferences.h +++ b/src/plugins/cpptools/cppfindreferences.h @@ -43,16 +43,16 @@ namespace Find { } // end of namespace Find namespace CppTools { -namespace Internal { +class CppModelManagerInterface; -class CppModelManager; +namespace Internal { class CppFindReferences: public QObject { Q_OBJECT public: - CppFindReferences(CppModelManager *modelManager); + CppFindReferences(CppModelManagerInterface *modelManager); virtual ~CppFindReferences(); QList references(CPlusPlus::Symbol *symbol, @@ -76,7 +76,7 @@ private: void findAll_helper(CPlusPlus::Symbol *symbol); private: - QPointer _modelManager; + QPointer _modelManager; Find::SearchResultWindow *_resultWindow; QFutureWatcher m_watcher; }; diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index d60cd1752ff..1d886920566 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -727,7 +727,7 @@ QByteArray CppModelManager::internalDefinedMacros() const return macros; } -void CppModelManager::setIncludesInPaths(const QMap includesInPaths) +void CppModelManager::setIncludesInPaths(const QMap &includesInPaths) { QMutexLocker locker(&mutex); QMapIterator i(includesInPaths); @@ -793,6 +793,11 @@ QMap CppModelManager::buildWorkingCopyList() return workingCopy; } +QMap CppModelManager::workingCopy() const +{ + return const_cast(this)->buildWorkingCopyList(); +} + void CppModelManager::updateSourceFiles(const QStringList &sourceFiles) { (void) refreshSourceFiles(sourceFiles); } @@ -1177,7 +1182,7 @@ void CppModelManager::updateIncludesInPaths(QFutureInterface &future, future.waitForResume(); if (future.isCanceled()) - break; + return; const QString path = paths.takeFirst(); diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 9aa3a800b2c..4222ccab6be 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -73,6 +73,7 @@ public: virtual ~CppModelManager(); virtual void updateSourceFiles(const QStringList &sourceFiles); + virtual QMap workingCopy() const; virtual QList projectInfos() const; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const; @@ -92,8 +93,6 @@ public: CppEditorSupport *editorSupport(TextEditor::ITextEditor *editor) const { return m_editorSupport.value(editor); } - QMap buildWorkingCopyList(); - void emitDocumentUpdated(CPlusPlus::Document::Ptr doc); void stopEditorSelectionsUpdate() @@ -132,6 +131,8 @@ private Q_SLOTS: void updateEditorSelections(); private: + QMap buildWorkingCopyList(); + QStringList projectFiles() { ensureUpdated(); @@ -162,7 +163,7 @@ private: QStringList internalFrameworkPaths() const; QByteArray internalDefinedMacros() const; - void setIncludesInPaths(const QMap includesInPaths); + void setIncludesInPaths(const QMap &includesInPaths); static void updateIncludesInPaths(QFutureInterface &future, CppModelManager *manager, diff --git a/src/plugins/cpptools/cppmodelmanagerinterface.h b/src/plugins/cpptools/cppmodelmanagerinterface.h index 58b04d4bf57..9c6f0fb4432 100644 --- a/src/plugins/cpptools/cppmodelmanagerinterface.h +++ b/src/plugins/cpptools/cppmodelmanagerinterface.h @@ -86,6 +86,7 @@ public: virtual void GC() = 0; virtual void updateSourceFiles(const QStringList &sourceFiles) = 0; + virtual QMap workingCopy() const = 0; virtual CPlusPlus::Snapshot snapshot() const = 0; virtual QList projectInfos() const = 0; diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 1086adf8e55..181ed4e0603 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -37,6 +37,7 @@ #include "cdbassembler.h" #include "cdboptionspage.h" #include "cdboptions.h" +#include "cdbexceptionutils.h" #include "debuggeragents.h" #include "debuggeractions.h" @@ -305,12 +306,14 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *manager, m_dumper(new CdbDumperHelper(manager, &m_cif)), m_currentThreadId(-1), m_eventThreadId(-1), - m_interrupted(false), + m_interruptArticifialThreadId(-1), + m_interrupted(false), m_watchTimer(-1), m_debugEventCallBack(engine), m_engine(engine), m_currentStackTrace(0), m_firstActivatedFrame(true), + m_inferiorStartupComplete(false), m_mode(AttachCore) { } @@ -447,7 +450,7 @@ void CdbDebugEnginePrivate::clearForRun() qDebug() << Q_FUNC_INFO; m_breakEventMode = BreakEventHandle; - m_eventThreadId = -1; + m_eventThreadId = m_interruptArticifialThreadId = -1; m_interrupted = false; cleanStackTrace(); } @@ -619,6 +622,8 @@ void CdbDebugEnginePrivate::checkVersion() void CdbDebugEngine::startDebugger(const QSharedPointer &sp) { + if (debugCDBExecution) + qDebug() << "startDebugger" << *sp; setState(AdapterStarting, Q_FUNC_INFO, __LINE__); m_d->checkVersion(); if (m_d->m_hDebuggeeProcess) { @@ -627,6 +632,7 @@ void CdbDebugEngine::startDebugger(const QSharedPointer emit startFailed(); } m_d->clearDisplay(); + m_d->m_inferiorStartupComplete = false; setState(AdapterStarted, Q_FUNC_INFO, __LINE__); setState(InferiorPreparing, Q_FUNC_INFO, __LINE__); @@ -699,10 +705,11 @@ bool CdbDebugEngine::startAttachDebugger(qint64 pid, DebuggerStartMode sm, QStri { // Need to attrach invasively, otherwise, no notification signals // for for CreateProcess/ExitProcess occur. - const ULONG flags = DEBUG_ATTACH_INVASIVE_RESUME_PROCESS; + // As of version 6.11, the initial breakpoint suppression has no effect (see notifyException). + const ULONG flags = DEBUG_ATTACH_INVASIVE_RESUME_PROCESS|DEBUG_ATTACH_INVASIVE_NO_INITIAL_BREAK; const HRESULT hr = m_d->m_cif.debugClient->AttachProcess(NULL, pid, flags); if (debugCDB) - qDebug() << "Attaching to " << pid << " returns " << hr << executionStatusString(m_d->m_cif.debugControl); + qDebug() << "Attaching to " << pid << " using flags" << flags << " returns " << hr << executionStatusString(m_d->m_cif.debugControl); if (FAILED(hr)) { *errorMessage = tr("Attaching to a process failed for process id %1: %2").arg(pid).arg(msgDebugEngineComResult(hr)); return false; @@ -771,7 +778,7 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString * } void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 initialThreadHandle) -{ +{ m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__); setDebuggeeHandles(reinterpret_cast(processHandle), reinterpret_cast(initialThreadHandle)); ULONG currentThreadId; @@ -782,8 +789,11 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6 } // Clear any saved breakpoints and set initial breakpoints m_engine->executeDebuggerCommand(QLatin1String("bc")); - if (manager()->breakHandler()->hasPendingBreakpoints()) + if (manager()->breakHandler()->hasPendingBreakpoints()) { + if (debugCDBExecution) + qDebug() << "processCreatedAttached: Syncing breakpoints"; m_engine->attemptBreakpointSynchronization(); + } // Attaching to crashed: This handshake (signalling an event) is required for // the exception to be delivered to the debugger if (m_mode == AttachCrashedExternal) { @@ -796,8 +806,8 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6 } } m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__); - if (debugCDB) - qDebug() << Q_FUNC_INFO << '\n' << executionStatusString(m_cif.debugControl); + if (debugCDBExecution) + qDebug() << "m_currentThreadId << " evt " << m_d->m_eventThreadId; + if (debugCDBExecution) + qDebug() << ">step" << executionStatus << "curr " << m_d->m_currentThreadId << " evt " << m_d->m_eventThreadId; // State of reverse stepping as of 10/2009 (Debugging tools 6.11@404): // The constants exist, but invoking the calls leads to E_NOINTERFACE. @@ -1029,6 +1039,12 @@ bool CdbDebugEngine::step(unsigned long executionStatus) return false; } + // Do not step the artifical thread created to interrupt the debuggee. + if (m_d->m_interrupted && m_d->m_currentThreadId == m_d->m_interruptArticifialThreadId) { + warning(tr("Thread %1 cannot be stepped.").arg(m_d->m_currentThreadId)); + return false; + } + // SetExecutionStatus() continues the thread that triggered the // stop event (~# p). This can be confusing if the user is looking // at the stack trace of another thread and wants to step that one. If that @@ -1067,6 +1083,8 @@ bool CdbDebugEngine::step(unsigned long executionStatus) } else { setState(InferiorStopped, Q_FUNC_INFO, __LINE__); } + if (debugCDBExecution) + qDebug() << "stackHandler(); @@ -1142,8 +1160,8 @@ void CdbDebugEngine::continueInferior() // Continue process without notifications bool CdbDebugEnginePrivate::continueInferiorProcess(QString *errorMessagePtr /* = 0 */) { - if (debugCDB) - qDebug() << Q_FUNC_INFO; + if (debugCDBExecution) + qDebug() << "continueInferiorProcess"; const HRESULT hr = m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_GO); if (FAILED(hr)) { const QString errorMessage = msgComFailed("SetExecutionStatus", hr); @@ -1198,11 +1216,12 @@ bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage) bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage) { + // Interrupt the interferior process without notifications - if (debugCDB) { + if (debugCDBExecution) { ULONG executionStatus; getExecutionStatus(m_cif.debugControl, &executionStatus, errorMessage); - qDebug() << Q_FUNC_INFO << "\n ex=" << executionStatus; + qDebug() << "interruptInterferiorProcess ex=" << executionStatus; } if (DebugBreakProcess(m_hDebuggeeProcess)) { @@ -1218,6 +1237,7 @@ bool CdbDebugEnginePrivate::interruptInterferiorProcess(QString *errorMessage) arg(getInterruptTimeOutSecs(m_cif.debugControl)).arg(msgComFailed("SetInterrupt", hr)); return false; } + m_interrupted = true; #endif return true; } @@ -1646,10 +1666,27 @@ void CdbDebugEngine::warning(const QString &w) qWarning("%s\n", qPrintable(w)); } -void CdbDebugEnginePrivate::notifyCrashed() +void CdbDebugEnginePrivate::notifyException(long code, bool fatal) { + if (debugCDBExecution) + qDebug() << "notifyException code" << code << " fatal=" << fatal; + // Suppress the initial breakpoint that occurs when + // attaching (If a breakpoint is encountered before startup + // is complete). + switch (code) { + case winExceptionStartupCompleteTrap: + m_inferiorStartupComplete = true; + break; + case EXCEPTION_BREAKPOINT: + if (!m_inferiorStartupComplete && m_breakEventMode == BreakEventHandle) { + manager()->showDebuggerOutput(LogMisc, CdbDebugEngine::tr("Ignoring initial breakpoint...")); + m_breakEventMode = BreakEventIgnoreOnce; + } + break; + } // Cannot go over crash point to execute calls. - m_dumper->disable(); + if (fatal) + m_dumper->disable(); } static int threadIndexById(const ThreadsHandler *threadsHandler, int id) @@ -1664,10 +1701,10 @@ static int threadIndexById(const ThreadsHandler *threadsHandler, int id) void CdbDebugEnginePrivate::handleDebugEvent() { - if (debugCDB) - qDebug() << Q_FUNC_INFO << '\n' << m_hDebuggeeProcess << m_breakEventMode - << executionStatusString(m_cif.debugControl); - + if (debugCDBExecution) + qDebug() << "handleDebugEvent mode " << m_breakEventMode + << executionStatusString(m_cif.debugControl) << " interrupt" << m_interrupted + << " startupcomplete" << m_inferiorStartupComplete; // restore mode and do special handling const HandleBreakEventMode mode = m_breakEventMode; m_breakEventMode = BreakEventHandle; @@ -1679,9 +1716,27 @@ void CdbDebugEnginePrivate::handleDebugEvent() if (m_engine->state() != InferiorStopping) m_engine->setState(InferiorStopping, Q_FUNC_INFO, __LINE__); m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__); - m_eventThreadId = m_currentThreadId = updateThreadList(); - manager()->showDebuggerOutput(LogMisc, CdbDebugEngine::tr("Stopped, current thread: %1").arg(m_currentThreadId)); + m_eventThreadId = updateThreadList(); + m_interruptArticifialThreadId = m_interrupted ? m_eventThreadId : -1; + // Get thread to stop and its index. If avoidable, do not use + // the artifical thread that is created when interrupting, + // use the oldest thread 0 instead. ThreadsHandler *threadsHandler = manager()->threadsHandler(); + m_currentThreadId = m_interrupted ? 0 : m_eventThreadId; + int currentThreadIndex = -1; + m_currentThreadId = -1; + if (m_interrupted) { + m_currentThreadId = 0; + currentThreadIndex = threadIndexById(threadsHandler, m_currentThreadId); + } + if (!m_interrupted || currentThreadIndex == -1) { + m_currentThreadId = m_eventThreadId; + currentThreadIndex = threadIndexById(threadsHandler, m_currentThreadId); + } + const QString msg = m_interrupted ? + CdbDebugEngine::tr("Interrupted in thread %1, current thread: %2").arg(m_interruptArticifialThreadId).arg(m_currentThreadId) : + CdbDebugEngine::tr("Stopped, current thread: %1").arg(m_currentThreadId); + manager()->showDebuggerOutput(LogMisc, msg); const int threadIndex = threadIndexById(threadsHandler, m_currentThreadId); if (threadIndex != -1) threadsHandler->setCurrentThread(threadIndex); @@ -1690,8 +1745,10 @@ void CdbDebugEnginePrivate::handleDebugEvent() break; case BreakEventIgnoreOnce: m_engine->startWatchTimer(); + m_interrupted = false; break; case BreakEventSyncBreakPoints: { + m_interrupted = false; // Temp stop to sync breakpoints QString errorMessage; attemptBreakpointSynchronization(&errorMessage); @@ -1764,9 +1821,12 @@ static inline unsigned long dumperThreadId(const QList &frames, return CdbDumperHelper::InvalidDumperCallThread; const int waitCheckDepth = qMin(frames.size(), 5); static const QString waitForPrefix = QLatin1String(CdbStackTraceContext::winFuncWaitForPrefix); - for (int f = 0; f < waitCheckDepth; f++) - if (frames.at(f).function.startsWith(waitForPrefix)) + static const QString msgWaitForPrefix = QLatin1String(CdbStackTraceContext::winFuncMsgWaitForPrefix); + for (int f = 0; f < waitCheckDepth; f++) { + const QString &function = frames.at(f).function; + if (function.startsWith(waitForPrefix) || function.startsWith(msgWaitForPrefix)) return CdbDumperHelper::InvalidDumperCallThread; + } return currentThread; } @@ -1812,7 +1872,7 @@ void CdbDebugEnginePrivate::updateStackTrace() } // Set up dumper with a thread (or invalid) const unsigned long dumperThread = dumperThreadId(stackFrames, m_currentThreadId); - if (debugCDB) + if (debugCDBExecution) qDebug() << "updateStackTrace() current: " << m_currentThreadId << " dumper=" << dumperThread; m_dumper->setDumperCallThread(dumperThread); // Display frames @@ -1824,6 +1884,10 @@ void CdbDebugEnginePrivate::updateStackTrace() if (m_dumper->isEnabled() && m_dumper->state() != CdbDumperHelper::Initialized) QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); m_engine->activateFrame(current); + } else { + // Clean out variables + manager()->watchHandler()->beginCycle(); + manager()->watchHandler()->endCycle(); } manager()->watchHandler()->updateWatchers(); } diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h index b0a01d37896..e52ddadef5c 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine_p.h +++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h @@ -135,7 +135,7 @@ struct CdbDebugEnginePrivate bool executeContinueCommand(const QString &command); bool attemptBreakpointSynchronization(QString *errorMessage); - void notifyCrashed(); + void notifyException(long code, bool fatal); enum EndInferiorAction { DetachInferior, TerminateInferior }; bool endInferior(EndInferiorAction a, QString *errorMessage); @@ -157,9 +157,10 @@ struct CdbDebugEnginePrivate const QSharedPointer m_options; HANDLE m_hDebuggeeProcess; HANDLE m_hDebuggeeThread; - bool m_interrupted; + bool m_interrupted; int m_currentThreadId; int m_eventThreadId; + int m_interruptArticifialThreadId; HandleBreakEventMode m_breakEventMode; int m_watchTimer; @@ -175,6 +176,7 @@ struct CdbDebugEnginePrivate EditorToolTipCache m_editorToolTipCache; bool m_firstActivatedFrame; + bool m_inferiorStartupComplete; DebuggerStartMode m_mode; Utils::ConsoleProcess m_consoleStubProc; @@ -192,6 +194,7 @@ QString msgDebugEngineComResult(HRESULT hr); QString msgComFailed(const char *func, HRESULT hr); enum { debugCDB = 0 }; +enum { debugCDBExecution = 0 }; enum { debugCDBWatchHandling = 0 }; } // namespace Internal diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp index 21f867ede22..26c24b2058b 100644 --- a/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp +++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.cpp @@ -35,6 +35,7 @@ #include #include +#include namespace Debugger { namespace Internal { @@ -249,8 +250,7 @@ STDMETHODIMP CdbDebugEventCallback::Exception( qDebug() << Q_FUNC_INFO << "\nex=" << Exception->ExceptionCode << " fatal=" << fatal << msg; m_pEngine->manager()->showApplicationOutput(msg); m_pEngine->manager()->showDebuggerOutput(LogMisc, msg); - if (fatal) - m_pEngine->m_d->notifyCrashed(); + m_pEngine->m_d->notifyException(Exception->ExceptionCode, fatal); return S_OK; } @@ -373,8 +373,11 @@ STDMETHODIMP CdbDebugEventCallback::SystemError( } // -----------ExceptionLoggerEventCallback -CdbExceptionLoggerEventCallback::CdbExceptionLoggerEventCallback(int logChannel, DebuggerManager *manager) : +CdbExceptionLoggerEventCallback::CdbExceptionLoggerEventCallback(int logChannel, + bool skipNonFatalExceptions, + DebuggerManager *manager) : m_logChannel(logChannel), + m_skipNonFatalExceptions(skipNonFatalExceptions), m_manager(manager) { } @@ -391,15 +394,18 @@ STDMETHODIMP CdbExceptionLoggerEventCallback::Exception( __in ULONG /* FirstChance */ ) { - m_exceptionCodes.push_back(Exception->ExceptionCode); - m_exceptionMessages.push_back(QString()); - { - QTextStream str(&m_exceptionMessages.back()); - formatException(Exception, str); + const bool recordException = !m_skipNonFatalExceptions || isFatalException(Exception->ExceptionCode); + QString message; + formatException(Exception, QTextStream(&message)); + if (recordException) { + m_exceptionCodes.push_back(Exception->ExceptionCode); + m_exceptionMessages.push_back(message); } if (debugCDB) - qDebug() << Q_FUNC_INFO << '\n' << m_exceptionMessages.back(); - m_manager->showDebuggerOutput(m_logChannel, m_exceptionMessages.back()); + qDebug() << Q_FUNC_INFO << '\n' << message; + m_manager->showDebuggerOutput(m_logChannel, message); + if (recordException) + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); return S_OK; } diff --git a/src/plugins/debugger/cdb/cdbdebugeventcallback.h b/src/plugins/debugger/cdb/cdbdebugeventcallback.h index b9de88e1745..4250cd5b24c 100644 --- a/src/plugins/debugger/cdb/cdbdebugeventcallback.h +++ b/src/plugins/debugger/cdb/cdbdebugeventcallback.h @@ -242,7 +242,9 @@ private: class CdbExceptionLoggerEventCallback : public CdbDebugEventCallbackBase { public: - CdbExceptionLoggerEventCallback(int logChannel, DebuggerManager *access); + CdbExceptionLoggerEventCallback(int logChannel, + bool skipNonFatalExceptions, + DebuggerManager *access); STDMETHOD(GetInterestMask)( THIS_ @@ -261,6 +263,7 @@ public: private: const int m_logChannel; + const bool m_skipNonFatalExceptions; DebuggerManager *m_manager; QList m_exceptionCodes; QStringList m_exceptionMessages; diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.cpp b/src/plugins/debugger/cdb/cdbdumperhelper.cpp index a188d2c1f2b..753c54be845 100644 --- a/src/plugins/debugger/cdb/cdbdumperhelper.cpp +++ b/src/plugins/debugger/cdb/cdbdumperhelper.cpp @@ -144,13 +144,14 @@ static bool createDebuggeeAscIIString(CdbComInterfaces *cif, // make sense for Qt apps. static bool debuggeeLoadLibrary(DebuggerManager *manager, CdbComInterfaces *cif, + unsigned long threadId, const QString &moduleName, QString *errorMessage) { if (loadDebug > 1) qDebug() << Q_FUNC_INFO << moduleName; - // Try to ignore the breakpoints - CdbExceptionLoggerEventCallback exLogger(LogWarning, manager); + // Try to ignore the breakpoints, skip stray startup-complete trap exceptions + CdbExceptionLoggerEventCallback exLogger(LogWarning, true, manager); EventCallbackRedirector eventRedir(cif->debugClient, &exLogger); // Make a call to LoadLibraryA. First, reserve memory in debugger // and copy name over. @@ -178,7 +179,9 @@ static bool debuggeeLoadLibrary(DebuggerManager *manager, if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, callCmd, errorMessage)) return false; // Execute current thread. This will hit a breakpoint. - if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, QLatin1String("~. g"), errorMessage)) + QString goCmd; + QTextStream(&goCmd) << '~' << threadId << " g"; + if (!CdbDebugEnginePrivate::executeDebuggerCommand(cif->debugControl, goCmd, errorMessage)) return false; const HRESULT hr = cif->debugControl->WaitForEvent(0, waitTimeOutMS); if (FAILED(hr)) { @@ -329,7 +332,7 @@ CdbDumperHelper::CallLoadResult CdbDumperHelper::initCallLoad(QString *errorMess if (modules.filter(QLatin1String(qtCoreModuleNameC), Qt::CaseInsensitive).isEmpty()) return CallLoadNoQtApp; // Try to load - if (!debuggeeLoadLibrary(m_manager, m_cif, m_library, errorMessage)) + if (!debuggeeLoadLibrary(m_manager, m_cif, m_dumperCallThread, m_library, errorMessage)) return CallLoadError; return CallLoadOk; } @@ -495,7 +498,8 @@ CdbDumperHelper::CallResult bool ignoreAccessViolation, QString *errorMessage) { *outDataPtr = 0; - CdbExceptionLoggerEventCallback exLogger(LogWarning, m_manager); + // Skip stray startup-complete trap exceptions. + CdbExceptionLoggerEventCallback exLogger(LogWarning, true, m_manager); EventCallbackRedirector eventRedir(m_cif->debugClient, &exLogger); // write input buffer if (!inBuffer.isEmpty()) { @@ -576,7 +580,7 @@ static inline QString msgNotHandled(const QString &type) CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool dumpChildren, QList *result, QString *errorMessage) { - if (dumpDebug) + if (dumpDebug || debugCDBExecution) qDebug() << ">dumpType() thread: " << m_dumperCallThread << " state: " << m_state << wd.type << QTime::currentTime().toString(); const CdbDumperHelper::DumpResult rc = dumpTypeI(wd, dumpChildren, result, errorMessage); if (dumpDebug) diff --git a/src/plugins/debugger/cdb/cdbexceptionutils.cpp b/src/plugins/debugger/cdb/cdbexceptionutils.cpp index 4975b697243..2c9b49d413e 100644 --- a/src/plugins/debugger/cdb/cdbexceptionutils.cpp +++ b/src/plugins/debugger/cdb/cdbexceptionutils.cpp @@ -38,15 +38,6 @@ enum { debugExc = 0 }; -// Special exception codes. -enum { cppExceptionCode = 0xe06d7363, startupCompleteTrap = 0x406d1388, - rpcServerUnavailableExceptionCode = 0x6ba, - dllNotFoundExceptionCode = 0xc0000135, - dllInitFailed = 0xc0000142, - missingSystemFile = 0xc0000143, - appInitFailed = 0xc0000143 - }; - namespace Debugger { namespace Internal { @@ -167,19 +158,19 @@ void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str) str << "\nException at 0x" << e->ExceptionAddress << ", code: 0x" << e->ExceptionCode << ": "; switch (e->ExceptionCode) { - case cppExceptionCode: + case winExceptionCppException: str << "C++ exception"; break; - case startupCompleteTrap: + case winExceptionStartupCompleteTrap: str << "Startup complete"; break; - case dllNotFoundExceptionCode: + case winExceptionDllNotFound: str << "DLL not found"; break; - case dllInitFailed: + case winExceptionDllInitFailed: str << "DLL failed to initialize"; break; - case missingSystemFile: + case winExceptionMissingSystemFile: str << "System file is missing"; break; case EXCEPTION_ACCESS_VIOLATION: { @@ -260,7 +251,7 @@ void formatException(const EXCEPTION_RECORD64 *e, QTextStream &str) { formatException(e, str); - if (e->ExceptionCode == cppExceptionCode) { + if (e->ExceptionCode == winExceptionCppException) { QString errorMessage; ULONG currentThreadId = 0; dumper->comInterfaces()->debugSystemObjects->GetCurrentThreadId(¤tThreadId); @@ -278,10 +269,10 @@ bool isFatalException(LONG code) switch (code) { case EXCEPTION_BREAKPOINT: case EXCEPTION_SINGLE_STEP: - case startupCompleteTrap: // Mysterious exception at start of application - case rpcServerUnavailableExceptionCode: - case dllNotFoundExceptionCode: - case cppExceptionCode: + case winExceptionStartupCompleteTrap: // Mysterious exception at start of application + case winExceptionRpcServerUnavailable: + case winExceptionDllNotFound: + case winExceptionCppException: return false; default: break; diff --git a/src/plugins/debugger/cdb/cdbexceptionutils.h b/src/plugins/debugger/cdb/cdbexceptionutils.h index 98af74706fa..b54447580f3 100644 --- a/src/plugins/debugger/cdb/cdbexceptionutils.h +++ b/src/plugins/debugger/cdb/cdbexceptionutils.h @@ -42,6 +42,17 @@ QT_END_NAMESPACE namespace Debugger { namespace Internal { +// Special exception codes. +enum { winExceptionCppException = 0xe06d7363, + winExceptionStartupCompleteTrap = 0x406d1388, + winExceptionRpcServerUnavailable = 0x6ba, + winExceptionDllNotFound = 0xc0000135, + winExceptionDllInitFailed = 0xc0000142, + winExceptionMissingSystemFile = 0xc0000143, + winExceptionAppInitFailed = 0xc0000143 +}; + + class CdbDumperHelper; // Utility class that blocks out exception handling (breaking) diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp index 93ab11d75ef..d97a968768c 100644 --- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp +++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp @@ -134,7 +134,7 @@ static inline bool fixDumperType(WatchData *wd, const WatchData *source = 0) const bool missing = wd->isTypeNeeded() || wd->type.isEmpty(); if (missing) { static const QString unknownType = QCoreApplication::translate("CdbStackFrameContext", ""); - wd->setType(source ? source->type : unknownType); + wd->setType(source ? source->type : unknownType, false); } return missing; } diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp index 605eeb61dbf..0a338f9fdcc 100644 --- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp +++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp @@ -43,6 +43,7 @@ namespace Internal { const char *CdbStackTraceContext::winFuncFastSystemCallRet = "ntdll!KiFastSystemCallRet"; const char *CdbStackTraceContext::winFuncDebugBreakPoint = "ntdll!DbgBreakPoint"; const char *CdbStackTraceContext::winFuncWaitForPrefix = "kernel32!WaitFor"; +const char *CdbStackTraceContext::winFuncMsgWaitForPrefix = "kernel32!MsgWaitForMultipleObjects"; CdbStackTraceContext::CdbStackTraceContext(const QSharedPointer &dumper) : m_dumper(dumper), diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.h b/src/plugins/debugger/cdb/cdbstacktracecontext.h index 3b0e2061fc8..ac9cb030b06 100644 --- a/src/plugins/debugger/cdb/cdbstacktracecontext.h +++ b/src/plugins/debugger/cdb/cdbstacktracecontext.h @@ -67,6 +67,8 @@ public: static const char *winFuncFastSystemCallRet; // WaitFor... static const char *winFuncWaitForPrefix; + static const char *winFuncMsgWaitForPrefix; + // Dummy function used for interrupting a debuggee static const char *winFuncDebugBreakPoint; diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index ea3924ddd26..166902112eb 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1406,10 +1406,14 @@ void DebuggerManager::modulesDockToggled(bool on) void DebuggerManager::showDebuggerOutput(int channel, const QString &msg) { - if (d->m_outputWindow) + if (d->m_outputWindow) { emit emitShowOutput(channel, msg); - else + if (channel == LogError) + ensureLogVisible(); + } else { qDebug() << "OUTPUT: " << channel << msg; + + } } void DebuggerManager::showDebuggerInput(int channel, const QString &msg) @@ -1761,6 +1765,13 @@ bool DebuggerManager::checkDebugConfiguration(int toolChain, return success; } +void DebuggerManager::ensureLogVisible() +{ + QAction *action = d->m_outputDock->toggleViewAction(); + if (!action->isChecked()) + action->trigger(); +} + QDebug operator<<(QDebug d, DebuggerState state) { return d << stateName(state) << '(' << int(state) << ')'; diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index ddd692b4316..2d84c9383cc 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -234,6 +234,8 @@ public slots: public slots: // FIXME void showDebuggerOutput(const QString &msg) { showDebuggerOutput(LogDebug, msg); } + void ensureLogVisible(); + //private slots: // FIXME void showDebuggerOutput(int channel, const QString &msg); void showDebuggerInput(int channel, const QString &msg); diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.cpp b/src/plugins/debugger/gdb/abstractgdbadapter.cpp index 1a523f8d1ca..52c76107606 100644 --- a/src/plugins/debugger/gdb/abstractgdbadapter.cpp +++ b/src/plugins/debugger/gdb/abstractgdbadapter.cpp @@ -83,5 +83,35 @@ bool AbstractGdbAdapter::isTrkAdapter() const return false; } +QString AbstractGdbAdapter::msgGdbStopFailed(const QString &why) +{ + return tr("The Gdb process could not be stopped:\n%1").arg(why); +} + +QString AbstractGdbAdapter::msgInferiorStopFailed(const QString &why) +{ + return tr("Inferior process could not be stopped:\n%1").arg(why); +} + +QString AbstractGdbAdapter::msgInferiorStarted() +{ + return tr("Inferior started."); +} + +QString AbstractGdbAdapter::msgInferiorRunning() +{ + return tr("Inferior running."); +} + +QString AbstractGdbAdapter::msgAttachedToStoppedInferior() +{ + return tr("Attached to stopped inferior."); +} + +QString AbstractGdbAdapter::msgConnectRemoteServerFailed(const QString &why) +{ + return tr("Connecting to remote server failed:\n%1").arg(why); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h index cafc03d491d..ecb52f9316e 100644 --- a/src/plugins/debugger/gdb/abstractgdbadapter.h +++ b/src/plugins/debugger/gdb/abstractgdbadapter.h @@ -93,6 +93,13 @@ protected: void showStatusMessage(const QString &msg) const { m_engine->showStatusMessage(msg); } + static QString msgGdbStopFailed(const QString &why); + static QString msgInferiorStopFailed(const QString &why); + static QString msgAttachedToStoppedInferior(); + static QString msgInferiorStarted(); + static QString msgInferiorRunning(); + static QString msgConnectRemoteServerFailed(const QString &why); + GdbEngine * const m_engine; QProcess m_gdbProc; diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index a43947129b7..7095db9b9a6 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -107,11 +107,10 @@ void AttachGdbAdapter::handleAttach(const GdbResponse &response) if (response.resultClass == GdbResultDone) { setState(InferiorStopped); debugMessage(_("INFERIOR STARTED")); - showStatusMessage(tr("Attached to stopped inferior.")); + showStatusMessage(msgAttachedToStoppedInferior()); m_engine->updateAll(); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = __(response.data.findChild("msg").data()); - setState(InferiorStartFailed); emit inferiorStartFailed(msg); } } @@ -154,9 +153,8 @@ void AttachGdbAdapter::handleDetach(const GdbResponse &response) setState(InferiorShutDown); emit inferiorShutDown(); shutdown(); // re-iterate... - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Inferior process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data())); setState(InferiorShutdownFailed); emit inferiorShutdownFailed(msg); } @@ -166,9 +164,8 @@ void AttachGdbAdapter::handleExit(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { // don't set state here, this will be handled in handleGdbFinished() - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Gdb process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data())); emit adapterShutdownFailed(msg); } } diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index d51963606e3..5a522f4d5eb 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -121,7 +121,6 @@ void CoreGdbAdapter::handleTargetCore1(const GdbResponse &response) int pos1 = console.data().indexOf('`'); int pos2 = console.data().indexOf('\''); if (pos1 == -1 || pos2 == -1) { - setState(InferiorStartFailed); emit inferiorStartFailed(tr("No binary found.")); } else { m_executable = console.data().mid(pos1 + 1, pos2 - pos1 - 1); @@ -133,9 +132,7 @@ void CoreGdbAdapter::handleTargetCore1(const GdbResponse &response) m_engine->postCommand(_("detach"), CB(handleDetach1)); } } else { - QTC_ASSERT(response.resultClass == GdbResultError, /**/); const QByteArray msg = response.data.findChild("msg").data(); - setState(InferiorStartFailed); emit inferiorStartFailed(msg); } } @@ -149,9 +146,7 @@ void CoreGdbAdapter::handleDetach1(const GdbResponse &response) m_engine->postCommand(_("-file-exec-and-symbols \"%1\"") .arg(fi.absoluteFilePath()), CB(handleFileExecAndSymbols)); } else { - QTC_ASSERT(response.resultClass == GdbResultError, /**/); const QByteArray msg = response.data.findChild("msg").data(); - setState(InferiorStartFailed); emit inferiorStartFailed(msg); } } @@ -165,12 +160,11 @@ void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) QFileInfo fi(startParameters().coreFile); QString coreName = fi.absoluteFilePath(); m_engine->postCommand(_("target core ") + coreName, CB(handleTargetCore2)); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = tr("Symbols not found in \"%1\" failed:\n%2") .arg(__(response.data.findChild("msg").data())); setState(InferiorUnrunnable); m_engine->updateAll(); - //setState(InferiorStartFailed); // emit inferiorStartFailed(msg); } } @@ -182,12 +176,11 @@ void CoreGdbAdapter::handleTargetCore2(const GdbResponse &response) showStatusMessage(tr("Attached to core.")); setState(InferiorUnrunnable); m_engine->updateAll(); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = tr("Attach to core \"%1\" failed:\n%2") .arg(__(response.data.findChild("msg").data())); setState(InferiorUnrunnable); m_engine->updateAll(); - //setState(InferiorStartFailed); // emit inferiorStartFailed(msg); } } @@ -220,9 +213,8 @@ void CoreGdbAdapter::handleExit(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { // don't set state here, this will be handled in handleGdbFinished() - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Gdb process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data())); emit adapterShutdownFailed(msg); } } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 90570591ad3..f45b63f648e 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -89,7 +89,7 @@ #endif #include -// FIXME: temporary hack to evalute tbreak based step-over behaviour +// FIXME: temporary hack to evalaute tbreak based step-over behaviour static QString lastFile; static int lastLine; @@ -811,10 +811,17 @@ void GdbEngine::handleResultRecord(const GdbResponse &response) GdbResponse responseWithCookie = response; responseWithCookie.cookie = cmd.cookie; - if (cmd.callback) - (this->*cmd.callback)(responseWithCookie); - if (cmd.adapterCallback) - (m_gdbAdapter->*cmd.adapterCallback)(responseWithCookie); + if (response.resultClass != GdbResultError && + response.resultClass != ((cmd.flags & RunRequest) ? GdbResultRunning : GdbResultDone)) { + debugMessage(_("UNEXPECTED RESPONSE %1 TO COMMAND %2") + .arg(_(GdbResponse::stringFromResultClass(response.resultClass))) + .arg(cmd.command)); + } else { + if (cmd.callback) + (this->*cmd.callback)(responseWithCookie); + else if (cmd.adapterCallback) + (m_gdbAdapter->*cmd.adapterCallback)(responseWithCookie); + } if (cmd.flags & RebuildModel) { --m_pendingRequests; @@ -1173,7 +1180,7 @@ void GdbEngine::handleStop1(const GdbMi &data) GdbMi frameData = data.findChild("frame"); if (frameData.findChild("func").data() == "_start" && frameData.findChild("from").data() == "/lib/ld-linux.so.2") { - postCommand(_("-exec-continue"), CB(handleExecContinue)); + postCommand(_("-exec-continue"), RunRequest, CB(handleExecContinue)); return; } } @@ -1302,7 +1309,7 @@ void GdbEngine::handleFileExecAndSymbols(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { //m_breakHandler->clearBreakMarkers(); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = __(response.data.findChild("msg").data()); showMessageBox(QMessageBox::Critical, tr("Starting executable failed"), msg); QTC_ASSERT(state() == InferiorRunning, /**/); @@ -1316,7 +1323,7 @@ void GdbEngine::handleExecContinue(const GdbResponse &response) if (response.resultClass == GdbResultRunning) { // The "running" state is picked up in handleResponse() QTC_ASSERT(state() == InferiorRunning, /**/); - } else if (response.resultClass == GdbResultError) { + } else { QTC_ASSERT(state() == InferiorRunningRequested, /**/); QByteArray msg = response.data.findChild("msg").data(); if (msg.startsWith("Cannot find bounds of current function")) { @@ -1331,8 +1338,6 @@ void GdbEngine::handleExecContinue(const GdbResponse &response) QTC_ASSERT(state() == InferiorRunning, /**/); shutdown(); } - } else { - QTC_ASSERT(false, /**/); } } @@ -1474,7 +1479,7 @@ void GdbEngine::continueInferiorInternal() m_manager->resetLocation(); setTokenBarrier(); setState(InferiorRunningRequested); - postCommand(_("-exec-continue"), CB(handleExecContinue)); + postCommand(_("-exec-continue"), RunRequest, CB(handleExecContinue)); } void GdbEngine::autoContinueInferior() @@ -1496,9 +1501,9 @@ void GdbEngine::stepExec() setState(InferiorRunningRequested); showStatusMessage(tr("Step requested..."), 5000); if (manager()->isReverseDebugging()) - postCommand(_("-reverse-step"), CB(handleExecContinue)); + postCommand(_("-reverse-step"), RunRequest, CB(handleExecContinue)); else - postCommand(_("-exec-step"), CB(handleExecContinue)); + postCommand(_("-exec-step"), RunRequest, CB(handleExecContinue)); } void GdbEngine::stepIExec() @@ -1508,9 +1513,9 @@ void GdbEngine::stepIExec() setState(InferiorRunningRequested); showStatusMessage(tr("Step by instruction requested..."), 5000); if (manager()->isReverseDebugging()) - postCommand(_("-reverse-stepi"), CB(handleExecContinue)); + postCommand(_("-reverse-stepi"), RunRequest, CB(handleExecContinue)); else - postCommand(_("-exec-step-instruction"), CB(handleExecContinue)); + postCommand(_("-exec-step-instruction"), RunRequest, CB(handleExecContinue)); } void GdbEngine::stepOutExec() @@ -1519,7 +1524,7 @@ void GdbEngine::stepOutExec() setTokenBarrier(); setState(InferiorRunningRequested); showStatusMessage(tr("Finish function requested..."), 5000); - postCommand(_("-exec-finish"), CB(handleExecContinue)); + postCommand(_("-exec-finish"), RunRequest, CB(handleExecContinue)); } void GdbEngine::nextExec() @@ -1529,14 +1534,14 @@ void GdbEngine::nextExec() setState(InferiorRunningRequested); showStatusMessage(tr("Step next requested..."), 5000); if (manager()->isReverseDebugging()) - postCommand(_("-reverse-next"), CB(handleExecContinue)); + postCommand(_("-reverse-next"), RunRequest, CB(handleExecContinue)); else { #if 1 - postCommand(_("-exec-next"), CB(handleExecContinue)); + postCommand(_("-exec-next"), RunRequest, CB(handleExecContinue)); #else postCommand(_("tbreak %1:%2").arg(QFileInfo(lastFile).fileName()) .arg(lastLine + 1)); - postCommand(_("-exec-continue"), CB(handleExecContinue)); + postCommand(_("-exec-continue"), RunRequest, CB(handleExecContinue)); #endif } } @@ -1548,9 +1553,9 @@ void GdbEngine::nextIExec() setState(InferiorRunningRequested); showStatusMessage(tr("Step next instruction requested..."), 5000); if (manager()->isReverseDebugging()) - postCommand(_("-reverse-nexti"), CB(handleExecContinue)); + postCommand(_("-reverse-nexti"), RunRequest, CB(handleExecContinue)); else - postCommand(_("-exec-next-instruction"), CB(handleExecContinue)); + postCommand(_("-exec-next-instruction"), RunRequest, CB(handleExecContinue)); } void GdbEngine::runToLineExec(const QString &fileName, int lineNumber) @@ -1571,7 +1576,7 @@ void GdbEngine::runToFunctionExec(const QString &functionName) showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000); // that should be "^running". We need to handle the resulting // "Stopped" - postCommand(_("-exec-continue"), CB(handleExecContinue)); + postCommand(_("-exec-continue"), RunRequest, CB(handleExecContinue)); //postCommand(_("-exec-continue"), handleExecRunToFunction); } @@ -1851,7 +1856,7 @@ void GdbEngine::handleBreakCondition(const GdbResponse &response) BreakpointData *data = handler->at(index); //qDebug() << "HANDLE BREAK CONDITION" << index << data->condition; data->bpCondition = data->condition; - } else { // GdbResultError + } else { QByteArray msg = response.data.findChild("msg").data(); // happens on Mac if (1 || msg.startsWith("Error parsing breakpoint condition. " @@ -1877,7 +1882,7 @@ void GdbEngine::handleBreakInsert(const GdbResponse &response) //#endif attemptBreakpointSynchronization(); handler->updateMarkers(); - } else { // GdbResultError + } else { const BreakpointData *data = handler->at(index); // Note that it is perfectly correct that the file name is put // in quotes but not escaped. GDB simply is like that. @@ -1967,7 +1972,7 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response) BreakpointData *data = handler->at(index); GdbMi bkpt = response.data.findChild("bkpt"); breakpointDataFromOutput(data, bkpt); - } else { // GdbResultError + } else { qDebug() << "INSERTING BREAKPOINT WITH BASE NAME FAILED. GIVING UP"; BreakpointData *data = handler->at(index); data->bpNumber = _(""); @@ -2648,8 +2653,6 @@ static void setWatchDataSAddress(WatchData &data, const GdbMi &mi) void GdbEngine::setUseDebuggingHelpers(const QVariant &on) { //qDebug() << "SWITCHING ON/OFF DUMPER DEBUGGING:" << on; - // FIXME: a bit too harsh, but otherwise the treeview sometimes look funny - //m_expandedINames.clear(); Q_UNUSED(on) setTokenBarrier(); updateLocals(); @@ -2916,6 +2919,7 @@ void GdbEngine::updateSubItem(const WatchData &data0) return; } +//#if !X if (data.isHasChildrenNeeded() && data.variable.isEmpty()) { #if DEBUG_SUBITEM qDebug() << "UPDATE SUBITEM: VARIABLE NEEDED FOR CHILDCOUNT"; @@ -2925,6 +2929,7 @@ void GdbEngine::updateSubItem(const WatchData &data0) // item, with childrenNeeded() set. return; } +//#endif if (data.isHasChildrenNeeded()) { QTC_ASSERT(!data.variable.isEmpty(), return); // tested above @@ -2939,16 +2944,32 @@ void GdbEngine::updateSubItem(const WatchData &data0) void GdbEngine::updateWatchData(const WatchData &data) { - // Bump requests to avoid model rebuilding during the nested - // updateWatchModel runs. - ++m_pendingRequests; - PENDING_DEBUG("UPDATE WATCH BUMPS PENDING UP TO " << m_pendingRequests); -#if 1 - QMetaObject::invokeMethod(this, "updateWatchDataHelper", - Qt::QueuedConnection, Q_ARG(WatchData, data)); + if (isSynchroneous()) { + // This should only be called for fresh expanded items, not for + // items that had their children retrieved earlier. + qDebug() << "\nUPDATE WATCH DATA: " << data.toString() << "\n"; +#if 0 + WatchData data1 = data; + data1.setAllUnneeded(); + insertData(data1); + rebuildModel(); #else - updateWatchDataHelper(data); + if (data.iname.endsWith(_("."))) + return; + updateLocals(); #endif + } else { + // Bump requests to avoid model rebuilding during the nested + // updateWatchModel runs. + ++m_pendingRequests; + PENDING_DEBUG("UPDATE WATCH BUMPS PENDING UP TO " << m_pendingRequests); +#if 1 + QMetaObject::invokeMethod(this, "updateWatchDataHelper", + Qt::QueuedConnection, Q_ARG(WatchData, data)); +#else + updateWatchDataHelper(data); +#endif + } } void GdbEngine::updateWatchDataHelper(const WatchData &data) @@ -3112,7 +3133,7 @@ void GdbEngine::handleVarCreate(const GdbResponse &response) // data.setValue(QString()); insertData(data); } - } else if (response.resultClass == GdbResultError) { + } else { data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data())); if (data.isWatcher()) { data.value = strNotInScope; @@ -3135,7 +3156,7 @@ void GdbEngine::handleEvaluateExpression(const GdbResponse &response) // data.name = response.data.findChild("value").data(); //else setWatchDataValue(data, response.data.findChild("value")); - } else if (response.resultClass == GdbResultError) { + } else { data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data())); } //qDebug() << "HANDLE EVALUATE EXPRESSION:" << data.toString(); @@ -3147,7 +3168,7 @@ void GdbEngine::handleDebuggingHelperSetup(const GdbResponse &response) { //qDebug() << "CUSTOM SETUP RESULT:" << response.toString(); if (response.resultClass == GdbResultDone) { - } else if (response.resultClass == GdbResultError) { + } else { QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data()); //qDebug() << "CUSTOM DUMPER SETUP ERROR MESSAGE:" << msg; showStatusMessage(tr("Custom dumper setup: %1").arg(msg), 10000); @@ -3160,7 +3181,7 @@ void GdbEngine::handleDebuggingHelperValue1(const GdbResponse &response) QTC_ASSERT(data.isValid(), return); if (response.resultClass == GdbResultDone) { // ignore this case, data will follow - } else if (response.resultClass == GdbResultError) { + } else { QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data()); #ifdef QT_DEBUG // Make debugging of dumpers easier @@ -3331,7 +3352,7 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResponse &response) data.setAllUnneeded(); insertData(data); } - } else if (response.resultClass == GdbResultError) { + } else { WatchData data = response.cookie.value(); data.setError(strNotInScope); data.setAllUnneeded(); @@ -3341,12 +3362,6 @@ void GdbEngine::handleDebuggingHelperValue3(const GdbResponse &response) void GdbEngine::updateLocals() { - // Asynchronous load of injected library, initialize in first stop - if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried - && m_dumperHelper.typeCount() == 0 - && inferiorPid() > 0) - tryQueryDebuggingHelpers(); - m_pendingRequests = 0; m_processedNames.clear(); @@ -3355,13 +3370,70 @@ void GdbEngine::updateLocals() m_toolTipExpression.clear(); manager()->watchHandler()->beginCycle(); - QString level = QString::number(currentFrame()); - // '2' is 'list with type and value' - QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level; - postCommand(cmd, WatchUpdate, CB(handleStackListArguments)); - // '2' is 'list with type and value' - postCommand(_("-stack-list-locals 2"), WatchUpdate, - CB(handleStackListLocals)); // stage 2/2 + // Asynchronous load of injected library, initialize in first stop + if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried + && m_dumperHelper.typeCount() == 0 + && inferiorPid() > 0) + tryQueryDebuggingHelpers(); + + if (isSynchroneous()) { + QStringList expanded = m_manager->watchHandler()->expandedINames().toList(); + qDebug() << "EXPANDED: " << expanded; + postCommand(_("bb %1").arg(expanded.join(_(","))), + WatchUpdate, CB(handleStackFrame1)); + postCommand(_("p 0"), WatchUpdate, CB(handleStackFrame2)); + } else { + QString level = QString::number(currentFrame()); + // '2' is 'list with type and value' + QString cmd = _("-stack-list-arguments 2 ") + level + _c(' ') + level; + postCommand(cmd, WatchUpdate, CB(handleStackListArguments)); + // '2' is 'list with type and value' + postCommand(_("-stack-list-locals 2"), WatchUpdate, + CB(handleStackListLocals)); // stage 2/2 + } +} + +void GdbEngine::handleStackFrame1(const GdbResponse &response) +{ + if (response.resultClass == GdbResultDone) { + QByteArray out = response.data.findChild("consolestreamoutput").data(); + while (out.endsWith(' ') || out.endsWith('\n')) + out.chop(1); + //qDebug() << "FIRST CHUNK: " << out; + m_firstChunk = out; + } else if (response.resultClass == GdbResultError) { + QTC_ASSERT(false, /**/); + } +} + +void GdbEngine::handleStackFrame2(const GdbResponse &response) +{ + if (response.resultClass == GdbResultDone) { + QByteArray out = response.data.findChild("consolestreamoutput").data(); + while (out.endsWith(' ') || out.endsWith('\n')) + out.chop(1); + //qDebug() << "SECOND CHUNK: " << out; + out = m_firstChunk + out; + // FIXME: Hack, make sure dumper does not return "{}" + out.replace(",{}", ""); + GdbMi all("[" + out + "]"); + qDebug() << "ALL: " << all.toString(); + QList locals = all.children(); + //manager()->watchHandler()->insertBulkData(locals); + //setLocals(locals); + WatchData *data = manager()->watchHandler()->findItem(_("local")); + QTC_ASSERT(data, return); + + QList list; + foreach (const GdbMi &local, locals) + handleChildren(*data, local, &list); + + manager()->watchHandler()->insertBulkData(list); + + manager()->watchHandler()->updateWatchers(); + } else if (response.resultClass == GdbResultError) { + QTC_ASSERT(false, /**/); + } } void GdbEngine::handleStackListArguments(const GdbResponse &response) @@ -3393,7 +3465,7 @@ void GdbEngine::handleStackListArguments(const GdbResponse &response) const GdbMi frame = list.findChild("frame"); const GdbMi args = frame.findChild("args"); m_currentFunctionArgs = args.children(); - } else if (response.resultClass == GdbResultError) { + } else { qDebug() << "FIXME: GdbEngine::handleStackListArguments: should not happen" << response.toString(); } @@ -3456,14 +3528,23 @@ void GdbEngine::setLocals(const QList &locals) data.exp = nam; data.framekey = m_currentFrame + data.name; setWatchDataType(data, item.findChild("type")); - // set value only directly if it is simple enough, otherwise - // pass through the insertData() machinery - if (isIntOrFloatType(data.type) || isPointerType(data.type)) - setWatchDataValue(data, item.findChild("value")); - if (isSymbianIntType(data.type)) { - setWatchDataValue(data, item.findChild("value")); - data.setHasChildren(false); + if (isSynchroneous()) { + setWatchDataValue(data, item.findChild("value"), + item.findChild("valueencoded").data().toInt()); + // We know that the complete list of children is + // somewhere in the response. + data.setChildrenUnneeded(); + } else { + // set value only directly if it is simple enough, otherwise + // pass through the insertData() machinery + if (isIntOrFloatType(data.type) || isPointerType(data.type)) + setWatchDataValue(data, item.findChild("value")); + if (isSymbianIntType(data.type)) { + setWatchDataValue(data, item.findChild("value")); + data.setHasChildren(false); + } } + // Let's be a bit more bold: //if (!hasDebuggingHelperForType(data.type)) { // QByteArray value = item.findChild("value").data(); @@ -3515,7 +3596,8 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item, //qDebug() << "DATA" << data.toString(); QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"'); //iname += '.' + exp; - postCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data)); + postCommand(cmd, WatchUpdate, + CB(handleVarListChildren), QVariant::fromValue(data)); } else if (item.findChild("numchild").data() == "0") { // happens for structs without data, e.g. interfaces. WatchData data; @@ -3533,7 +3615,8 @@ void GdbEngine::handleVarListChildrenHelper(const GdbMi &item, WatchData data; data.iname = _(name); QString cmd = _("-var-list-children --all-values \"") + data.variable + _c('"'); - postCommand(cmd, WatchUpdate, CB(handleVarListChildren), QVariant::fromValue(data)); + postCommand(cmd, WatchUpdate, + CB(handleVarListChildren), QVariant::fromValue(data)); } else if (exp == "staticMetaObject") { // && item.findChild("type").data() == "const QMetaObject") // FIXME: Namespaces? @@ -3627,10 +3710,8 @@ void GdbEngine::handleVarListChildren(const GdbResponse &response) // this skips the spurious "public", "private" etc levels // gdb produces } - } else if (response.resultClass == GdbResultError) { - data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data())); } else { - data.setError(tr("Unknown error: ") + QString::fromLocal8Bit(response.toString())); + data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data())); } } @@ -3655,6 +3736,9 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString & void GdbEngine::tryLoadDebuggingHelpers() { + if (isSynchroneous()) + return; + if (m_debuggingHelperState != DebuggingHelperUninitialized) return; if (!startModeAllowsDumpers()) { @@ -3735,9 +3819,13 @@ void GdbEngine::tryLoadDebuggingHelpers() void GdbEngine::tryQueryDebuggingHelpers() { +#if !X // retrieve list of dumpable classes postCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"), EmbedToken); postCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper)); +#else + m_debuggingHelperState = DebuggingHelperUnavailable; +#endif } void GdbEngine::recheckDebuggingHelperAvailability() @@ -3939,7 +4027,7 @@ void GdbEngine::handleFetchDisassemblerByLine(const GdbResponse &response) fetchDisassemblerByAddress(ac.agent, true); else ac.agent->setContents(parseDisassembler(lines)); - } else if (response.resultClass == GdbResultError) { + } else { // 536^error,msg="mi_cmd_disassemble: Invalid line number" QByteArray msg = response.data.findChild("msg").data(); if (msg == "mi_cmd_disassemble: Invalid line number") @@ -4130,6 +4218,7 @@ void GdbEngine::handleInferiorStartFailed(const QString &msg) { debugMessage(_("INFERIOR START FAILED")); showMessageBox(QMessageBox::Critical, tr("Inferior start failed"), msg); + setState(InferiorStartFailed); shutdown(); } @@ -4186,6 +4275,10 @@ void GdbEngine::showMessageBox(int icon, const QString &title, const QString &te m_manager->showMessageBox(icon, title, text); } +bool GdbEngine::isSynchroneous() const +{ + return false; +} // // Factory diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 73d898fc2fd..8c5b3020cdb 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -146,9 +146,10 @@ private: Q_SLOT void setDebugDebuggingHelpers(const QVariant &on); Q_SLOT void setUseDebuggingHelpers(const QVariant &on); Q_SLOT void setAutoDerefPointers(const QVariant &on); - virtual bool isGdbEngine() const { return true; } + bool isGdbEngine() const { return true; } + bool isSynchroneous() const; - virtual bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) const; + bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) const; // // Own stuff @@ -171,11 +172,12 @@ private: public: // otherwise the Qt flag macros are unhappy enum GdbCommandFlag { NoFlags = 0, - NeedsStop = 1, - Discardable = 2, - RebuildModel = 4, + NeedsStop = 1, // The command needs a stopped inferior + Discardable = 2, // No need to wait for the reply before continuing inferior + RebuildModel = 4, // Trigger model rebuild when no such commands are pending any more WatchUpdate = Discardable | RebuildModel, - EmbedToken = 8 + EmbedToken = 8, // Expand %1 in the command to the command token + RunRequest = 16 // Callback expect GdbResultRunning instead of GdbResultDone }; Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag) @@ -347,6 +349,9 @@ private: void handleStackListFrames(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response); void handleStackListThreads(const GdbResponse &response); + void handleStackFrame1(const GdbResponse &response); + void handleStackFrame2(const GdbResponse &response); + QByteArray m_firstChunk; Q_SLOT void reloadStack(bool forceGotoLocation); Q_SLOT void reloadFullStack(); diff --git a/src/plugins/debugger/gdb/gdbmi.cpp b/src/plugins/debugger/gdb/gdbmi.cpp index a805df94df7..ffac5d76d15 100644 --- a/src/plugins/debugger/gdb/gdbmi.cpp +++ b/src/plugins/debugger/gdb/gdbmi.cpp @@ -362,7 +362,7 @@ GdbMi GdbMi::findChild(const char *name) const // ////////////////////////////////////////////////////////////////////////////////// -QByteArray stringFromResultClass(GdbResultClass resultClass) +QByteArray GdbResponse::stringFromResultClass(GdbResultClass resultClass) { switch (resultClass) { case GdbResultDone: return "done"; diff --git a/src/plugins/debugger/gdb/gdbmi.h b/src/plugins/debugger/gdb/gdbmi.h index 6abea9292f0..24295afea66 100644 --- a/src/plugins/debugger/gdb/gdbmi.h +++ b/src/plugins/debugger/gdb/gdbmi.h @@ -149,7 +149,6 @@ enum GdbResultClass // "done" | "running" | "connected" | "error" | "exit" GdbResultUnknown, GdbResultDone, - GdbResultCustomDone, GdbResultRunning, GdbResultConnected, GdbResultError, @@ -161,6 +160,7 @@ class GdbResponse public: GdbResponse() : token(-1), resultClass(GdbResultUnknown) {} QByteArray toString() const; + static QByteArray stringFromResultClass(GdbResultClass resultClass); int token; GdbResultClass resultClass; diff --git a/src/plugins/debugger/gdb/plaingdbadapter.cpp b/src/plugins/debugger/gdb/plaingdbadapter.cpp index 5d679527aa4..100d1f5f772 100644 --- a/src/plugins/debugger/gdb/plaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/plaingdbadapter.cpp @@ -122,7 +122,7 @@ void PlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) //m_breakHandler->clearBreakMarkers(); setState(InferiorPrepared); emit inferiorPrepared(); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = tr("Starting executable failed:\n") + __(response.data.findChild("msg").data()); setState(InferiorPreparationFailed); @@ -135,14 +135,12 @@ void PlainGdbAdapter::handleExecRun(const GdbResponse &response) if (response.resultClass == GdbResultRunning) { QTC_ASSERT(state() == InferiorRunning, qDebug() << state()); debugMessage(_("INFERIOR STARTED")); - showStatusMessage(tr("Inferior started.")); + showStatusMessage(msgInferiorStarted()); } else { QTC_ASSERT(state() == InferiorRunningRequested, qDebug() << state()); - QTC_ASSERT(response.resultClass == GdbResultError, /**/); const QByteArray &msg = response.data.findChild("msg").data(); //QTC_ASSERT(status() == InferiorRunning, /**/); //interruptInferior(); - setState(InferiorStartFailed); emit inferiorStartFailed(msg); } } @@ -151,7 +149,7 @@ void PlainGdbAdapter::startInferior() { QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); setState(InferiorRunningRequested); - m_engine->postCommand(_("-exec-run"), CB(handleExecRun)); + m_engine->postCommand(_("-exec-run"), GdbEngine::RunRequest, CB(handleExecRun)); } void PlainGdbAdapter::interruptInferior() @@ -218,9 +216,8 @@ void PlainGdbAdapter::handleKill(const GdbResponse &response) setState(InferiorShutDown); emit inferiorShutDown(); shutdown(); // re-iterate... - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Inferior process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data())); setState(InferiorShutdownFailed); emit inferiorShutdownFailed(msg); } @@ -230,9 +227,8 @@ void PlainGdbAdapter::handleExit(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { // don't set state here, this will be handled in handleGdbFinished() - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Gdb process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data())); emit adapterShutdownFailed(msg); } } diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp index 71ee7852b27..732fe7ed097 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp @@ -175,6 +175,7 @@ void RemoteGdbAdapter::prepareInferior() #endif } +#if 0 void RemoteGdbAdapter::handleSetTargetAsync(const GdbResponse &response) { QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); @@ -184,12 +185,13 @@ void RemoteGdbAdapter::handleSetTargetAsync(const GdbResponse &response) QString fileName = fi.absoluteFilePath(); m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName), CB(handleFileExecAndSymbols)); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = tr("Adapter too old: does not support asynchronous mode."); setState(InferiorPreparationFailed); emit inferiorPreparationFailed(msg); } } +#endif void RemoteGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) { @@ -198,7 +200,7 @@ void RemoteGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) //m_breakHandler->clearBreakMarkers(); m_engine->setState(InferiorPrepared); emit inferiorPrepared(); - } else if (response.resultClass == GdbResultError) { + } else { QString msg = tr("Starting remote executable failed:\n"); msg += __(response.data.findChild("msg").data()); setState(InferiorPreparationFailed); @@ -212,13 +214,12 @@ void RemoteGdbAdapter::handleTargetRemote(const GdbResponse &record) if (record.resultClass == GdbResultDone) { // gdb server will stop the remote application itself. debugMessage(_("INFERIOR STARTED")); - showStatusMessage(tr("Attached to stopped inferior.")); + showStatusMessage(msgAttachedToStoppedInferior()); setState(InferiorStopped); m_engine->continueInferior(); - } else if (record.resultClass == GdbResultError) { + } else { // 16^error,msg="hd:5555: Connection timed out." - QString msg = tr("Connecting to remote server failed:\n"); - msg += __(record.data.findChild("msg").data()); + QString msg = msgConnectRemoteServerFailed(__(record.data.findChild("msg").data())); setState(InferiorPreparationFailed); emit inferiorStartFailed(msg); } @@ -272,9 +273,8 @@ void RemoteGdbAdapter::handleKill(const GdbResponse &response) setState(InferiorShutDown); emit inferiorShutDown(); shutdown(); // re-iterate... - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Inferior process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data())); setState(InferiorShutdownFailed); emit inferiorShutdownFailed(msg); } @@ -284,9 +284,8 @@ void RemoteGdbAdapter::handleExit(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { // don't set state here, this will be handled in handleGdbFinished() - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Gdb process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data())); emit adapterShutdownFailed(msg); } } diff --git a/src/plugins/debugger/gdb/remotegdbadapter.h b/src/plugins/debugger/gdb/remotegdbadapter.h index a0ca3aac4cb..44600b9b89e 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.h +++ b/src/plugins/debugger/gdb/remotegdbadapter.h @@ -65,7 +65,9 @@ private: Q_SLOT void readUploadStandardError(); Q_SLOT void uploadProcError(QProcess::ProcessError error); +#if 0 void handleSetTargetAsync(const GdbResponse &response); +#endif void handleFileExecAndSymbols(const GdbResponse &response); void handleTargetRemote(const GdbResponse &response); void handleKill(const GdbResponse &response); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index a2b735777c4..4605044bf6a 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -391,7 +391,7 @@ void TrkGdbAdapter::slotEmitDelayedAdapterStartFailed() emit adapterStartFailed(m_adapterFailMessage, TrkOptionsPage::settingsId()); } -void TrkGdbAdapter::startInferiorEarly() +void TrkGdbAdapter::waitForTrkConnect() { QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); QString errorMessage; @@ -406,7 +406,7 @@ void TrkGdbAdapter::startInferiorEarly() } // Do not loop forever if (m_waitCount++ < (m_options->mode == TrkOptions::BlueTooth ? 60 : 5)) { - QTimer::singleShot(1000, this, SLOT(startInferiorEarly())); + QTimer::singleShot(1000, this, SLOT(waitForTrkConnect())); } else { QString msg = _("Failed to connect to %1 after " "%2 attempts").arg(device).arg(m_waitCount); @@ -426,14 +426,7 @@ void TrkGdbAdapter::startInferiorEarly() // "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File //sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File - QByteArray ba; - appendByte(&ba, 0); // ? - appendByte(&ba, 0); // ? - appendByte(&ba, 0); // ? - - appendString(&ba, m_remoteExecutable.toLatin1(), TargetByteOrder); - sendTrkMessage(0x40, TrkCB(handleCreateProcess), ba); // Create Item - //sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(startGdbServer)); + maybeAdapterStarted(); } void TrkGdbAdapter::logMessage(const QString &msg) @@ -969,24 +962,6 @@ i */ } } -void TrkGdbAdapter::executeCommand(const QString &msg) -{ - if (msg == "EI") { - sendGdbMessage("-exec-interrupt"); - } else if (msg == "C") { - sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE"); - } else if (msg == "S") { - sendTrkMessage(0x19, TrkCallback(), trkStepRangeMessage(0x01), "STEP"); - } else if (msg == "N") { - sendTrkMessage(0x19, TrkCallback(), trkStepRangeMessage(0x11), "NEXT"); - } else if (msg == "I") { - interruptInferior(); - } else { - logMessage("EXECUTING GDB COMMAND " + msg); - sendGdbMessage(msg); - } -} - void TrkGdbAdapter::sendTrkMessage(byte code, TrkCallback callback, const QByteArray &data, const QVariant &cookie) { @@ -1161,39 +1136,6 @@ void TrkGdbAdapter::handleCpuType(const TrkResult &result) logMessage(logMsg); } -void TrkGdbAdapter::handleCreateProcess(const TrkResult &result) -{ - QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); - // 40 00 00] - //logMessage(" RESULT: " + result.toString()); - // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] - if (result.errorCode()) { - logMessage("ERROR: " + result.errorString()); - QString msg = _("Cannot start executable \"%1\" on the device:\n%2") - .arg(m_remoteExecutable).arg(result.errorString()); - // Delay cleanup as not to close a trk device from its read handler, - // which blocks. - emitDelayedAdapterStartFailed(msg); - return; - } - const char *data = result.data.data(); - m_session.pid = extractInt(data + 1); - m_session.tid = extractInt(data + 5); - m_session.codeseg = extractInt(data + 9); - m_session.dataseg = extractInt(data + 13); - - logMessage("PID: " + hexxNumber(m_session.pid)); - logMessage("TID: " + hexxNumber(m_session.tid)); - logMessage("COD: " + hexxNumber(m_session.codeseg)); - logMessage("DAT: " + hexxNumber(m_session.dataseg)); - - QByteArray ba; - appendInt(&ba, m_session.pid); - appendInt(&ba, m_session.tid); - - startGdb(); -} - void TrkGdbAdapter::handleDeleteProcess(const TrkResult &result) { Q_UNUSED(result); @@ -1602,10 +1544,17 @@ void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitSta void TrkGdbAdapter::handleGdbStarted() { - QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); logMessage(QString("GDB: Process Started")); - setState(AdapterStarted); - emit adapterStarted(); + maybeAdapterStarted(); +} + +void TrkGdbAdapter::maybeAdapterStarted() +{ + QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); + if (m_gdbProc.state() == QProcess::Running && m_trkDevice.isOpen()) { + setState(AdapterStarted); + emit adapterStarted(); + } } void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState) @@ -1656,15 +1605,76 @@ void TrkGdbAdapter::startAdapter() } m_waitCount = 0; - startInferiorEarly(); + QTC_ASSERT(m_gdbServer == 0, delete m_gdbServer); + QTC_ASSERT(m_gdbConnection == 0, m_gdbConnection = 0); + m_gdbServer = new QTcpServer(this); + + if (!m_gdbServer->listen(QHostAddress(gdbServerIP()), gdbServerPort())) { + QString msg = QString("Unable to start the gdb server at %1: %2.") + .arg(m_gdbServerName).arg(m_gdbServer->errorString()); + logMessage(msg); + emit adapterStartFailed(msg, TrkOptionsPage::settingsId()); + return; + } + + logMessage(QString("Gdb server running on %1.\nLittle endian assumed.") + .arg(m_gdbServerName)); + + connect(m_gdbServer, SIGNAL(newConnection()), + this, SLOT(handleGdbConnection())); + + logMessage("STARTING GDB"); + logMessage(_("### Starting gdb %1").arg(m_options->gdb)); + QStringList gdbArgs; + gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file + gdbArgs.append(QLatin1String("-i")); + gdbArgs.append(QLatin1String("mi")); + m_gdbProc.start(m_options->gdb, gdbArgs); + + waitForTrkConnect(); } void TrkGdbAdapter::prepareInferior() { QTC_ASSERT(state() == AdapterStarted, qDebug() << state()); - // We already started the inferior process during the adapter start. - // Now make gdb aware of it. setState(InferiorPreparing); + + QByteArray ba; + appendByte(&ba, 0); // ? + appendByte(&ba, 0); // ? + appendByte(&ba, 0); // ? + + appendString(&ba, m_remoteExecutable.toLatin1(), TargetByteOrder); + sendTrkMessage(0x40, TrkCB(handleCreateProcess), ba); // Create Item + //sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(startGdbServer)); +} + +void TrkGdbAdapter::handleCreateProcess(const TrkResult &result) +{ + QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); + // 40 00 00] + //logMessage(" RESULT: " + result.toString()); + // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] + if (result.errorCode()) { + logMessage("ERROR: " + result.errorString()); + QString msg = _("Cannot start executable \"%1\" on the device:\n%2") + .arg(m_remoteExecutable).arg(result.errorString()); + // Delay cleanup as not to close a trk device from its read handler, + // which blocks. + emitDelayedAdapterStartFailed(msg); + return; + } + const char *data = result.data.data(); + m_session.pid = extractInt(data + 1); + m_session.tid = extractInt(data + 5); + m_session.codeseg = extractInt(data + 9); + m_session.dataseg = extractInt(data + 13); + + logMessage("PID: " + hexxNumber(m_session.pid)); + logMessage("TID: " + hexxNumber(m_session.tid)); + logMessage("COD: " + hexxNumber(m_session.codeseg)); + logMessage("DAT: " + hexxNumber(m_session.dataseg)); + const QString fileName = m_symbolFile; if (m_symbolFile.isEmpty()) { logMessage(_("WARNING: No symbol file available.")); @@ -1683,7 +1693,7 @@ void TrkGdbAdapter::handleTargetRemote(const GdbResponse &record) if (record.resultClass == GdbResultDone) { setState(InferiorPrepared); emit inferiorPrepared(); - } else if (record.resultClass == GdbResultError) { + } else { QString msg = tr("Connecting to trk server adapter failed:\n") + _(record.data.findChild("msg").data()); emit inferiorPreparationFailed(msg); @@ -1702,57 +1712,12 @@ void TrkGdbAdapter::handleFirstContinue(const GdbResponse &record) QTC_ASSERT(state() == InferiorRunning, qDebug() << state()); if (record.resultClass == GdbResultDone) { debugMessage(_("INFERIOR STARTED")); - showStatusMessage(tr("Inferior running.")); - } else if (record.resultClass == GdbResultError) { - //QString msg = __(record.data.findChild("msg").data()); - QString msg1 = tr("Connecting to remote server failed:"); - emit inferiorStartFailed(msg1 + record.toString()); + showStatusMessage(msgInferiorRunning()); + } else { + emit inferiorStartFailed(msgConnectRemoteServerFailed(record.toString())); } } -void TrkGdbAdapter::startGdb() -{ - QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); - QTC_ASSERT(m_gdbServer == 0, delete m_gdbServer); - QTC_ASSERT(m_gdbConnection == 0, m_gdbConnection = 0); - m_gdbServer = new QTcpServer(this); - - if (!m_gdbServer->listen(QHostAddress(gdbServerIP()), gdbServerPort())) { - QString msg = QString("Unable to start the gdb server at %1: %2.") - .arg(m_gdbServerName).arg(m_gdbServer->errorString()); - logMessage(msg); - // Delay cleanup as not to close a trk device from its read handler, - // which blocks. - emitDelayedAdapterStartFailed(msg); - return; - } - - logMessage(QString("Gdb server running on %1.\nLittle endian assumed.") - .arg(m_gdbServerName)); - - connect(m_gdbServer, SIGNAL(newConnection()), - this, SLOT(handleGdbConnection())); - - logMessage("STARTING GDB"); - logMessage(_("### Starting gdb %1").arg(m_options->gdb)); - QStringList gdbArgs; - gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file - gdbArgs.append(QLatin1String("-i")); - gdbArgs.append(QLatin1String("mi")); - m_gdbProc.start(m_options->gdb, gdbArgs); -} - -void TrkGdbAdapter::sendGdbMessage(const QString &msg, GdbCallback callback, - const QVariant &cookie) -{ - GdbCommand data; - data.command = msg; - data.callback = callback; - data.cookie = cookie; - logMessage(QString("<- ADAPTER TO GDB: %2").arg(msg)); - m_gdbProc.write(msg.toLatin1() + "\n"); -} - // // Rfcomm process handling // @@ -2017,10 +1982,9 @@ void TrkGdbAdapter::handleDirectStep3(const TrkResult &result) void TrkGdbAdapter::cleanup() { - if (m_trkDevice.isOpen()) - m_trkDevice.close(); - if (m_gdbServer) - delete m_gdbServer; + m_trkDevice.close(); + delete m_gdbServer; + m_gdbServer = 0; } void TrkGdbAdapter::shutdown() @@ -2082,9 +2046,8 @@ void TrkGdbAdapter::handleKill(const GdbResponse &response) setState(InferiorShutDown); emit inferiorShutDown(); shutdown(); // re-iterate... - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Inferior process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data())); setState(InferiorShutdownFailed); emit inferiorShutdownFailed(msg); } @@ -2095,9 +2058,8 @@ void TrkGdbAdapter::handleExit(const GdbResponse &response) if (response.resultClass == GdbResultDone) { qDebug() << "EXITED, NO MESSAGE..."; // don't set state here, this will be handled in handleGdbFinished() - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Gdb process could not be stopped:\n") + - __(response.data.findChild("msg").data()); + } else { + const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data())); emit adapterShutdownFailed(msg); } } diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index 030d61215a2..d5c9243bf3a 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -140,7 +140,6 @@ public: void setVerbose(int verbose) { m_verbose = verbose; } void setBufferedMemoryRead(bool b) { m_bufferedMemoryRead = b; } trk::Session &session() { return m_session; } - void startGdb(); // Set a device (from the project) to override the settings. QString overrideTrkDevice() const; @@ -180,7 +179,7 @@ private: void emitDelayedAdapterStartFailed(const QString &msg); Q_SLOT void slotEmitDelayedAdapterStartFailed(); - Q_SLOT void startInferiorEarly(); + Q_SLOT void waitForTrkConnect(); void handleKill(const GdbResponse &response); void handleExit(const GdbResponse &response); void handleTargetRemote(const GdbResponse &response); @@ -273,9 +272,6 @@ private: //QTime postTime; }; - void sendGdbMessage(const QString &msg, - GdbCallback callback = GdbCallback(), - const QVariant &cookie = QVariant()); Q_SLOT void handleGdbConnection(); Q_SLOT void readGdbServerCommand(); void readGdbResponse(); @@ -293,6 +289,8 @@ private: Q_SLOT void handleGdbStarted(); Q_SLOT void handleGdbStateChanged(QProcess::ProcessState newState); + void maybeAdapterStarted(); + void logMessage(const QString &msg); // triggers output() if m_verbose Q_SLOT void trkLogMessage(const QString &msg); @@ -316,7 +314,6 @@ private: QString effectiveTrkDevice() const; // Debuggee state - Q_SLOT void executeCommand(const QString &msg); trk::Session m_session; // global-ish data (process id, target information) Snapshot m_snapshot; // local-ish data (memory and registers) QString m_remoteExecutable; diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index b1110bda67a..619ac2bddb9 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -119,6 +119,7 @@ public: virtual bool isGdbEngine() const { return false; } virtual bool checkConfiguration(int /* toolChain */, QString * /* errorMessage */, QString * /* settingsPage */ = 0) const { return true; } + virtual bool isSynchroneous() const { return false; } protected: void showStatusMessage(const QString &msg, int timeout = -1); DebuggerState state() const; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 04e3bee8f73..1cf41e93235 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -177,7 +177,7 @@ void WatchData::setValueToolTip(const QString &tooltip) valuetooltip = tooltip; } -void WatchData::setType(const QString &str) +void WatchData::setType(const QString &str, bool guessChildrenFromType) { type = str.trimmed(); bool changed = true; @@ -202,7 +202,8 @@ void WatchData::setType(const QString &str) changed = false; } setTypeUnneeded(); - switch (guessChildren(type)) { + if (guessChildrenFromType) { + switch (guessChildren(type)) { case HasChildren: setHasChildren(true); break; @@ -212,6 +213,7 @@ void WatchData::setType(const QString &str) case HasPossiblyChildren: setHasChildren(true); // FIXME: bold assumption break; + } } } @@ -1091,7 +1093,10 @@ void WatchHandler::cleanup() void WatchHandler::insertData(const WatchData &data) { MODEL_DEBUG("INSERTDATA: " << data.toString()); - QTC_ASSERT(data.isValid(), return); + if (!data.isValid()) { + qWarning("%s:%d: Attempt to insert invalid watch item: %s", __FILE__, __LINE__, qPrintable(data.toString())); + return; + } if (data.isSomethingNeeded()) { m_manager->updateWatchData(data); } else { @@ -1117,7 +1122,11 @@ void WatchHandler::insertBulkData(const QList &list) foreach (const WatchData &data, list) { // we insert everything, including incomplete stuff // to reduce the number of row add operations in the model. - hash[parentName(data.iname)].append(data); + if (data.isValid()) { + hash[parentName(data.iname)].append(data); + } else { + qWarning("%s:%d: Attempt to bulk-insert invalid watch item: %s", __FILE__, __LINE__, qPrintable(data.toString())); + } } foreach (const QString &parentIName, hash.keys()) { WatchModel *model = modelForIName(parentIName); diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index eb2797f3e0e..dc426f4e22d 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -78,7 +78,7 @@ public: }; void setValue(const QString &); - void setType(const QString &); + void setType(const QString &, bool guessChildrenFromType = true); void setValueToolTip(const QString &); void setError(const QString &); void setAddress(const QString &address); diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index c004a25652c..e8f51d0d424 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -409,7 +409,8 @@ QString decodeData(const QByteArray &ba, int encoding) const QChar doubleQuote(QLatin1Char('"')); const QByteArray decodedBa = QByteArray::fromBase64(ba); QString rc = doubleQuote; - rc += QString::fromUtf16(reinterpret_cast(decodedBa.data()), decodedBa.size() / 2); + rc += QString::fromUtf16(reinterpret_cast + (decodedBa.data()), decodedBa.size() / 2); rc += doubleQuote; return rc; } @@ -417,17 +418,25 @@ QString decodeData(const QByteArray &ba, int encoding) const QByteArray decodedBa = QByteArray::fromBase64(ba); const QChar doubleQuote(QLatin1Char('"')); QString rc = doubleQuote; - rc += QString::fromUcs4(reinterpret_cast(decodedBa.data()), decodedBa.size() / 4); + rc += QString::fromUcs4(reinterpret_cast + (decodedBa.data()), decodedBa.size() / 4); rc += doubleQuote; return rc; } case 4: { // base64 encoded 16 bit data, without quotes (see 2) const QByteArray decodedBa = QByteArray::fromBase64(ba); - return QString::fromUtf16(reinterpret_cast(decodedBa.data()), decodedBa.size() / 2); + return QString::fromUtf16(reinterpret_cast + (decodedBa.data()), decodedBa.size() / 2); } case 5: { // base64 encoded 8 bit data, without quotes (see 1) return quoteUnprintableLatin1(QByteArray::fromBase64(ba)); } + case 7: { // %04x endoded 16 bit data + const QByteArray decodedBa = QByteArray::fromHex(ba); + //qDebug() << quoteUnprintableLatin1(decodedBa) << "\n\n"; + return QString::fromUtf16(reinterpret_cast + (decodedBa.data()), decodedBa.size() / 2); + } } return QCoreApplication::translate("Debugger", ""); } diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp index a995dfc5b7b..c60e2d6c9ee 100644 --- a/src/plugins/find/searchresultwindow.cpp +++ b/src/plugins/find/searchresultwindow.cpp @@ -78,7 +78,7 @@ SearchResultWindow::SearchResultWindow() m_replaceLabel->setContentsMargins(12, 0, 5, 0); m_replaceTextEdit = new QLineEdit(m_widget); m_replaceButton = new QToolButton(m_widget); - m_replaceButton->setToolTip(tr("Replace all occurances")); + m_replaceButton->setToolTip(tr("Replace all occurrences")); m_replaceButton->setText(tr("Replace")); m_replaceButton->setToolButtonStyle(Qt::ToolButtonTextOnly); m_replaceButton->setAutoRaise(true); @@ -234,7 +234,7 @@ void SearchResultWindow::setTextEditorFont(const QFont &font) m_searchResultTreeView->setTextEditorFont(font); } -void SearchResultWindow::handleJumpToSearchResult(int index, bool checked) +void SearchResultWindow::handleJumpToSearchResult(int index, bool /* checked */) { QTC_ASSERT(m_currentSearch, return); m_currentSearch->activated(m_items.at(index)); diff --git a/src/plugins/qmleditor/parser/qmljs.g b/src/plugins/qmleditor/parser/qmljs.g index 211887b4f48..8531ed51079 100644 --- a/src/plugins/qmleditor/parser/qmljs.g +++ b/src/plugins/qmleditor/parser/qmljs.g @@ -1,18 +1,20 @@ ---------------------------------------------------------------------------- -- --- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). --- Contact: Qt Software Information (qt-info@nokia.com) +-- This file is part of Qt Creator -- --- This file is part of the QtDeclarative module of the Qt Toolkit. +-- Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -- --- $QT_BEGIN_LICENSE:LGPL$ --- No Commercial Usage --- This file contains pre-release code and may not be distributed. --- You may use this file in accordance with the terms and conditions --- contained in the either Technology Preview License Agreement or the --- Beta Release License Agreement. +-- 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 @@ -20,25 +22,8 @@ -- ensure the GNU Lesser General Public License version 2.1 requirements -- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -- --- In addition, as a special exception, Nokia gives you certain --- additional rights. These rights are described in the Nokia Qt LGPL --- Exception version 1.0, 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. --- -- If you are unsure which license is appropriate for your use, please --- contact the sales department at qt-sales@nokia.com. --- $QT_END_LICENSE$ --- --- This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE --- WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- contact the sales department at http://qt.nokia.com/contact. -- ---------------------------------------------------------------------------- @@ -100,21 +85,23 @@ %start TopLevel /. -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -122,24 +109,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #include @@ -153,21 +126,23 @@ ./ /: -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -175,24 +150,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ // // W A R N I N G diff --git a/src/plugins/qmleditor/parser/qmljsast.cpp b/src/plugins/qmleditor/parser/qmljsast.cpp index 4c45bc89d9e..ec199e80ae7 100644 --- a/src/plugins/qmleditor/parser/qmljsast.cpp +++ b/src/plugins/qmleditor/parser/qmljsast.cpp @@ -1,18 +1,20 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #include "qmljsast_p.h" #include "qmljsastvisitor_p.h" diff --git a/src/plugins/qmleditor/parser/qmljsast_p.h b/src/plugins/qmleditor/parser/qmljsast_p.h index ef8a66bd949..94a26096ee2 100644 --- a/src/plugins/qmleditor/parser/qmljsast_p.h +++ b/src/plugins/qmleditor/parser/qmljsast_p.h @@ -1,18 +1,20 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSAST_P_H #define QMLJSAST_P_H diff --git a/src/plugins/qmleditor/parser/qmljsastfwd_p.h b/src/plugins/qmleditor/parser/qmljsastfwd_p.h index fcb97ad870a..dd164e9e3c8 100644 --- a/src/plugins/qmleditor/parser/qmljsastfwd_p.h +++ b/src/plugins/qmleditor/parser/qmljsastfwd_p.h @@ -1,18 +1,20 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSAST_FWD_P_H #define QMLJSAST_FWD_P_H diff --git a/src/plugins/qmleditor/parser/qmljsastvisitor.cpp b/src/plugins/qmleditor/parser/qmljsastvisitor.cpp index d3a1d530682..6a0d55a4f16 100644 --- a/src/plugins/qmleditor/parser/qmljsastvisitor.cpp +++ b/src/plugins/qmleditor/parser/qmljsastvisitor.cpp @@ -1,18 +1,20 @@ -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #include "qmljsastvisitor_p.h" diff --git a/src/plugins/qmleditor/parser/qmljsastvisitor_p.h b/src/plugins/qmleditor/parser/qmljsastvisitor_p.h index eea492a0572..09714ee0a0a 100644 --- a/src/plugins/qmleditor/parser/qmljsastvisitor_p.h +++ b/src/plugins/qmleditor/parser/qmljsastvisitor_p.h @@ -1,18 +1,20 @@ -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSASTVISITOR_P_H #define QMLJSASTVISITOR_P_H diff --git a/src/plugins/qmleditor/parser/qmljsengine_p.cpp b/src/plugins/qmleditor/parser/qmljsengine_p.cpp index 7d4d6d7695d..6e7a45a5065 100644 --- a/src/plugins/qmleditor/parser/qmljsengine_p.cpp +++ b/src/plugins/qmleditor/parser/qmljsengine_p.cpp @@ -1,18 +1,20 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #include "qmljsglobal_p.h" #include "qmljsengine_p.h" diff --git a/src/plugins/qmleditor/parser/qmljsengine_p.h b/src/plugins/qmleditor/parser/qmljsengine_p.h index 8627a990243..98e71c88790 100644 --- a/src/plugins/qmleditor/parser/qmljsengine_p.h +++ b/src/plugins/qmleditor/parser/qmljsengine_p.h @@ -1,18 +1,20 @@ -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSENGINE_P_H #define QMLJSENGINE_P_H diff --git a/src/plugins/qmleditor/parser/qmljslexer.cpp b/src/plugins/qmleditor/parser/qmljslexer.cpp index f71b92f0fdb..a52ea7c0896 100644 --- a/src/plugins/qmleditor/parser/qmljslexer.cpp +++ b/src/plugins/qmleditor/parser/qmljslexer.cpp @@ -1,18 +1,20 @@ -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/plugins/qmleditor/parser/qmljslexer_p.h b/src/plugins/qmleditor/parser/qmljslexer_p.h index 50f7c4b279d..1be466c3e62 100644 --- a/src/plugins/qmleditor/parser/qmljslexer_p.h +++ b/src/plugins/qmleditor/parser/qmljslexer_p.h @@ -1,18 +1,20 @@ -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSLEXER_P_H #define QMLJSLEXER_P_H diff --git a/src/plugins/qmleditor/parser/qmljsmemorypool_p.h b/src/plugins/qmleditor/parser/qmljsmemorypool_p.h index 70e77371127..4b79f174fb0 100644 --- a/src/plugins/qmleditor/parser/qmljsmemorypool_p.h +++ b/src/plugins/qmleditor/parser/qmljsmemorypool_p.h @@ -1,18 +1,20 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSMEMORYPOOL_P_H #define QMLJSMEMORYPOOL_P_H diff --git a/src/plugins/qmleditor/parser/qmljsnodepool_p.h b/src/plugins/qmleditor/parser/qmljsnodepool_p.h index dfe3bac4652..ba0c3678efd 100644 --- a/src/plugins/qmleditor/parser/qmljsnodepool_p.h +++ b/src/plugins/qmleditor/parser/qmljsnodepool_p.h @@ -1,18 +1,20 @@ -/**************************************************************************** +/************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,24 +22,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #ifndef QMLJSNODEPOOL_P_H #define QMLJSNODEPOOL_P_H diff --git a/src/plugins/qmleditor/parser/qmljsparser.cpp b/src/plugins/qmleditor/parser/qmljsparser.cpp index e805ce5b6fc..f5fab00f4cc 100644 --- a/src/plugins/qmleditor/parser/qmljsparser.cpp +++ b/src/plugins/qmleditor/parser/qmljsparser.cpp @@ -2,19 +2,21 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -22,24 +24,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ #include diff --git a/src/plugins/qmleditor/parser/qmljsparser_p.h b/src/plugins/qmleditor/parser/qmljsparser_p.h index b35bec32b38..7ee69a57d56 100644 --- a/src/plugins/qmleditor/parser/qmljsparser_p.h +++ b/src/plugins/qmleditor/parser/qmljsparser_p.h @@ -2,19 +2,21 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) +** This file is part of Qt Creator ** -** This file is part of the QtScript module of the Qt Toolkit. +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -22,24 +24,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** ** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ +** contact the sales department at http://qt.nokia.com/contact. ** -****************************************************************************/ +**************************************************************************/ // // W A R N I N G diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp index 6ef0c4dde5b..4b16410e61b 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.cpp @@ -4,7 +4,7 @@ ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** @@ -23,7 +23,7 @@ ** 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 qt-sales@nokia.com. +** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ diff --git a/src/plugins/qt4projectmanager/qt-s60/s60manager.h b/src/plugins/qt4projectmanager/qt-s60/s60manager.h index 08c0be623d5..fe4078583d8 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60manager.h +++ b/src/plugins/qt4projectmanager/qt-s60/s60manager.h @@ -4,7 +4,7 @@ ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** -** Contact: Qt Software Information (qt-info@nokia.com) +** Contact: Nokia Corporation (qt-info@nokia.com) ** ** Commercial Usage ** @@ -23,7 +23,7 @@ ** 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 qt-sales@nokia.com. +** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp index 2c4083ad46f..4c7a31e13bc 100644 --- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp @@ -241,10 +241,10 @@ void Qt4RunConfigurationWidget::updateSummary() { const QString &filename = QFileInfo(m_qt4RunConfiguration->executable()).fileName(); const QString &arguments = ProjectExplorer::Environment::joinArgumentList(m_qt4RunConfiguration->commandLineArguments()); - QString text = tr("Running executable: %1 %2 %3").arg( - filename, - arguments, - m_qt4RunConfiguration->runMode() == LocalApplicationRunConfiguration::Console ? tr("(in terminal)") : ""); + const bool terminal = m_qt4RunConfiguration->runMode() == LocalApplicationRunConfiguration::Console; + const QString text = terminal ? + tr("Running executable: %1 %2 (in terminal)").arg(filename, arguments) : + tr("Running executable: %1 %2").arg(filename, arguments); m_detailsContainer->setSummaryText(text); } diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index fadaf923184..9dea8af0bdc 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -158,6 +158,7 @@ QtVersionManager *QtVersionManager::instance() void QtVersionManager::addVersion(QtVersion *version) { + QTC_ASSERT(version != 0, return); m_versions.append(version); m_uniqueIdToIndex.insert(version->uniqueId(), m_versions.count() - 1); emit qtVersionsChanged(); @@ -166,7 +167,9 @@ void QtVersionManager::addVersion(QtVersion *version) void QtVersionManager::removeVersion(QtVersion *version) { + QTC_ASSERT(version != 0, return); m_versions.removeAll(version); + m_uniqueIdToIndex.remove(version->uniqueId()); emit qtVersionsChanged(); writeVersionsIntoSettings(); delete version; diff --git a/src/shared/cplusplus/Scope.cpp b/src/shared/cplusplus/Scope.cpp index 6c910c072c6..fcb5a68027c 100644 --- a/src/shared/cplusplus/Scope.cpp +++ b/src/shared/cplusplus/Scope.cpp @@ -208,6 +208,21 @@ void Scope::enterSymbol(Symbol *symbol) } } +Symbol *Scope::lookat(Name *name) const +{ + if (! name) + return 0; + + else if (OperatorNameId *opId = name->asOperatorNameId()) + return lookat(opId->kind()); + + else if (Identifier *id = name->identifier()) + return lookat(id); + + else + return 0; +} + Symbol *Scope::lookat(Identifier *id) const { if (! _hash || ! id) diff --git a/src/shared/cplusplus/Scope.h b/src/shared/cplusplus/Scope.h index 5fb9eb3ac7c..1abc41530df 100644 --- a/src/shared/cplusplus/Scope.h +++ b/src/shared/cplusplus/Scope.h @@ -129,6 +129,7 @@ public: /// Returns the last Symbol in the scope. iterator lastSymbol() const; + Symbol *lookat(Name *name) const; Symbol *lookat(Identifier *id) const; Symbol *lookat(int operatorId) const; diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp index 3d3f3c78744..dc80add92b2 100644 --- a/src/shared/cplusplus/Symbol.cpp +++ b/src/shared/cplusplus/Symbol.cpp @@ -314,6 +314,14 @@ void Symbol::setScope(Scope *scope) _scope = scope; } +Symbol *Symbol::enclosingSymbol() const +{ + if (! _scope) + return 0; + + return _scope->owner(); +} + Scope *Symbol::enclosingNamespaceScope() const { if (! _scope) diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h index 511e14c9f21..0857673d3f4 100644 --- a/src/shared/cplusplus/Symbol.h +++ b/src/shared/cplusplus/Symbol.h @@ -281,6 +281,8 @@ public: bool isGenerated() const; + Symbol *enclosingSymbol() const; + /// Returns the eclosing namespace scope. Scope *enclosingNamespaceScope() const; diff --git a/tests/auto/debugger/debugger.pro b/tests/auto/debugger/debugger.pro index c4cadd3715f..ef1547f9ce6 100644 --- a/tests/auto/debugger/debugger.pro +++ b/tests/auto/debugger/debugger.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -SUBDIRS = dumpers.pro plugin.pro +SUBDIRS = dumpers.pro plugin.pro gdb.pro diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index b4ca3723c84..3a3fbef043f 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1195,7 +1195,7 @@ template const QString &sizeStr = N(size); const QByteArray elemTypeStr = typeToString(); QByteArray expected = QByteArray("value='<").append(sizeStr). - append(" items>',valuedisabled='true',numchild='").append(sizeStr). + append(" items>',valueeditable='false',numchild='").append(sizeStr). append("',childtype='").append(elemTypeStr).append("',childnumchild='"). append(typeToNumchild()).append("',children=["); typename QLinkedList::const_iterator iter = l.constBegin(); @@ -1277,13 +1277,13 @@ void tst_Debugger::dumpQLinkedList() QLinkedList l; // Case 1.1: Empty list. - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "childtype='int',childnumchild='0',children=[]", &l, NS"QLinkedList", true, "int"); // Case 1.2: One element. l.append(2); - testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + testDumper("value='<1 items>',valueeditable='false',numchild='1'," "childtype='int',childnumchild='0',children=[{addr='%',value='2'}]" << ptrToBa(l.constBegin().operator->()), &l, NS"QLinkedList", true, "int"); @@ -1292,7 +1292,7 @@ void tst_Debugger::dumpQLinkedList() l.append(3); QByteArray it0 = ptrToBa(l.constBegin().operator->()); QByteArray it1 = ptrToBa(l.constBegin().operator++().operator->()); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "childtype='int',childnumchild='0',children=[{addr='%',value='2'}," "{addr='%',value='3'}]" << it0 << it1, &l, NS"QLinkedList", true, "int"); @@ -1302,7 +1302,7 @@ void tst_Debugger::dumpQLinkedList() QLinkedList::const_iterator iter; // Case 2.1: Empty list. - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "childtype='"NS"QString',childnumchild='0',children=[]", &l2, NS"QLinkedList", true, NS"QString"); @@ -1310,13 +1310,13 @@ void tst_Debugger::dumpQLinkedList() l2.append("Teststring 1"); iter = l2.constBegin(); qDebug() << *iter; - testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + testDumper("value='<1 items>',valueeditable='false',numchild='1'," "childtype='"NS"QString',childnumchild='0',children=[{addr='%',value='%',}]" << ptrToBa(iter.operator->()) << utfToBase64(*iter), &l2, NS"QLinkedList", true, NS"QString"); // Case 2.3: Two elements. - QByteArray expected = "value='<2 items>',valuedisabled='true',numchild='2'," + QByteArray expected = "value='<2 items>',valueeditable='false',numchild='2'," "childtype='int',childnumchild='0',children=["; iter = l2.constBegin(); expected.append("{addr='%',%}," @@ -1331,7 +1331,7 @@ void tst_Debugger::dumpQLinkedList() for (int i = 3; i <= 1002; ++i) l2.append("Test " + N(i)); - expected = "value='<1002 items>',valuedisabled='true'," + expected = "value='<1002 items>',valueeditable='false'," "numchild='1002',childtype='"NS"QString',childnumchild='0',children=['"; iter = l2.constBegin(); for (int i = 0; i < 1002; ++i, ++iter) @@ -1354,12 +1354,12 @@ void tst_Debugger::dumpQLinkedList() void tst_Debugger::dumpQList_int() { QList ilist; - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "internal='1',children=[]", &ilist, NS"QList", true, "int"); ilist.append(1); ilist.append(2); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "internal='1',childtype='int',childnumchild='0',children=[" "{addr='" + str(&ilist.at(0)) + "',value='1'}," "{addr='" + str(&ilist.at(1)) + "',value='2'}]", @@ -1369,12 +1369,12 @@ void tst_Debugger::dumpQList_int() void tst_Debugger::dumpQList_char() { QList clist; - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "internal='1',children=[]", &clist, NS"QList", true, "char"); clist.append('a'); clist.append('b'); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "internal='1',childtype='char',childnumchild='0',children=[" "{addr='" + str(&clist.at(0)) + "',value=''a', ascii=97'}," "{addr='" + str(&clist.at(1)) + "',value=''b', ascii=98'}]", @@ -1384,12 +1384,12 @@ void tst_Debugger::dumpQList_char() void tst_Debugger::dumpQList_QString() { QList slist; - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "internal='1',children=[]", &slist, NS"QList", true, NS"QString"); slist.append("a"); slist.append("b"); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "internal='1',childtype='"NS"QString',childnumchild='0',children=[" "{addr='" + str(&slist.at(0)) + "',value='YQA=',valueencoded='2'}," "{addr='" + str(&slist.at(1)) + "',value='YgA=',valueencoded='2'}]", @@ -1399,12 +1399,12 @@ void tst_Debugger::dumpQList_QString() void tst_Debugger::dumpQList_Int3() { QList i3list; - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "internal='0',children=[]", &i3list, NS"QList", true, "Int3"); i3list.append(Int3()); i3list.append(Int3()); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "internal='0',childtype='Int3',children=[" "{addr='" + str(&i3list.at(0)) + "'}," "{addr='" + str(&i3list.at(1)) + "'}]", @@ -1414,12 +1414,12 @@ void tst_Debugger::dumpQList_Int3() void tst_Debugger::dumpQList_QString3() { QList s3list; - testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + testDumper("value='<0 items>',valueeditable='false',numchild='0'," "internal='0',children=[]", &s3list, NS"QList", true, "QString3"); s3list.append(QString3()); s3list.append(QString3()); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "internal='0',childtype='QString3',children=[" "{addr='" + str(&s3list.at(0)) + "'}," "{addr='" + str(&s3list.at(1)) + "'}]", @@ -1819,6 +1819,7 @@ void tst_Debugger::dumpQObjectSignalHelper(QObject &o, int sigNum) connLists != 0 && connLists->size() > sigNum ? connLists->at(sigNum) : QObjectPrivate::ConnectionList(); int i = 0; + // FIXME: 4.6 only for (QObjectPrivate::Connection *conn = connList.first; conn != 0; ++i, conn = conn->nextConnectionList) { const QString iStr = N(i); @@ -2137,7 +2138,7 @@ void tst_Debugger::dumpQSharedPointerHelper(QSharedPointer &ptr) weakAddr = strongAddr = 0; weakValue = strongValue = 0; } - expected.append(val2).append("',valuedisabled='true',numchild='1',children=["). + expected.append(val2).append("',valueeditable='false',numchild='1',children=["). append("{name='data',addr='").append(ptrToBa(ptr.data())). append("',type='").append(typeToString()).append("',value='").append(val1). append("'},{name='weakref',value='").append(N(weakValue)). @@ -2236,18 +2237,18 @@ void tst_Debugger::dumpStdVector() std::vector *> vector; QByteArray inner = "std::list *"; QByteArray innerp = "std::list"; - testDumper("value='<0 items>',valuedisabled='true',numchild='0'", + testDumper("value='<0 items>',valueeditable='false',numchild='0'", &vector, "std::vector", false, inner, "", sizeof(std::list *)); std::list list; vector.push_back(new std::list(list)); - testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + testDumper("value='<1 items>',valueeditable='false',numchild='1'," "childtype='" + inner + "',childnumchild='1'," "children=[{addr='" + str(deref(&vector[0])) + "'," "saddr='" + str(deref(&vector[0])) + "',type='" + innerp + "'}]", &vector, "std::vector", true, inner, "", sizeof(std::list *)); vector.push_back(0); list.push_back(45); - testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + testDumper("value='<2 items>',valueeditable='false',numchild='2'," "childtype='" + inner + "',childnumchild='1'," "children=[{addr='" + str(deref(&vector[0])) + "'," "saddr='" + str(deref(&vector[0])) + "',type='" + innerp + "'}," @@ -2297,7 +2298,7 @@ void tst_Debugger::dumpQWeakPointerHelper(QWeakPointer &ptr) QByteArray expected("value='"); if (isSimpleType()) expected.append(dataStr); - expected.append("',valuedisabled='true',numchild='1',children=[{name='data',addr='"). + expected.append("',valueeditable='false',numchild='1',children=[{name='data',addr='"). append(ptrToBa(data)).append("',type='").append(typeToString()). append("',value='").append(dataStr).append("'},{name='weakref',value='"). append(valToString(*weakRefPtr)).append("',type='int',addr='"). @@ -2316,7 +2317,7 @@ void tst_Debugger::dumpQWeakPointer() // Case 1.1: Null pointer. QSharedPointer spNull; QWeakPointer wp = spNull.toWeakRef(); - testDumper("value='',valuedisabled='true',numchild='0'", + testDumper("value='',valueeditable='false',numchild='0'", &wp, NS"QWeakPointer", true, "int"); // Case 1.2: Weak pointer is unique. diff --git a/tests/auto/debugger/tst_gdb.cpp b/tests/auto/debugger/tst_gdb.cpp new file mode 100644 index 00000000000..9310016b4b5 --- /dev/null +++ b/tests/auto/debugger/tst_gdb.cpp @@ -0,0 +1,2324 @@ + +#include +#include +#include + +#include + +#include +#include + +#include + +#include "gdb/gdbmi.h" + +#include +#include + + +#undef NS +#ifdef QT_NAMESPACE +# define STRINGIFY0(s) #s +# define STRINGIFY1(s) STRINGIFY0(s) +# define NS STRINGIFY1(QT_NAMESPACE) "::" +# define NSX "'" STRINGIFY1(QT_NAMESPACE) "::" +# define NSY "'" +#else +# define NS "" +# define NSX "" +# define NSY "" +#endif + +#define gettid() QString("0x%1").arg((qulonglong)(void *)currentThread(), 0, 16) + +using namespace Debugger; +using namespace Debugger::Internal; + +typedef QList QByteArrayList; + +static QByteArray operator<<(QByteArray ba, const QByteArray &replacement) +{ + int pos = ba.indexOf('%'); + Q_ASSERT(pos != -1); + return ba.replace(pos, 1, replacement); +} + +static QByteArray &operator<<=(QByteArray &ba, const QByteArray &replacement) +{ + int pos = ba.indexOf('%'); + Q_ASSERT(pos != -1); + return ba.replace(pos, 1, replacement); +} + + +template +inline QByteArray N(T t) { return QByteArray::number(t); } + + + +struct Int3 { + Int3() { i1 = 42; i2 = 43; i3 = 44; } + int i1, i2, i3; +}; + +struct QString3 { + QString3() { s1 = "a"; s2 = "b"; s3 = "c"; } + QString s1, s2, s3; +}; + +class tst_Gdb; + +class Thread : public QThread +{ + Q_OBJECT + +public: + Thread(tst_Gdb *test); + void run(); + +public slots: + void readStandardOutput(); + void readStandardError(); + void handleGdbStarted(); + void handleGdbError(QProcess::ProcessError); + void handleGdbFinished(int, QProcess::ExitStatus); + void writeToGdbRequested(const QByteArray &ba) + { + //qDebug() << "THREAD GDB IN: " << ba; + m_proc->write(ba); + m_proc->write("\n"); + } + + +public: + QByteArray m_output; + QByteArray m_error; + QProcess *m_proc; // owned + tst_Gdb *m_test; // not owned +}; + +class tst_Gdb : public QObject +{ + Q_OBJECT + +public: + tst_Gdb() : m_thread(this) {} + +public slots: + void dumperCompatibility(); + void dumpQAbstractItemAndModelIndex(); + void dumpQAbstractItemModel(); + void dumpQByteArray(); + void dumpQChar(); + void dumpQDateTime(); + void dumpQDir(); + void dumpQFile(); + void dumpQFileInfo(); + void dumpQHash(); + void dumpQHashNode(); + void dumpQImage(); + void dumpQImageData(); + void dumpQLinkedList(); + void dumpQList_int(); + void dumpQList_char(); + void dumpQList_QString(); + void dumpQList_QString3(); + void dumpQList_Int3(); + void dumpQLocale(); + void dumpQMap(); + void dumpQMapNode(); + void dumpQObject(); + void dumpQObjectChildList(); + void dumpQObjectMethodList(); + void dumpQObjectPropertyList(); + void dumpQObjectSignal(); + void dumpQObjectSignalList(); + void dumpQObjectSlot(); + void dumpQObjectSlotList(); + void dumpQPixmap(); + void dumpQSharedPointer(); + void dumpQTextCodec(); + void dumpQVariant_invalid(); + void dumpQVariant_QString(); + void dumpQVariant_QStringList(); + void dumpStdVector(); + void dumpQWeakPointer(); + void initTestCase(); + void cleanupTestCase(); + void runTestCase(const QByteArray &name, + const QByteArray &type, + const QByteArrayList &expexted); + +signals: + void writeToGdb(const QByteArray &ba); + +private slots: + void dumpQString(); + void dumpQStringList(); + +private: + void dumpQAbstractItemHelper(QModelIndex &index); + void dumpQAbstractItemModelHelper(QAbstractItemModel &m); + void dumpQDateTimeHelper(const QDateTime &d); + void dumpQFileHelper(const QString &name, bool exists); + template void dumpQHashNodeHelper(QHash &hash); + void dumpQImageHelper(const QImage &img); + void dumpQImageDataHelper(QImage &img); + template void dumpQLinkedListHelper(QLinkedList &l); + void dumpQLocaleHelper(QLocale &loc); + template void dumpQMapHelper(QMap &m); + template void dumpQMapNodeHelper(QMap &m); + void dumpQObjectChildListHelper(QObject &o); + void dumpQObjectSignalHelper(QObject &o, int sigNum); +#if QT_VERSION >= 0x040500 + template + void dumpQSharedPointerHelper(QSharedPointer &ptr); + template + void dumpQWeakPointerHelper(QWeakPointer &ptr); +#endif + void dumpQTextCodecHelper(QTextCodec *codec); + +private: + Thread m_thread; +}; + +QMutex m_mutex; +QWaitCondition m_waitCondition; + +// +// Dumpers +// + +static void testDumper(QByteArray expected, const void *data, QByteArray outertype, + bool dumpChildren, QByteArray actual____ = QByteArray(), + QByteArray = QByteArray(), int = 0, int = 0, int = 0, int = 0) +{ + Q_UNUSED(dumpChildren); + expected = "locals={iname='local',name='Locals',value=' ',type=' '," + "children=[" + expected + "],arg=''}"; + char buf[100]; + sprintf(buf, "%p", data); + //if ((!expected.startsWith('t') && !expected.startsWith('f')) + // || expected.startsWith("type")) + // expected = "tiname='$I',addr='$A'," + expected; + expected.replace("$I", "iname"); + expected.replace("$T", QByteArray(outertype)); + expected.replace("$A", QByteArray(buf)); + if (actual____ != expected) { + QByteArrayList l1 = actual____.split(','); + QByteArrayList l2 = expected.split(','); + for (int i = 0; i < l1.size() && i < l2.size(); ++i) { + if (l1.at(i) == l2.at(i)) + qWarning() << "== " << l1.at(i); + else + //qWarning() << "!= " << l1.at(i).right(30) << l2.at(i).right(30); + qWarning() << "!= " << l1.at(i) << l2.at(i); + } + if (l1.size() != l2.size()) + qWarning() << "!= size: " << l1.size() << l2.size(); + } + QCOMPARE(actual____, expected); +} + +QByteArray str(const void *p) +{ + char buf[100]; + sprintf(buf, "%p", p); + return buf; +} + +static const void *deref(const void *p) +{ + return *reinterpret_cast(p); +} + +void tst_Gdb::dumperCompatibility() +{ + // Ensure that no arbitrary padding is introduced by QVectorTypedData. + const size_t qVectorDataSize = 16; + QCOMPARE(sizeof(QVectorData), qVectorDataSize); + QVectorTypedData *v = 0; + QCOMPARE(size_t(&v->array), qVectorDataSize); +} + +static const QByteArray utfToBase64(const QString &string) +{ + return QByteArray(reinterpret_cast(string.utf16()), 2 * string.size()).toBase64(); +} + +static const char *boolToVal(bool b) +{ + return b ? "'true'" : "'false'"; +} + +static const QByteArray ptrToBa(const void *p, bool symbolicNull = true) +{ + return QByteArray().append(p == 0 && symbolicNull ? + "" : + QByteArray("0x") + QByteArray::number((quintptr) p, 16)); +} + +static const QByteArray generateQStringSpec(const QString &str) +{ + return QByteArray("value='%',type='"NS"QString',numchild='0',valueencoded='2'") + << utfToBase64(str); +} + +static const QByteArray generateQCharSpec(const QChar& ch) +{ + return QByteArray("value='%',valueencoded='2',type='"NS"QChar',numchild='0'") + << utfToBase64(QString(QLatin1String("'%1' (%2, 0x%3)")). + arg(ch).arg(ch.unicode()).arg(ch.unicode(), 0, 16)); +} + +static const QByteArray generateBoolSpec(bool b) +{ + return QByteArray("value=%,type='bool',numchild='0'") + << boolToVal(b); +} + +static const QByteArray generateLongSpec(long n) +{ + return QByteArray("value='%',type='long',numchild='0'") + << N(qlonglong(n)); +} + +static const QByteArray generateIntSpec(int n) +{ + return QByteArray("value='%',type='int',numchild='0'") + << N(n); +} + +const QByteArray createExp(const void *ptr, + const QByteArray &type, const QByteArray &method) +{ + return QByteArray("exp='(("NSX"%"NSY"*)%)->%'") + << type << ptrToBa(ptr) << method; +} + +// Helper functions. + +#ifdef Q_CC_MSVC +# define MAP_NODE_TYPE_END ">" +#else +# define MAP_NODE_TYPE_END " >" +#endif + +template static const char *typeToString() +{ + return ""; +} +template const QByteArray valToString(const T &) +{ + return ""; +} +template <> const QByteArray valToString(const int &n) +{ + return QByteArray().append(N(n)); +} +template <> const QByteArray valToString(const QString &s) +{ + return QByteArray(utfToBase64(s)).append("',valueencoded='2"); +} +template <> const QByteArray valToString(int * const &p) +{ + return ptrToBa(p); +} +template const QByteArray derefValToString(const T &v) +{ + return valToString(v); +} +template <> const QByteArray derefValToString(int * const &ptr) +{ + return valToString(*ptr); +} +const QString stripPtrType(const QString &ptrTypeStr) +{ + return ptrTypeStr.mid(0, ptrTypeStr.size() - 2); +} +template <> const char *typeToString() +{ + return "int"; +} +template <> const char *typeToString() +{ + return NS"QString"; +} +template <> const char *typeToString() +{ + return "int *"; +} +template bool isSimpleType() +{ + return false; +} +template <> bool isSimpleType() +{ + return true; +} +template bool isPointer() +{ + return false; +} +template <> bool isPointer() +{ + return true; +} + +template static const char *typeToNumchild() +{ + return "1"; +} +template <> const char *typeToNumchild() +{ + return "0"; +} +template <> const char *typeToNumchild() +{ + return "0"; +} +template +QByteArray getMapType() +{ + return QByteArray(typeToString()) + "@" + QByteArray(typeToString()); +} +template +void getMapNodeParams(size_t &nodeSize, size_t &valOffset) +{ +#if QT_VERSION >= 0x040500 + typedef QMapNode NodeType; + NodeType *node = 0; + nodeSize = sizeof(NodeType); + valOffset = size_t(&node->value); +#else + nodeSize = sizeof(K) + sizeof(V) + 2*sizeof(void *); + valOffset = sizeof(K); +#endif +} + +void tst_Gdb::dumpQAbstractItemHelper(QModelIndex &index) +{ + const QAbstractItemModel *model = index.model(); + const QString &rowStr = N(index.row()); + const QString &colStr = N(index.column()); + const QByteArray &internalPtrStrSymbolic = ptrToBa(index.internalPointer()); + const QByteArray &internalPtrStrValue = ptrToBa(index.internalPointer(), false); + const QByteArray &modelPtrStr = ptrToBa(model); + QByteArray indexSpecSymbolic = QByteArray().append(rowStr + "," + colStr + ","). + append(internalPtrStrSymbolic + "," + modelPtrStr); + QByteArray indexSpecValue = QByteArray().append(rowStr + "," + colStr + ","). + append(internalPtrStrValue + "," + modelPtrStr); + QByteArray expected = QByteArray("tiname='iname',addr='").append(ptrToBa(&index)). + append("',type='"NS"QAbstractItem',addr='$").append(indexSpecSymbolic). + append("',value='").append(valToString(model->data(index).toString())). + append("',numchild='1',children=["); + int rowCount = model->rowCount(index); + int columnCount = model->columnCount(index); + for (int row = 0; row < rowCount; ++row) { + for (int col = 0; col < columnCount; ++col) { + const QModelIndex &childIndex = model->index(row, col, index); + expected.append("{name='[").append(valToString(row)).append(","). + append(N(col)).append("]',numchild='1',addr='$"). + append(N(childIndex.row())).append(","). + append(N(childIndex.column())).append(","). + append(ptrToBa(childIndex.internalPointer())).append(","). + append(modelPtrStr).append("',type='"NS"QAbstractItem',value='"). + append(valToString(model->data(childIndex).toString())).append("'}"); + if (col < columnCount - 1 || row < rowCount - 1) + expected.append(","); + } + } + expected.append("]"); + testDumper(expected, &index, NS"QAbstractItem", true, indexSpecValue); +} + +void tst_Gdb::dumpQAbstractItemAndModelIndex() +{ + class PseudoTreeItemModel : public QAbstractItemModel + { + public: + PseudoTreeItemModel() : QAbstractItemModel(), parent1(0), + parent1Child(1), parent2(10), parent2Child1(11), parent2Child2(12) + {} + + int columnCount(const QModelIndex &parent = QModelIndex()) const + { + Q_UNUSED(parent); + return 1; + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + return !index.isValid() || role != Qt::DisplayRole ? + QVariant() : *static_cast(index.internalPointer()); + } + + QModelIndex index(int row, int column, + const QModelIndex & parent = QModelIndex()) const + { + QModelIndex index; + if (column == 0) { + if (!parent.isValid()) { + if (row == 0) + index = createIndex(row, column, &parent1); + else if (row == 1) + index = createIndex(row, column, &parent2); + } else if (parent.internalPointer() == &parent1 && row == 0) { + index = createIndex(row, column, &parent1Child); + } else if (parent.internalPointer() == &parent2) { + index = createIndex(row, column, + row == 0 ? &parent2Child1 : &parent2Child2); + } + } + return index; + } + + QModelIndex parent(const QModelIndex & index) const + { + QModelIndex parent; + if (index.isValid()) { + if (index.internalPointer() == &parent1Child) + parent = createIndex(0, 0, &parent1); + else if (index.internalPointer() == &parent2Child1 || + index.internalPointer() == &parent2Child2) + parent = createIndex(1, 0, &parent2); + } + return parent; + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + int rowCount; + if (!parent.isValid() || parent.internalPointer() == &parent2) + rowCount = 2; + else if (parent.internalPointer() == &parent1) + rowCount = 1; + else + rowCount = 0; + return rowCount; + } + + private: + mutable int parent1; + mutable int parent1Child; + mutable int parent2; + mutable int parent2Child1; + mutable int parent2Child2; + }; + + PseudoTreeItemModel m2; + + // Case 1: ModelIndex with no children. + QStringListModel m(QStringList() << "item1" << "item2" << "item3"); + QModelIndex index = m.index(2, 0); + + testDumper(QByteArray("type='$T',value='(2, 0)',numchild='5',children=[" + "{name='row',value='2',type='int',numchild='0'}," + "{name='column',value='0',type='int',numchild='0'}," + "{name='parent',value='',exp='(('$T'*)$A)->parent()'," + "type='$T',numchild='1'}," + "{name='internalId',%}," + "{name='model',value='%',type='"NS"QAbstractItemModel*'," + "numchild='1'}]") + << generateQStringSpec(N(index.internalId())) + << ptrToBa(&m), + &index, NS"QModelIndex", true); + + // Case 2: ModelIndex with one child. + QModelIndex index2 = m2.index(0, 0); + dumpQAbstractItemHelper(index2); + + qDebug() << "FIXME: invalid indices should not have children"; + testDumper(QByteArray("type='$T',value='(0, 0)',numchild='5',children=[" + "{name='row',value='0',type='int',numchild='0'}," + "{name='column',value='0',type='int',numchild='0'}," + "{name='parent',value='',exp='(('$T'*)$A)->parent()'," + "type='$T',numchild='1'}," + "{name='internalId',%}," + "{name='model',value='%',type='"NS"QAbstractItemModel*'," + "numchild='1'}]") + << generateQStringSpec(N(index2.internalId())) + << ptrToBa(&m2), + &index2, NS"QModelIndex", true); + + + // Case 3: ModelIndex with two children. + QModelIndex index3 = m2.index(1, 0); + dumpQAbstractItemHelper(index3); + + testDumper(QByteArray("type='$T',value='(1, 0)',numchild='5',children=[" + "{name='row',value='1',type='int',numchild='0'}," + "{name='column',value='0',type='int',numchild='0'}," + "{name='parent',value='',exp='(('$T'*)$A)->parent()'," + "type='$T',numchild='1'}," + "{name='internalId',%}," + "{name='model',value='%',type='"NS"QAbstractItemModel*'," + "numchild='1'}]") + << generateQStringSpec(N(index3.internalId())) + << ptrToBa(&m2), + &index3, NS"QModelIndex", true); + + + // Case 4: ModelIndex with a parent. + index = m2.index(0, 0, index3); + testDumper(QByteArray("type='$T',value='(0, 0)',numchild='5',children=[" + "{name='row',value='0',type='int',numchild='0'}," + "{name='column',value='0',type='int',numchild='0'}," + "{name='parent',value='(1, 0)',exp='(('$T'*)$A)->parent()'," + "type='$T',numchild='1'}," + "{name='internalId',%}," + "{name='model',value='%',type='"NS"QAbstractItemModel*'," + "numchild='1'}]") + << generateQStringSpec(N(index.internalId())) + << ptrToBa(&m2), + &index, NS"QModelIndex", true); + + + // Case 5: Empty ModelIndex + QModelIndex index4; + testDumper("type='$T',value='',numchild='0'", + &index4, NS"QModelIndex", true); +} + +void tst_Gdb::dumpQAbstractItemModelHelper(QAbstractItemModel &m) +{ + QByteArray address = ptrToBa(&m); + QByteArray expected = QByteArray("tiname='iname',addr='%'," + "type='"NS"QAbstractItemModel',value='(%,%)',numchild='1',children=[" + "{numchild='1',name='"NS"QObject',addr='%',value='%'," + "valueencoded='2',type='"NS"QObject',displayedtype='%'}") + << address + << N(m.rowCount()) + << N(m.columnCount()) + << address + << utfToBase64(m.objectName()) + << m.metaObject()->className(); + + for (int row = 0; row < m.rowCount(); ++row) { + for (int column = 0; column < m.columnCount(); ++column) { + QModelIndex mi = m.index(row, column); + expected.append(QByteArray(",{name='[%,%]',value='%'," + "valueencoded='2',numchild='1',addr='$%,%,%,%'," + "type='"NS"QAbstractItem'}") + << N(row) + << N(column) + << utfToBase64(m.data(mi).toString()) + << N(mi.row()) + << N(mi.column()) + << ptrToBa(mi.internalPointer()) + << ptrToBa(mi.model())); + } + } + expected.append("]"); + testDumper(expected, &m, NS"QAbstractItemModel", true); +} + +void tst_Gdb::dumpQAbstractItemModel() +{ + // Case 1: No rows, one column. + QStringList strList; + QStringListModel model(strList); + dumpQAbstractItemModelHelper(model); + + // Case 2: One row, one column. + strList << "String 1"; + model.setStringList(strList); + dumpQAbstractItemModelHelper(model); + + // Case 3: Two rows, one column. + strList << "String 2"; + model.setStringList(strList); + dumpQAbstractItemModelHelper(model); + + // Case 4: No rows, two columns. + QStandardItemModel model2(0, 2); + dumpQAbstractItemModelHelper(model2); + + // Case 5: One row, two columns. + QStandardItem item1("Item (0,0)"); + QStandardItem item2("(Item (0,1)"); + model2.appendRow(QList() << &item1 << &item2); + dumpQAbstractItemModelHelper(model2); + + // Case 6: Two rows, two columns + QStandardItem item3("Item (1,0"); + QStandardItem item4("Item (1,1)"); + model2.appendRow(QList() << &item3 << &item4); + dumpQAbstractItemModelHelper(model); +} + +void tst_Gdb::dumpQByteArray() +{ + // Case 1: Empty object. + QByteArray ba; + testDumper("value='',valueencoded='1',type='"NS"QByteArray',numchild='0'," + "childtype='char',childnumchild='0',children=[]", + &ba, NS"QByteArray", true); + + // Case 2: One element. + ba.append('a'); + testDumper("value='YQ==',valueencoded='1',type='"NS"QByteArray',numchild='1'," + "childtype='char',childnumchild='0',children=[{value='61 (97 'a')'}]", + &ba, NS"QByteArray", true); + + // Case 3: Two elements. + ba.append('b'); + testDumper("value='YWI=',valueencoded='1',type='"NS"QByteArray',numchild='2'," + "childtype='char',childnumchild='0',children=[" + "{value='61 (97 'a')'},{value='62 (98 'b')'}]", + &ba, NS"QByteArray", true); + + // Case 4: > 100 elements. + ba = QByteArray(101, 'a'); + QByteArray children; + for (int i = 0; i < 101; i++) + children.append("{value='61 (97 'a')'},"); + children.chop(1); + testDumper(QByteArray("value='YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh" + "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFh" + "YWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ== '," + "valueencoded='1',type='"NS"QByteArray',numchild='101'," + "childtype='char',childnumchild='0',children=[%]") << children, + &ba, NS"QByteArray", true); + + // Case 5: Regular and special characters and the replacement character. + ba = QByteArray("abc\a\n\r\e\'\"?"); + testDumper("value='YWJjBwoNGyciPw==',valueencoded='1',type='"NS"QByteArray'," + "numchild='10',childtype='char',childnumchild='0',children=[" + "{value='61 (97 'a')'},{value='62 (98 'b')'}," + "{value='63 (99 'c')'},{value='07 (7 '?')'}," + "{value='0a (10 '?')'},{value='0d (13 '?')'}," + "{value='1b (27 '?')'},{value='27 (39 '?')'}," + "{value='22 (34 '?')'},{value='3f (63 '?')'}]", + &ba, NS"QByteArray", true); +} + +void tst_Gdb::dumpQChar() +{ + // Case 1: Printable ASCII character. + QChar c('X'); + testDumper("value=''X', ucs=88',numchild='0'", + &c, NS"QChar", false); + + // Case 2: Printable non-ASCII character. + c = QChar(0x600); + testDumper("value=''?', ucs=1536',numchild='0'", + &c, NS"QChar", false); + + // Case 3: Non-printable ASCII character. + c = QChar::fromAscii('\a'); + testDumper("value=''?', ucs=7',numchild='0'", + &c, NS"QChar", false); + + // Case 4: Non-printable non-ASCII character. + c = QChar(0x9f); + testDumper("value=''?', ucs=159',numchild='0'", + &c, NS"QChar", false); + + // Case 5: Printable ASCII Character that looks like the replacement character. + c = QChar::fromAscii('?'); + testDumper("value=''?', ucs=63',numchild='0'", + &c, NS"QChar", false); +} + +void tst_Gdb::dumpQDateTimeHelper(const QDateTime &d) +{ + QByteArray value; + if (d.isNull()) + value = "value='(null)'"; + else + value = QByteArray("value='%',valueencoded='2'") + << utfToBase64(d.toString()); + + QByteArray expected = QByteArray("%,type='$T',numchild='3',children=[" + "{name='isNull',%}," + "{name='toTime_t',%}," + "{name='toString',%}," + "{name='toString_(ISO)',%}," + "{name='toString_(SystemLocale)',%}," + "{name='toString_(Locale)',%}]") + << value + << generateBoolSpec(d.isNull()) + << generateLongSpec((d.toTime_t())) + << generateQStringSpec(d.toString()) + << generateQStringSpec(d.toString(Qt::ISODate)) + << generateQStringSpec(d.toString(Qt::SystemLocaleDate)) + << generateQStringSpec(d.toString(Qt::LocaleDate)); + testDumper(expected, &d, NS"QDateTime", true); +} + +void tst_Gdb::dumpQDateTime() +{ + // Case 1: Null object. + QDateTime d; + dumpQDateTimeHelper(d); + + // Case 2: Non-null object. + d = QDateTime::currentDateTime(); + dumpQDateTimeHelper(d); +} + +void tst_Gdb::dumpQDir() +{ + // Case 1: Current working directory. + QDir dir = QDir::current(); + testDumper(QByteArray("value='%',valueencoded='2',type='"NS"QDir',numchild='3'," + "children=[{name='absolutePath',%},{name='canonicalPath',%}]") + << utfToBase64(dir.absolutePath()) + << generateQStringSpec(dir.absolutePath()) + << generateQStringSpec(dir.canonicalPath()), + &dir, NS"QDir", true); + + // Case 2: Root directory. + dir = QDir::root(); + testDumper(QByteArray("value='%',valueencoded='2',type='"NS"QDir',numchild='3'," + "children=[{name='absolutePath',%},{name='canonicalPath',%}]") + << utfToBase64(dir.absolutePath()) + << generateQStringSpec(dir.absolutePath()) + << generateQStringSpec(dir.canonicalPath()), + &dir, NS"QDir", true); +} + +void tst_Gdb::dumpQFileHelper(const QString &name, bool exists) +{ + QFile file(name); + QByteArray filenameAsBase64 = utfToBase64(name); + testDumper(QByteArray("value='%',valueencoded='2',type='$T',numchild='2'," + "children=[{name='fileName',value='%',type='"NS"QString'," + "numchild='0',valueencoded='2'}," + "{name='exists',value=%,type='bool',numchild='0'}]") + << filenameAsBase64 << filenameAsBase64 << boolToVal(exists), + &file, NS"QFile", true); +} + +void tst_Gdb::dumpQFile() +{ + // Case 1: Empty file name => Does not exist. + dumpQFileHelper("", false); + + // Case 2: File that is known to exist. + QTemporaryFile file; + file.open(); + dumpQFileHelper(file.fileName(), true); + + // Case 3: File with a name that most likely does not exist. + dumpQFileHelper("jfjfdskjdflsdfjfdls", false); +} + +void tst_Gdb::dumpQFileInfo() +{ + QFileInfo fi("."); + QByteArray expected("value='%',valueencoded='2',type='$T',numchild='3'," + "children=[" + "{name='absolutePath',%}," + "{name='absoluteFilePath',%}," + "{name='canonicalPath',%}," + "{name='canonicalFilePath',%}," + "{name='completeBaseName',%}," + "{name='completeSuffix',%}," + "{name='baseName',%}," +#ifdef QX + "{name='isBundle',%}," + "{name='bundleName',%}," +#endif + "{name='fileName',%}," + "{name='filePath',%}," + "{name='group',%}," + "{name='owner',%}," + "{name='path',%}," + "{name='groupid',%}," + "{name='ownerid',%}," + "{name='permissions',%}," + "{name='caching',%}," + "{name='exists',%}," + "{name='isAbsolute',%}," + "{name='isDir',%}," + "{name='isExecutable',%}," + "{name='isFile',%}," + "{name='isHidden',%}," + "{name='isReadable',%}," + "{name='isRelative',%}," + "{name='isRoot',%}," + "{name='isSymLink',%}," + "{name='isWritable',%}," + "{name='created',value='%',valueencoded='2',%," + "type='"NS"QDateTime',numchild='1'}," + "{name='lastModified',value='%',valueencoded='2',%," + "type='"NS"QDateTime',numchild='1'}," + "{name='lastRead',value='%',valueencoded='2',%," + "type='"NS"QDateTime',numchild='1'}]"); + + expected <<= utfToBase64(fi.filePath()); + expected <<= generateQStringSpec(fi.absolutePath()); + expected <<= generateQStringSpec(fi.absoluteFilePath()); + expected <<= generateQStringSpec(fi.canonicalPath()); + expected <<= generateQStringSpec(fi.canonicalFilePath()); + expected <<= generateQStringSpec(fi.completeBaseName()); + expected <<= generateQStringSpec(fi.completeSuffix()); + expected <<= generateQStringSpec(fi.baseName()); +#ifdef Q_OS_MACX + expected <<= generateBoolSpec(fi.isBundle()); + expected <<= generateQStringSpec(fi.bundleName()); +#endif + expected <<= generateQStringSpec(fi.fileName()); + expected <<= generateQStringSpec(fi.filePath()); + expected <<= generateQStringSpec(fi.group()); + expected <<= generateQStringSpec(fi.owner()); + expected <<= generateQStringSpec(fi.path()); + expected <<= generateLongSpec(fi.groupId()); + expected <<= generateLongSpec(fi.ownerId()); + expected <<= generateLongSpec(fi.permissions()); + expected <<= generateBoolSpec(fi.caching()); + expected <<= generateBoolSpec(fi.exists()); + expected <<= generateBoolSpec(fi.isAbsolute()); + expected <<= generateBoolSpec(fi.isDir()); + expected <<= generateBoolSpec(fi.isExecutable()); + expected <<= generateBoolSpec(fi.isFile()); + expected <<= generateBoolSpec(fi.isHidden()); + expected <<= generateBoolSpec(fi.isReadable()); + expected <<= generateBoolSpec(fi.isRelative()); + expected <<= generateBoolSpec(fi.isRoot()); + expected <<= generateBoolSpec(fi.isSymLink()); + expected <<= generateBoolSpec(fi.isWritable()); + expected <<= utfToBase64(fi.created().toString()); + expected <<= createExp(&fi, "QFileInfo", "created()"); + expected <<= utfToBase64(fi.lastModified().toString()); + expected <<= createExp(&fi, "QFileInfo", "lastModified()"); + expected <<= utfToBase64(fi.lastRead().toString()); + expected <<= createExp(&fi, "QFileInfo", "lastRead()"); + + testDumper(expected, &fi, NS"QFileInfo", true); +} + +void tst_Gdb::dumpQHash() +{ + QHash > hash; + hash.insert("Hallo", QList()); + hash.insert("Welt", QList() << 1); + hash.insert("!", QList() << 1 << 2); + hash.insert("!", QList() << 1 << 2); +} + +template +void tst_Gdb::dumpQHashNodeHelper(QHash &hash) +{ + typename QHash::iterator it = hash.begin(); + typedef QHashNode HashNode; + HashNode *dummy = 0; + HashNode *node = + reinterpret_cast(reinterpret_cast(const_cast(&it.key())) - + size_t(&dummy->key)); + const K &key = it.key(); + const V &val = it.value(); + QByteArray expected("value='"); + if (isSimpleType()) + expected.append(valToString(val)); + expected.append("',numchild='2',children=[{name='key',type='"). + append(typeToString()).append("',addr='").append(ptrToBa(&key)). + append("'},{name='value',type='").append(typeToString()). + append("',addr='").append(ptrToBa(&val)).append("'}]"); + testDumper(expected, node, NS"QHashNode", true, + getMapType(), "", sizeof(it.key()), sizeof(it.value())); +} + +void tst_Gdb::dumpQHashNode() +{ + // Case 1: simple type -> simple type. + QHash hash1; + hash1[2] = 3; + dumpQHashNodeHelper(hash1); + + // Case 2: simple type -> composite type. + QHash hash2; + hash2[5] = "String 7"; + dumpQHashNodeHelper(hash2); + + // Case 3: composite type -> simple type + QHash hash3; + hash3["String 11"] = 13; + dumpQHashNodeHelper(hash3); + + // Case 4: composite type -> composite type + QHash hash4; + hash4["String 17"] = "String 19"; + dumpQHashNodeHelper(hash4); +} + +void tst_Gdb::dumpQImageHelper(const QImage &img) +{ + QByteArray expected = "value='(%x%)',type='"NS"QImage',numchild='1'," + "children=[{name='data',type='"NS"QImageData',addr='%'}]" + << N(img.width()) + << N(img.height()) + << ptrToBa(&img); + testDumper(expected, &img, NS"QImage", true); +} + +void tst_Gdb::dumpQImage() +{ + // Case 1: Null image. + QImage img; + dumpQImageHelper(img); + + // Case 2: Normal image. + img = QImage(3, 700, QImage::Format_RGB555); + dumpQImageHelper(img); + + // Case 3: Invalid image. + img = QImage(100, 0, QImage::Format_Invalid); + dumpQImageHelper(img); +} + +void tst_Gdb::dumpQImageDataHelper(QImage &img) +{ + const QByteArray ba(QByteArray::fromRawData((const char*) img.bits(), img.numBytes())); + QByteArray expected = QByteArray("tiname='$I',addr='$A',type='"NS"QImageData',"). + append("numchild='0',value='',valuetooltipencoded='1',"). + append("valuetooltipsize='").append(N(ba.size())).append("',"). + append("valuetooltip='").append(ba.toBase64()).append("'"); + testDumper(expected, &img, NS"QImageData", false); +} + +void tst_Gdb::dumpQImageData() +{ + // Case 1: Null image. + QImage img; + dumpQImageDataHelper(img); + + // Case 2: Normal image. + img = QImage(3, 700, QImage::Format_RGB555); + dumpQImageDataHelper(img); + + // Case 3: Invalid image. + img = QImage(100, 0, QImage::Format_Invalid); + dumpQImageDataHelper(img); +} + +template + void tst_Gdb::dumpQLinkedListHelper(QLinkedList &l) +{ + const int size = qMin(l.size(), 1000); + const QString &sizeStr = N(size); + const QByteArray elemTypeStr = typeToString(); + QByteArray expected = QByteArray("value='<").append(sizeStr). + append(" items>',valuedisabled='true',numchild='").append(sizeStr). + append("',childtype='").append(elemTypeStr).append("',childnumchild='"). + append(typeToNumchild()).append("',children=["); + typename QLinkedList::const_iterator iter = l.constBegin(); + for (int i = 0; i < size; ++i, ++iter) { + expected.append("{"); + const T &curElem = *iter; + if (isPointer()) { + const QString typeStr = stripPtrType(typeToString()); + const QByteArray addrStr = valToString(curElem); + if (curElem != 0) { + expected.append("addr='").append(addrStr).append("',saddr='"). + append(addrStr).append("',type='").append(typeStr). + append("',value='"). + append(derefValToString(curElem)).append("'"); + } else { + expected.append("addr='").append(ptrToBa(&curElem)).append("',type='"). + append(typeStr).append("',value='',numchild='0'"); + } + } else { + expected.append("addr='").append(ptrToBa(&curElem)). + append("',value='").append(valToString(curElem)).append("'"); + } + expected.append("}"); + if (i < size - 1) + expected.append(","); + } + if (size < l.size()) + expected.append(",..."); + expected.append("]"); + testDumper(expected, &l, NS"QLinkedList", true, elemTypeStr); +} + +void tst_Gdb::dumpQLinkedList() +{ + // Case 1: Simple element type. + QLinkedList l; + + // Case 1.1: Empty list. + dumpQLinkedListHelper(l); + + // Case 1.2: One element. + l.append(2); + dumpQLinkedListHelper(l); + + // Case 1.3: Two elements + l.append(3); + dumpQLinkedListHelper(l); + + // Case 2: Composite element type. + QLinkedList l2; + + // Case 2.1: Empty list. + dumpQLinkedListHelper(l2); + + // Case 2.2: One element. + l2.append("Teststring 1"); + dumpQLinkedListHelper(l2); + + // Case 2.3: Two elements. + l2.append("Teststring 2"); + dumpQLinkedListHelper(l2); + + // Case 2.4: > 1000 elements. + for (int i = 3; i <= 1002; ++i) + l2.append("Test " + N(i)); + + // Case 3: Pointer type. + QLinkedList l3; + l3.append(new int(5)); + l3.append(new int(7)); + l3.append(0); + dumpQLinkedListHelper(l3); +} + + #if 0 + void tst_Gdb::dumpQLinkedList() + { + // Case 1: Simple element type. + QLinkedList l; + + // Case 1.1: Empty list. + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "childtype='int',childnumchild='0',children=[]", + &l, NS"QLinkedList", true, "int"); + + // Case 1.2: One element. + l.append(2); + testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + "childtype='int',childnumchild='0',children=[{addr='%',value='2'}]" + << ptrToBa(l.constBegin().operator->()), + &l, NS"QLinkedList", true, "int"); + + // Case 1.3: Two elements + l.append(3); + QByteArray it0 = ptrToBa(l.constBegin().operator->()); + QByteArray it1 = ptrToBa(l.constBegin().operator++().operator->()); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "childtype='int',childnumchild='0',children=[{addr='%',value='2'}," + "{addr='%',value='3'}]" << it0 << it1, + &l, NS"QLinkedList", true, "int"); + + // Case 2: Composite element type. + QLinkedList l2; + QLinkedList::const_iterator iter; + + // Case 2.1: Empty list. + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "childtype='"NS"QString',childnumchild='0',children=[]", + &l2, NS"QLinkedList", true, NS"QString"); + + // Case 2.2: One element. + l2.append("Teststring 1"); + iter = l2.constBegin(); + qDebug() << *iter; + testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + "childtype='"NS"QString',childnumchild='0',children=[{addr='%',value='%',}]" + << ptrToBa(iter.operator->()) << utfToBase64(*iter), + &l2, NS"QLinkedList", true, NS"QString"); + + // Case 2.3: Two elements. + QByteArray expected = "value='<2 items>',valuedisabled='true',numchild='2'," + "childtype='int',childnumchild='0',children=["; + iter = l2.constBegin(); + expected.append("{addr='%',%}," + << ptrToBa(iter.operator->()) << utfToBase64(*iter)); + ++iter; + expected.append("{addr='%',%}]" + << ptrToBa(iter.operator->()) << utfToBase64(*iter)); + testDumper(expected, + &l, NS"QLinkedList", true, NS"QString"); + + // Case 2.4: > 1000 elements. + for (int i = 3; i <= 1002; ++i) + l2.append("Test " + N(i)); + + expected = "value='<1002 items>',valuedisabled='true'," + "numchild='1002',childtype='"NS"QString',childnumchild='0',children=['"; + iter = l2.constBegin(); + for (int i = 0; i < 1002; ++i, ++iter) + expected.append("{addr='%',value='%'}," + << ptrToBa(iter.operator->()) << utfToBase64(*iter)); + expected.append(",...]"); + testDumper(expected, &l, NS"QLinkedList", true, NS"QString"); + + + // Case 3: Pointer type. + QLinkedList l3; + l3.append(new int(5)); + l3.append(new int(7)); + l3.append(0); + //dumpQLinkedListHelper(l3); + testDumper("", &l, NS"QLinkedList", true, NS"QString"); + } + #endif + +void tst_Gdb::dumpQList_int() +{ + QList ilist; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "internal='1',children=[]", + &ilist, NS"QList", true, "int"); + ilist.append(1); + ilist.append(2); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "internal='1',childtype='int',childnumchild='0',children=[" + "{addr='" + str(&ilist.at(0)) + "',value='1'}," + "{addr='" + str(&ilist.at(1)) + "',value='2'}]", + &ilist, NS"QList", true, "int"); +} + +void tst_Gdb::dumpQList_char() +{ + QList clist; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "internal='1',children=[]", + &clist, NS"QList", true, "char"); + clist.append('a'); + clist.append('b'); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "internal='1',childtype='char',childnumchild='0',children=[" + "{addr='" + str(&clist.at(0)) + "',value=''a', ascii=97'}," + "{addr='" + str(&clist.at(1)) + "',value=''b', ascii=98'}]", + &clist, NS"QList", true, "char"); +} + +void tst_Gdb::dumpQList_QString() +{ + QList slist; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "internal='1',children=[]", + &slist, NS"QList", true, NS"QString"); + slist.append("a"); + slist.append("b"); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "internal='1',childtype='"NS"QString',childnumchild='0',children=[" + "{addr='" + str(&slist.at(0)) + "',value='YQA=',valueencoded='2'}," + "{addr='" + str(&slist.at(1)) + "',value='YgA=',valueencoded='2'}]", + &slist, NS"QList", true, NS"QString"); +} + +void tst_Gdb::dumpQList_Int3() +{ + QList i3list; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "internal='0',children=[]", + &i3list, NS"QList", true, "Int3"); + i3list.append(Int3()); + i3list.append(Int3()); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "internal='0',childtype='Int3',children=[" + "{addr='" + str(&i3list.at(0)) + "'}," + "{addr='" + str(&i3list.at(1)) + "'}]", + &i3list, NS"QList", true, "Int3"); +} + +void tst_Gdb::dumpQList_QString3() +{ + QList s3list; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'," + "internal='0',children=[]", + &s3list, NS"QList", true, "QString3"); + s3list.append(QString3()); + s3list.append(QString3()); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "internal='0',childtype='QString3',children=[" + "{addr='" + str(&s3list.at(0)) + "'}," + "{addr='" + str(&s3list.at(1)) + "'}]", + &s3list, NS"QList", true, "QString3"); +} + +void tst_Gdb::dumpQLocaleHelper(QLocale &loc) +{ + QByteArray expected = QByteArray("value='%',type='$T',numchild='8'," + "children=[{name='country',%}," + "{name='language',%}," + "{name='measurementSystem',%}," + "{name='numberOptions',%}," + "{name='timeFormat_(short)',%}," + "{name='timeFormat_(long)',%}," + "{name='decimalPoint',%}," + "{name='exponential',%}," + "{name='percent',%}," + "{name='zeroDigit',%}," + "{name='groupSeparator',%}," + "{name='negativeSign',%}]") + << valToString(loc.name()) + << createExp(&loc, "QLocale", "country()") + << createExp(&loc, "QLocale", "language()") + << createExp(&loc, "QLocale", "measurementSystem()") + << createExp(&loc, "QLocale", "numberOptions()") + << generateQStringSpec(loc.timeFormat(QLocale::ShortFormat)) + << generateQStringSpec(loc.timeFormat()) + << generateQCharSpec(loc.decimalPoint()) + << generateQCharSpec(loc.exponential()) + << generateQCharSpec(loc.percent()) + << generateQCharSpec(loc.zeroDigit()) + << generateQCharSpec(loc.groupSeparator()) + << generateQCharSpec(loc.negativeSign()); + testDumper(expected, &loc, NS"QLocale", true); +} + +void tst_Gdb::dumpQLocale() +{ + QLocale english(QLocale::English); + dumpQLocaleHelper(english); + + QLocale german(QLocale::German); + dumpQLocaleHelper(german); + + QLocale chinese(QLocale::Chinese); + dumpQLocaleHelper(chinese); + + QLocale swahili(QLocale::Swahili); + dumpQLocaleHelper(swahili); +} + +template + void tst_Gdb::dumpQMapHelper(QMap &map) +{ + QByteArray sizeStr(valToString(map.size())); + size_t nodeSize; + size_t valOff; + getMapNodeParams(nodeSize, valOff); + int transKeyOffset = static_cast(2*sizeof(void *)) - static_cast(nodeSize); + int transValOffset = transKeyOffset + valOff; + bool simpleKey = isSimpleType(); + bool simpleVal = isSimpleType(); + QByteArray expected = QByteArray("value='<").append(sizeStr).append(" items>',numchild='"). + append(sizeStr).append("',extra='simplekey: ").append(N(simpleKey)). + append(" isSimpleValue: ").append(N(simpleVal)). + append(" keyOffset: ").append(N(transKeyOffset)).append(" valueOffset: "). + append(N(transValOffset)).append(" mapnodesize: "). + append(N(qulonglong(nodeSize))).append("',children=["); // 64bit Linux hack + typedef typename QMap::iterator mapIter; + for (mapIter it = map.begin(); it != map.end(); ++it) { + if (it != map.begin()) + expected.append(","); + const QByteArray keyString = + QByteArray(valToString(it.key())).replace("valueencoded","keyencoded"); + expected.append("{key='").append(keyString).append("',value='"). + append(valToString(it.value())).append("',"); + if (simpleKey && simpleVal) { + expected.append("type='").append(typeToString()). + append("',addr='").append(ptrToBa(&it.value())).append("'"); + } else { + QByteArray keyTypeStr = typeToString(); + QByteArray valTypeStr = typeToString(); +#if QT_VERSION >= 0x040500 + expected.append("addr='"). + append(ptrToBa(reinterpret_cast(&(*it)) + sizeof(V))). + append("',type='"NS"QMapNode<").append(keyTypeStr).append(","). + append(valTypeStr).append(MAP_NODE_TYPE_END).append("'"); +#else + expected.append("type='"NS"QMapData::Node<").append(keyTypeStr). + append(",").append(valTypeStr).append(MAP_NODE_TYPE_END). + append("',exp='*('"NS"QMapData::Node<").append(keyTypeStr). + append(",").append(valTypeStr).append(MAP_NODE_TYPE_END). + append(" >'*)").append(ptrToBa(&(*it))).append("'"); +#endif + } + expected.append("}"); + } + expected.append("]"); + mapIter it = map.begin(); + testDumper(expected, *reinterpret_cast(&it), NS"QMap", + true, getMapType(), "", 0, 0, nodeSize, valOff); +} + +void tst_Gdb::dumpQMap() +{ + // Case 1: Simple type -> simple type. + QMap map1; + + // Case 1.1: Empty map. + dumpQMapHelper(map1); + + // Case 1.2: One element. + map1[2] = 3; + dumpQMapHelper(map1); + + // Case 1.3: Two elements. + map1[3] = 5; + dumpQMapHelper(map1); + + // Case 2: Simple type -> composite type. + QMap map2; + + // Case 2.1: Empty Map. + dumpQMapHelper(map2); + + // Case 2.2: One element. + map2[5] = "String 7"; + dumpQMapHelper(map2); + + // Case 2.3: Two elements. + map2[7] = "String 11"; + dumpQMapHelper(map2); + + // Case 3: Composite type -> simple type. + QMap map3; + + // Case 3.1: Empty map. + dumpQMapHelper(map3); + + // Case 3.2: One element. + map3["String 13"] = 11; + dumpQMapHelper(map3); + + // Case 3.3: Two elements. + map3["String 17"] = 13; + dumpQMapHelper(map3); + + // Case 4: Composite type -> composite type. + QMap map4; + + // Case 4.1: Empty map. + dumpQMapHelper(map4); + + // Case 4.2: One element. + map4["String 19"] = "String 23"; + dumpQMapHelper(map4); + + // Case 4.3: Two elements. + map4["String 29"] = "String 31"; + dumpQMapHelper(map4); + + // Case 4.4: Different value, same key (multimap functionality). + map4["String 29"] = "String 37"; + dumpQMapHelper(map4); +} + +template + void tst_Gdb::dumpQMapNodeHelper(QMap &m) +{ + typename QMap::iterator it = m.begin(); + const K &key = it.key(); + const V &val = it.value(); + //const char * const keyType = typeToString(key); + QByteArray expected = QByteArray("value='',numchild='2'," + "children=[{name='key',addr='").append(ptrToBa(&key)). + append("',type='").append(typeToString()).append("',value='"). + append(valToString(key)).append("'},{name='value',addr='"). + append(ptrToBa(&val)).append("',type='").append(typeToString()). + append("',value='").append(valToString(val)). + append("'}]"); + size_t nodeSize; + size_t valOffset; + getMapNodeParams(nodeSize, valOffset); + testDumper(expected, *reinterpret_cast(&it), NS"QMapNode", + true, getMapType(), "", 0, 0, nodeSize, valOffset); +} + +void tst_Gdb::dumpQMapNode() +{ + // Case 1: simple type -> simple type. + QMap map; + map[2] = 3; + dumpQMapNodeHelper(map); + + // Case 2: simple type -> composite type. + QMap map2; + map2[3] = "String 5"; + dumpQMapNodeHelper(map2); + + // Case 3: composite type -> simple type. + QMap map3; + map3["String 7"] = 11; + dumpQMapNodeHelper(map3); + + // Case 4: composite type -> composite type. + QMap map4; + map4["String 13"] = "String 17"; + dumpQMapNodeHelper(map4); +} + +void tst_Gdb::dumpQObject() +{ + QObject parent; + testDumper("value='',valueencoded='2',type='$T',displayedtype='QObject'," + "numchild='4'", + &parent, NS"QObject", false); + testDumper("value='',valueencoded='2',type='$T',displayedtype='QObject'," + "numchild='4',children=[" + "{name='properties',addr='$A',type='$TPropertyList'," + "value='<1 items>',numchild='1'}," + "{name='signals',addr='$A',type='$TSignalList'," + "value='<2 items>',numchild='2'}," + "{name='slots',addr='$A',type='$TSlotList'," + "value='<2 items>',numchild='2'}," + "{name='parent',value='0x0',type='$T *',numchild='0'}," + "{name='className',value='QObject',type='',numchild='0'}]", + &parent, NS"QObject", true); + +#if 0 + testDumper("numchild='2',value='<2 items>',type='QObjectSlotList'," + "children=[{name='2',value='deleteLater()'," + "numchild='0',addr='$A',type='QObjectSlot'}," + "{name='3',value='_q_reregisterTimers(void*)'," + "numchild='0',addr='$A',type='QObjectSlot'}]", + &parent, NS"QObjectSlotList", true); +#endif + + parent.setObjectName("A Parent"); + testDumper("value='QQAgAFAAYQByAGUAbgB0AA==',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='4'", + &parent, NS"QObject", false); + QObject child(&parent); + testDumper("value='',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='4'", + &child, NS"QObject", false); + child.setObjectName("A Child"); + QByteArray ba ="value='QQAgAEMAaABpAGwAZAA=',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='4',children=[" + "{name='properties',addr='$A',type='$TPropertyList'," + "value='<1 items>',numchild='1'}," + "{name='signals',addr='$A',type='$TSignalList'," + "value='<2 items>',numchild='2'}," + "{name='slots',addr='$A',type='$TSlotList'," + "value='<2 items>',numchild='2'}," + "{name='parent',addr='" + str(&parent) + "'," + "value='QQAgAFAAYQByAGUAbgB0AA==',valueencoded='2',type='$T'," + "displayedtype='QObject',numchild='1'}," + "{name='className',value='QObject',type='',numchild='0'}]"; + testDumper(ba, &child, NS"QObject", true); + connect(&child, SIGNAL(destroyed()), qApp, SLOT(quit())); + testDumper(ba, &child, NS"QObject", true); + disconnect(&child, SIGNAL(destroyed()), qApp, SLOT(quit())); + testDumper(ba, &child, NS"QObject", true); + child.setObjectName("A renamed Child"); + testDumper("value='QQAgAHIAZQBuAGEAbQBlAGQAIABDAGgAaQBsAGQA',valueencoded='2'," + "type='$T',displayedtype='QObject',numchild='4'", + &child, NS"QObject", false); +} + +void tst_Gdb::dumpQObjectChildListHelper(QObject &o) +{ + const QObjectList children = o.children(); + const int size = children.size(); + const QString sizeStr = N(size); + QByteArray expected = QByteArray("numchild='").append(sizeStr).append("',value='<"). + append(sizeStr).append(" items>',type='"NS"QObjectChildList',children=["); + for (int i = 0; i < size; ++i) { + const QObject *child = children.at(i); + expected.append("{addr='").append(ptrToBa(child)).append("',value='"). + append(utfToBase64(child->objectName())). + append("',valueencoded='2',type='"NS"QObject',displayedtype='"). + append(child->metaObject()->className()).append("',numchild='1'}"); + if (i < size - 1) + expected.append(","); + } + expected.append("]"); + testDumper(expected, &o, NS"QObjectChildList", true); +} + +void tst_Gdb::dumpQObjectChildList() +{ + // Case 1: Object with no children. + QObject o; + dumpQObjectChildListHelper(o); + + // Case 2: Object with one child. + QObject o2(&o); + dumpQObjectChildListHelper(o); + + // Case 3: Object with two children. + QObject o3(&o); + dumpQObjectChildListHelper(o); +} + +void tst_Gdb::dumpQObjectMethodList() +{ + QStringListModel m; + testDumper("addr='',type='$T',numchild='20'," + "childtype='"NS"QMetaMethod::Method',childnumchild='0',children=[" + "{name='0 0 destroyed(QObject*)',value=' (1)'}," + "{name='1 1 destroyed()',value=' (1)'}," + "{name='2 2 deleteLater()',value=' (2)'}," + "{name='3 3 _q_reregisterTimers(void*)',value=' (2)'}," + "{name='4 4 dataChanged(QModelIndex,QModelIndex)',value=' (1)'}," + "{name='5 5 headerDataChanged(Qt::Orientation,int,int)',value=' (1)'}," + "{name='6 6 layoutChanged()',value=' (1)'}," + "{name='7 7 layoutAboutToBeChanged()',value=' (1)'}," + "{name='8 8 rowsAboutToBeInserted(QModelIndex,int,int)',value=' (1)'}," + "{name='9 9 rowsInserted(QModelIndex,int,int)',value=' (1)'}," + "{name='10 10 rowsAboutToBeRemoved(QModelIndex,int,int)',value=' (1)'}," + "{name='11 11 rowsRemoved(QModelIndex,int,int)',value=' (1)'}," + "{name='12 12 columnsAboutToBeInserted(QModelIndex,int,int)',value=' (1)'}," + "{name='13 13 columnsInserted(QModelIndex,int,int)',value=' (1)'}," + "{name='14 14 columnsAboutToBeRemoved(QModelIndex,int,int)',value=' (1)'}," + "{name='15 15 columnsRemoved(QModelIndex,int,int)',value=' (1)'}," + "{name='16 16 modelAboutToBeReset()',value=' (1)'}," + "{name='17 17 modelReset()',value=' (1)'}," + "{name='18 18 submit()',value=' (2)'}," + "{name='19 19 revert()',value=' (2)'}]", + &m, NS"QObjectMethodList", true); +} + +void tst_Gdb::dumpQObjectPropertyList() +{ + // Case 1: Model without a parent. + QStringListModel m(QStringList() << "Test1" << "Test2"); + testDumper("addr='',type='$T',numchild='1',value='<1 items>'," + "children=[{name='objectName',type='QString',value=''," + "valueencoded='2',numchild='0'}]", + &m, NS"QObjectPropertyList", true); + + // Case 2: Model with a parent. + QStringListModel m2(&m); + testDumper("addr='',type='$T',numchild='1',value='<1 items>'," + "children=[{name='objectName',type='QString',value=''," + "valueencoded='2',numchild='0'}]", + &m2, NS"QObjectPropertyList", true); +} + +static const char *connectionType(uint type) +{ + Qt::ConnectionType connType = static_cast(type); + const char *output = "unknown"; + switch (connType) { + case Qt::AutoConnection: output = "auto"; break; + case Qt::DirectConnection: output = "direct"; break; + case Qt::QueuedConnection: output = "queued"; break; + case Qt::BlockingQueuedConnection: output = "blockingqueued"; break; + case 3: output = "autocompat"; break; +#if QT_VERSION >= 0x040600 + case Qt::UniqueConnection: break; // Can't happen. +#endif + default: + qWarning() << "Unknown connection type: " << type; + break; + }; + return output; +}; + +class Cheater : public QObject +{ +public: + static const QObjectPrivate *getPrivate(const QObject &o) + { + const Cheater &cheater = static_cast(o); +#if QT_VERSION >= 0x040600 + return dynamic_cast(cheater.d_ptr.data()); +#else + return dynamic_cast(cheater.d_ptr); +#endif + } +}; + +typedef QVector ConnLists; + +void tst_Gdb::dumpQObjectSignalHelper(QObject &o, int sigNum) +{ + //qDebug() << o.objectName() << sigNum; + QByteArray expected("addr='',numchild='1',type='"NS"QObjectSignal'"); +#if QT_VERSION >= 0x040400 + expected.append(",children=["); + const QObjectPrivate *p = Cheater::getPrivate(o); + Q_ASSERT(p != 0); + const ConnLists *connLists = reinterpret_cast(p->connectionLists); + QObjectPrivate::ConnectionList connList = + connLists != 0 && connLists->size() > sigNum ? + connLists->at(sigNum) : QObjectPrivate::ConnectionList(); + int i = 0; + for (QObjectPrivate::Connection *conn = connList.first; conn != 0; + ++i, conn = conn->nextConnectionList) { + const QString iStr = N(i); + expected.append("{name='").append(iStr).append(" receiver',"); + if (conn->receiver == &o) + expected.append("value='',type='"). + append(o.metaObject()->className()). + append("',numchild='0',addr='").append(ptrToBa(&o)).append("'"); + else if (conn->receiver == 0) + expected.append("value='0x0',type='"NS"QObject *',numchild='0'"); + else + expected.append("addr='").append(ptrToBa(conn->receiver)).append("',value='"). + append(utfToBase64(conn->receiver->objectName())).append("',valueencoded='2',"). + append("type='"NS"QObject',displayedtype='"). + append(conn->receiver->metaObject()->className()).append("',numchild='1'"); + expected.append("},{name='").append(iStr).append(" slot',type='',value='"); + if (conn->receiver != 0) + expected.append(conn->receiver->metaObject()->method(conn->method).signature()); + else + expected.append(""); + expected.append("',numchild='0'},{name='").append(iStr).append(" type',type='',value='<"). + append(connectionType(conn->connectionType)).append(" connection>',"). + append("numchild='0'}"); + if (conn != connList.last) + expected.append(","); + } + expected.append("],numchild='").append(N(i)).append("'"); +#endif + testDumper(expected, &o, NS"QObjectSignal", true, "", "", sigNum); +} + +void tst_Gdb::dumpQObjectSignal() +{ + // Case 1: Simple QObject. + QObject o; + o.setObjectName("Test"); + testDumper("addr='',numchild='1',type='"NS"QObjectSignal'," + "children=[],numchild='0'", + &o, NS"QObjectSignal", true, "", "", 0); + + // Case 2: QAbstractItemModel with no connections. + QStringListModel m(QStringList() << "Test1" << "Test2"); + for (int signalIndex = 0; signalIndex < 17; ++signalIndex) + dumpQObjectSignalHelper(m, signalIndex); + + // Case 3: QAbstractItemModel with connections to itself and to another + // object, using different connection types. + qRegisterMetaType("QModelIndex"); + connect(&m, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), + &o, SLOT(deleteLater()), Qt::DirectConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + &m, SLOT(revert()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + &m, SLOT(submit()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsInserted(const QModelIndex &, int, int)), + &m, SLOT(submit()), Qt::BlockingQueuedConnection); + connect(&m, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), + &m, SLOT(deleteLater()), Qt::AutoConnection); +#if QT_VERSION >= 0x040600 + connect(&m, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + &m, SLOT(revert()), Qt::UniqueConnection); +#endif + for (int signalIndex = 0; signalIndex < 17; ++signalIndex) + dumpQObjectSignalHelper(m, signalIndex); +} + +void tst_Gdb::dumpQObjectSignalList() +{ + // Case 1: Simple QObject. + QObject o; + o.setObjectName("Test"); + + testDumper("type='"NS"QObjectSignalList',value='<2 items>'," + "addr='$A',numchild='2',children=[" + "{name='0',value='destroyed(QObject*)',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}," + "{name='1',value='destroyed()',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}]", + &o, NS"QObjectSignalList", true); + + // Case 2: QAbstractItemModel with no connections. + QStringListModel m(QStringList() << "Test1" << "Test2"); + QByteArray expected = "type='"NS"QObjectSignalList',value='<16 items>'," + "addr='$A',numchild='16',children=[" + "{name='0',value='destroyed(QObject*)',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}," + "{name='1',value='destroyed()',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}," + "{name='4',value='dataChanged(QModelIndex,QModelIndex)',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}," + "{name='5',value='headerDataChanged(Qt::Orientation,int,int)'," + "numchild='0',addr='$A',type='"NS"QObjectSignal'}," + "{name='6',value='layoutChanged()',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}," + "{name='7',value='layoutAboutToBeChanged()',numchild='0'," + "addr='$A',type='"NS"QObjectSignal'}," + "{name='8',value='rowsAboutToBeInserted(QModelIndex,int,int)'," + "numchild='0',addr='$A',type='"NS"QObjectSignal'}," + "{name='9',value='rowsInserted(QModelIndex,int,int)'," + "numchild='0',addr='$A',type='"NS"QObjectSignal'}," + "{name='10',value='rowsAboutToBeRemoved(QModelIndex,int,int)'," + "numchild='%',addr='$A',type='"NS"QObjectSignal'}," + "{name='11',value='rowsRemoved(QModelIndex,int,int)'," + "numchild='%',addr='$A',type='"NS"QObjectSignal'}," + "{name='12',value='columnsAboutToBeInserted(QModelIndex,int,int)'," + "numchild='%',addr='$A',type='"NS"QObjectSignal'}," + "{name='13',value='columnsInserted(QModelIndex,int,int)'," + "numchild='%',addr='$A',type='"NS"QObjectSignal'}," + "{name='14',value='columnsAboutToBeRemoved(QModelIndex,int,int)'," + "numchild='%',addr='$A',type='"NS"QObjectSignal'}," + "{name='15',value='columnsRemoved(QModelIndex,int,int)'," + "numchild='%',addr='$A',type='"NS"QObjectSignal'}," + "{name='16',value='modelAboutToBeReset()'," + "numchild='0',addr='$A',type='"NS"QObjectSignal'}," + "{name='17',value='modelReset()'," + "numchild='0',addr='$A',type='"NS"QObjectSignal'}]"; + + testDumper(expected << "0" << "0" << "0" << "0" << "0" << "0", + &m, NS"QObjectSignalList", true); + + + // Case 3: QAbstractItemModel with connections to itself and to another + // object, using different connection types. + qRegisterMetaType("QModelIndex"); + connect(&m, SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), + &o, SLOT(deleteLater()), Qt::DirectConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + &m, SLOT(revert()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + &m, SLOT(submit()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsInserted(QModelIndex, int, int)), + &m, SLOT(submit()), Qt::BlockingQueuedConnection); + connect(&m, SIGNAL(columnsRemoved(QModelIndex, int, int)), + &m, SLOT(deleteLater()), Qt::AutoConnection); + + testDumper(expected << "1" << "1" << "2" << "1" << "0" << "0", + &m, NS"QObjectSignalList", true); +} + +QByteArray slotIndexList(const QObject *ob) +{ + QByteArray slotIndices; + const QMetaObject *mo = ob->metaObject(); + for (int i = 0; i < mo->methodCount(); ++i) { + const QMetaMethod &mm = mo->method(i); + if (mm.methodType() == QMetaMethod::Slot) { + int slotIndex = mo->indexOfSlot(mm.signature()); + Q_ASSERT(slotIndex != -1); + slotIndices.append(N(slotIndex)); + slotIndices.append(','); + } + } + slotIndices.chop(1); + return slotIndices; +} + +void tst_Gdb::dumpQObjectSlot() +{ + // Case 1: Simple QObject. + QObject o; + o.setObjectName("Test"); + + QByteArray slotIndices = slotIndexList(&o); + QCOMPARE(slotIndices, QByteArray("2,3")); + QCOMPARE(o.metaObject()->indexOfSlot("deleteLater()"), 2); + + QByteArray expected = QByteArray("addr='$A',numchild='1',type='$T'," + //"children=[{name='1 sender'}],numchild='1'"); + "children=[],numchild='0'"); + qDebug() << "FIXME!"; + testDumper(expected, &o, NS"QObjectSlot", true, "", "", 2); + + + // Case 2: QAbstractItemModel with no connections. + QStringListModel m(QStringList() << "Test1" << "Test2"); + slotIndices = slotIndexList(&o); + + QCOMPARE(slotIndices, QByteArray("2,3")); + QCOMPARE(o.metaObject()->indexOfSlot("deleteLater()"), 2); + + expected = QByteArray("addr='$A',numchild='1',type='$T'," + //"children=[{name='1 sender'}],numchild='1'"); + "children=[],numchild='0'"); + qDebug() << "FIXME!"; + testDumper(expected, &o, NS"QObjectSlot", true, "", "", 2); + + + // Case 3: QAbstractItemModel with connections to itself and to another + // o, using different connection types. + qRegisterMetaType("QModelIndex"); + connect(&m, SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), + &o, SLOT(deleteLater()), Qt::DirectConnection); + connect(&o, SIGNAL(destroyed(QObject *)), + &m, SLOT(revert()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + &m, SLOT(submit()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsInserted(QModelIndex, int, int)), + &m, SLOT(submit()), Qt::BlockingQueuedConnection); + connect(&m, SIGNAL(columnsRemoved(QModelIndex, int, int)), + &m, SLOT(deleteLater()), Qt::AutoConnection); +#if QT_VERSION >= 0x040600 + connect(&m, SIGNAL(dataChanged(QModelIndex, QModelIndex)), + &m, SLOT(revert()), Qt::UniqueConnection); +#endif + expected = QByteArray("addr='$A',numchild='1',type='$T'," + //"children=[{name='1 sender'}],numchild='1'"); + "children=[],numchild='0'"); + qDebug() << "FIXME!"; + testDumper(expected, &o, NS"QObjectSlot", true, "", "", 2); + +} + +void tst_Gdb::dumpQObjectSlotList() +{ + // Case 1: Simple QObject. + QObject o; + o.setObjectName("Test"); + testDumper("numchild='2',value='<2 items>',type='$T'," + "children=[{name='2',value='deleteLater()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='3',value='_q_reregisterTimers(void*)',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}]", + &o, NS"QObjectSlotList", true); + + // Case 2: QAbstractItemModel with no connections. + QStringListModel m(QStringList() << "Test1" << "Test2"); + testDumper("numchild='4',value='<4 items>',type='$T'," + "children=[{name='2',value='deleteLater()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='3',value='_q_reregisterTimers(void*)',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='18',value='submit()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='19',value='revert()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}]", + &m, NS"QObjectSlotList", true); + + // Case 3: QAbstractItemModel with connections to itself and to another + // object, using different connection types. + qRegisterMetaType("QModelIndex"); + connect(&m, SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), + &o, SLOT(deleteLater()), Qt::DirectConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + &m, SLOT(revert()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + &m, SLOT(submit()), Qt::QueuedConnection); + connect(&m, SIGNAL(columnsInserted(QModelIndex, int, int)), + &m, SLOT(submit()), Qt::BlockingQueuedConnection); + connect(&m, SIGNAL(columnsRemoved(QModelIndex, int, int)), + &m, SLOT(deleteLater()), Qt::AutoConnection); + connect(&o, SIGNAL(destroyed(QObject *)), &m, SLOT(submit())); + testDumper("numchild='4',value='<4 items>',type='$T'," + "children=[{name='2',value='deleteLater()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='3',value='_q_reregisterTimers(void*)',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='18',value='submit()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}," + "{name='19',value='revert()',numchild='0'," + "addr='$A',type='"NS"QObjectSlot'}]", + &m, NS"QObjectSlotList", true); +} + +void tst_Gdb::dumpQPixmap() +{ + // Case 1: Null Pixmap. + QPixmap p; + + testDumper("value='(0x0)',type='$T',numchild='0'", + &p, NS"QPixmap", true); + + + // Case 2: Uninitialized non-null pixmap. + p = QPixmap(20, 100); + testDumper("value='(20x100)',type='$T',numchild='0'", + &p, NS"QPixmap", true); + + + // Case 3: Initialized non-null pixmap. + const char * const pixmap[] = { + "2 24 3 1", " c None", ". c #DBD3CB", "+ c #FCFBFA", + " ", " ", " ", ".+", ".+", ".+", ".+", ".+", ".+", ".+", ".+", ".+", + ".+", ".+", ".+", ".+", ".+", ".+", ".+", ".+", ".+", " ", " ", " " + }; + p = QPixmap(pixmap); + testDumper("value='(2x24)',type='$T',numchild='0'", + &p, NS"QPixmap", true); +} + +#if QT_VERSION >= 0x040500 +template +void tst_Gdb::dumpQSharedPointerHelper(QSharedPointer &ptr) +{ + struct Cheater : public QSharedPointer + { + static const typename QSharedPointer::Data *getData(const QSharedPointer &p) + { + return static_cast(p).d; + } + }; + + QByteArray expected("value='"); + QString val1 = ptr.isNull() ? "" : valToString(*ptr.data()); + QString val2 = isSimpleType() ? val1 : ""; +/* + const int *weakAddr; + const int *strongAddr; + int weakValue; + int strongValue; + if (!ptr.isNull()) { + weakAddr = reinterpret_cast(&Cheater::getData(ptr)->weakref); + strongAddr = reinterpret_cast(&Cheater::getData(ptr)->strongref); + weakValue = *weakAddr; + strongValue = *strongAddr; + } else { + weakAddr = strongAddr = 0; + weakValue = strongValue = 0; + } + expected.append(val2).append("',valuedisabled='true',numchild='1',children=["). + append("{name='data',addr='").append(ptrToBa(ptr.data())). + append("',type='").append(typeToString()).append("',value='").append(val1). + append("'},{name='weakref',value='").append(N(weakValue)). + append("',type='int',addr='").append(ptrToBa(weakAddr)).append("',numchild='0'},"). + append("{name='strongref',value='").append(N(strongValue)). + append("',type='int',addr='").append(ptrToBa(strongAddr)).append("',numchild='0'}]"); + testDumper(expected, &ptr, NS"QSharedPointer", true, typeToString()); +*/ +} +#endif + +void tst_Gdb::dumpQSharedPointer() +{ +#if QT_VERSION >= 0x040500 + // Case 1: Simple type. + // Case 1.1: Null pointer. + QSharedPointer simplePtr; + dumpQSharedPointerHelper(simplePtr); + + // Case 1.2: Non-null pointer, + QSharedPointer simplePtr2(new int(99)); + dumpQSharedPointerHelper(simplePtr2); + + // Case 1.3: Shared pointer. + QSharedPointer simplePtr3 = simplePtr2; + dumpQSharedPointerHelper(simplePtr2); + + // Case 1.4: Weak pointer. + QWeakPointer simplePtr4(simplePtr2); + dumpQSharedPointerHelper(simplePtr2); + + // Case 2: Composite type. + // Case 1.1: Null pointer. + QSharedPointer compositePtr; + // TODO: This case is not handled in gdbmacros.cpp (segfault!) + //dumpQSharedPointerHelper(compoistePtr); + + // Case 1.2: Non-null pointer, + QSharedPointer compositePtr2(new QString("Test")); + dumpQSharedPointerHelper(compositePtr2); + + // Case 1.3: Shared pointer. + QSharedPointer compositePtr3 = compositePtr2; + dumpQSharedPointerHelper(compositePtr2); + + // Case 1.4: Weak pointer. + QWeakPointer compositePtr4(compositePtr2); + dumpQSharedPointerHelper(compositePtr2); +#endif +} + +void tst_Gdb::dumpQVariant_invalid() +{ + QVariant v; + testDumper("value='(invalid)',type='$T',numchild='0'", + &v, NS"QVariant", false); +} + +void tst_Gdb::dumpQVariant_QString() +{ + QVariant v = "abc"; + testDumper("value='KFFTdHJpbmcpICJhYmMi',valueencoded='5',type='$T'," + "numchild='0'", + &v, NS"QVariant", true); +/* + FIXME: the QString version should have a child: + testDumper("value='KFFTdHJpbmcpICJhYmMi',valueencoded='5',type='$T'," + "numchild='1',children=[{name='value',value='IgBhAGIAYwAiAA=='," + "valueencoded='4',type='QString',numchild='0'}]", + &v, NS"QVariant", true); +*/ +} + +void tst_Gdb::dumpQVariant_QStringList() +{ + QVariant v = QStringList() << "Hi"; + testDumper("value='(QStringList) ',type='$T',numchild='1'," + "children=[{name='value',exp='(*('myns::QStringList'*)%)'," + "type='QStringList',numchild='1'}]" + << QByteArray::number(quintptr(&v)), + &v, NS"QVariant", true); +} + +void tst_Gdb::dumpStdVector() +{ + std::vector *> vector; + QByteArray inner = "std::list *"; + QByteArray innerp = "std::list"; + testDumper("value='<0 items>',valuedisabled='true',numchild='0'", + &vector, "std::vector", false, inner, "", sizeof(std::list *)); + std::list list; + vector.push_back(new std::list(list)); + testDumper("value='<1 items>',valuedisabled='true',numchild='1'," + "childtype='" + inner + "',childnumchild='1'," + "children=[{addr='" + str(deref(&vector[0])) + "'," + "saddr='" + str(deref(&vector[0])) + "',type='" + innerp + "'}]", + &vector, "std::vector", true, inner, "", sizeof(std::list *)); + vector.push_back(0); + list.push_back(45); + testDumper("value='<2 items>',valuedisabled='true',numchild='2'," + "childtype='" + inner + "',childnumchild='1'," + "children=[{addr='" + str(deref(&vector[0])) + "'," + "saddr='" + str(deref(&vector[0])) + "',type='" + innerp + "'}," + "{addr='" + str(&vector[1]) + "'," + "type='" + innerp + "',value='',numchild='0'}]", + &vector, "std::vector", true, inner, "", sizeof(std::list *)); + vector.push_back(new std::list(list)); + vector.push_back(0); +} + +void tst_Gdb::dumpQTextCodecHelper(QTextCodec *codec) +{ + const QByteArray name = codec->name().toBase64(); + QByteArray expected = QByteArray("value='%',valueencoded='1',type='$T'," + "numchild='2',children=[{name='name',value='%',type='"NS"QByteArray'," + "numchild='0',valueencoded='1'},{name='mibEnum',%}]") + << name << name << generateIntSpec(codec->mibEnum()); + testDumper(expected, codec, NS"QTextCodec", true); +} + +void tst_Gdb::dumpQTextCodec() +{ + const QList &codecNames = QTextCodec::availableCodecs(); + foreach (const QByteArray &codecName, codecNames) + dumpQTextCodecHelper(QTextCodec::codecForName(codecName)); +} + +#if QT_VERSION >= 0x040500 +template + size_t offsetOf(const T1 *klass, const T2 *member) +{ + return static_cast(reinterpret_cast(member) - + reinterpret_cast(klass)); +} + +template +void tst_Gdb::dumpQWeakPointerHelper(QWeakPointer &ptr) +{ + typedef QtSharedPointer::ExternalRefCountData Data; + const size_t dataOffset = 0; + const Data *d = *reinterpret_cast( + reinterpret_cast(&ptr) + dataOffset); + const int *weakRefPtr = reinterpret_cast(&d->weakref); + const int *strongRefPtr = reinterpret_cast(&d->strongref); + T *data = ptr.toStrongRef().data(); + const QString dataStr = valToString(*data); + QByteArray expected("value='"); + if (isSimpleType()) + expected.append(dataStr); + expected.append("',valuedisabled='true',numchild='1',children=[{name='data',addr='"). + append(ptrToBa(data)).append("',type='").append(typeToString()). + append("',value='").append(dataStr).append("'},{name='weakref',value='"). + append(valToString(*weakRefPtr)).append("',type='int',addr='"). + append(ptrToBa(weakRefPtr)).append("',numchild='0'},{name='strongref',value='"). + append(valToString(*strongRefPtr)).append("',type='int',addr='"). + append(ptrToBa(strongRefPtr)).append("',numchild='0'}]"); + testDumper(expected, &ptr, NS"QWeakPointer", true, typeToString()); +} +#endif + +void tst_Gdb::dumpQWeakPointer() +{ +#if QT_VERSION >= 0x040500 + // Case 1: Simple type. + + // Case 1.1: Null pointer. + QSharedPointer spNull; + QWeakPointer wp = spNull.toWeakRef(); + testDumper("value='',valuedisabled='true',numchild='0'", + &wp, NS"QWeakPointer", true, "int"); + + // Case 1.2: Weak pointer is unique. + QSharedPointer sp(new int(99)); + wp = sp.toWeakRef(); + dumpQWeakPointerHelper(wp); + + // Case 1.3: There are other weak pointers. + QWeakPointer wp2 = sp.toWeakRef(); + dumpQWeakPointerHelper(wp); + + // Case 1.4: There are other strong shared pointers as well. + QSharedPointer sp2(sp); + dumpQWeakPointerHelper(wp); + + // Case 2: Composite type. + QSharedPointer spS(new QString("Test")); + QWeakPointer wpS = spS.toWeakRef(); + dumpQWeakPointerHelper(wpS); +#endif +} + +#define VERIFY_OFFSETOF(member) \ +do { \ + QObjectPrivate *qob = 0; \ + ObjectPrivate *ob = 0; \ + QVERIFY(size_t(&qob->member) == size_t(&ob->member)); \ +} while (0) + + +Thread::Thread(tst_Gdb *test) +{ + moveToThread(this); + m_test = test; + m_proc = 0; + m_proc = new QProcess; + m_proc->moveToThread(this); + qDebug() << "\nTHREAD CREATED" << getpid() << gettid(); + connect(m_test, SIGNAL(writeToGdb(QByteArray)), + this, SLOT(writeToGdbRequested(QByteArray))); + connect(m_proc, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(handleGdbError(QProcess::ProcessError))); + connect(m_proc, SIGNAL(finished(int, QProcess::ExitStatus)), + this, SLOT(handleGdbFinished(int, QProcess::ExitStatus))); + connect(m_proc, SIGNAL(started()), + this, SLOT(handleGdbStarted())); + connect(m_proc, SIGNAL(readyReadStandardOutput()), + this, SLOT(readStandardOutput())); + connect(m_proc, SIGNAL(readyReadStandardError()), + this, SLOT(readStandardError())); + start(); +} + +void Thread::handleGdbError(QProcess::ProcessError) +{ + qDebug() << "GDB ERROR: "; +} + +void Thread::handleGdbFinished(int, QProcess::ExitStatus) +{ + qDebug() << "GDB FINISHED: "; +} + +void Thread::readStandardOutput() +{ + QByteArray ba = m_proc->readAllStandardOutput(); + if (ba.isEmpty()) + return; + // =library-loaded... + if (ba.startsWith("=")) + return; + //if (ba.startsWith("~")) + // return; + if (!ba.startsWith("~\"locals=")) + return; + //qDebug() << "THREAD GDB OUT: " << ba; + //m_output += ba; + ba = ba.mid(2, ba.size() - 4); + ba = ba.replace("\\\"", "\""); + m_output = ba; + m_waitCondition.wakeAll(); +} + +void Thread::readStandardError() +{ + return; + QByteArray ba = m_proc->readAllStandardOutput(); + qDebug() << "THREAD GDB ERR: " << ba; + m_error += ba; + m_waitCondition.wakeAll(); +} + +void Thread::handleGdbStarted() +{ + //qDebug() << "\n\nGDB STARTED" << getpid() << gettid() << "\n\n"; +} + +void Thread::run() +{ + //qDebug() << "\nTHREAD RUN" << getpid() << gettid(); + m_proc->start("./gdb -i mi --args ./tst_gdb run"); + m_proc->waitForStarted(); + m_proc->write("b main\n"); + m_proc->write("run\n"); + m_proc->write("handle SIGSTOP stop pass\n"); + //qDebug() << "\nTHREAD RUNNING"; + exec(); +} + +void tst_Gdb::initTestCase() +{ + // FIXME: Wait until gdb proc is running. + QTest::qWait(1000); +} + + +void tst_Gdb::runTestCase(const QByteArray &name, const QByteArray &type, + const QByteArrayList &expected) +{ + //qDebug() << "\nABOUT TO RUN TEST: " << name << m_thread.m_proc; + + writeToGdb("b " + name); + + for (int i = 0; i != expected.size(); ++i) { + if (i == 0) + writeToGdb("call " + name + "()"); + else + writeToGdb("next"); + writeToGdb("bb"); + m_mutex.lock(); + m_waitCondition.wait(&m_mutex); + QByteArray ba = m_thread.m_output; + m_mutex.unlock(); + //GdbMi locals; + //locals.fromString("{" + ba + "}"); + QByteArray received = ba.replace("\"", "'"); + //qDebug() << "OUTPUT: " << ba << "\n\n"; + //qDebug() << "OUTPUT: " << locals.toString() << "\n\n"; + testDumper(expected.at(i), 0, type, false, received); + } +} + +void tst_Gdb::cleanupTestCase() +{ + writeToGdb("kill"); + writeToGdb("quit"); + //m_thread.m_proc->waitForFinished(); +} + +void dumpQStringTest() +{ + QString s; + s = "hallo"; + s += "x"; + s += "y"; +} + +void tst_Gdb::dumpQString() +{ + QByteArrayList bal; + + bal.append("{iname='local.s',addr='0xbffff19c',name='S'," + "type='"NS"QString',value='',numchild='0'}"); + + //bal.append("xxx"); + //bal.append("xxx"); + runTestCase("dumpQStringTest", NS"QString", bal); +/* + testDumper("value='',valueencoded='2',type='$T',numchild='0'", + &s, NS"QString", false); + s = "abc"; + testDumper("value='YQBiAGMA',valueencoded='2',type='$T',numchild='0'", + &s, NS"QString", false); +*/ +} + +void dumpQStringListTest() +{ + QStringList s; +} + +void tst_Gdb::dumpQStringList() +{ + QByteArrayList bal; + //bal.append("xxx"); + runTestCase("dumpQStringListTest", NS"QStringList", bal); +} + +int runit(int &argc, char *argv[]) +{ + // Plain call. Start the testing. + QApplication app(argc, argv); + tst_Gdb test; + return QTest::qExec(&test, argc, argv); +} + +int main(int argc, char *argv[]) +{ + if (argc == 2 && QByteArray(argv[1]) == "run") { + // We are the debugged process, recursively called and steered + // by our spawning alter ego. + return 0; + } + + return runit(argc, argv); +} + +#include "tst_gdb.moc" + diff --git a/tests/auto/debugger/tst_plugin.cpp b/tests/auto/debugger/tst_plugin.cpp index 5d26a6ac121..84ffc58a685 100644 --- a/tests/auto/debugger/tst_plugin.cpp +++ b/tests/auto/debugger/tst_plugin.cpp @@ -24,7 +24,6 @@ #include #include "gdb/gdbmi.h" -#include "tcf/json.h" #include "gdbmacros.h" #include "gdbmacros_p.h"