diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc
index 74fc7674308..f9c62be93dc 100644
--- a/doc/qtcreator.qdoc
+++ b/doc/qtcreator.qdoc
@@ -5,7 +5,7 @@
\title Qt Creator Manual
- \section1 Version 1.2.80
+ \section1 Version 1.2.91
The goal of Qt Creator is to provide a cross-platform, complete Integrated
Development Environment (IDE) to develop Qt projects. It is available for
@@ -1786,7 +1786,7 @@
There are some known issues with Qt Creator.
The development team is aware of those, there is no need to report them as bug.
- \section1 Known Issues of Version 1.2.80
+ \section1 Known Issues of Version 1.2.91
\list
\o Gdb on Windows may not work if the 'Embassy \reg Security Center' software
diff --git a/doc/qtcreator.qdocconf b/doc/qtcreator.qdocconf
index 14d79d8f2c3..7663eb8c255 100644
--- a/doc/qtcreator.qdocconf
+++ b/doc/qtcreator.qdocconf
@@ -19,16 +19,16 @@ sources.fileextensions = "qtcreator.qdoc addressbook-sdk.qdoc"
qhp.projects = QtCreator
qhp.QtCreator.file = qtcreator.qhp
-qhp.QtCreator.namespace = com.nokia.qtcreator.1280
+qhp.QtCreator.namespace = com.nokia.qtcreator.1291
qhp.QtCreator.virtualFolder = doc
qhp.QtCreator.indexTitle = Qt Creator
qhp.QtCreator.indexRoot =
qhp.QtCreator.extraFiles = classic.css \
images/qt-logo.png \
images/qtcreator-screenshots.png
-qhp.QtCreator.filterAttributes = qtcreator 1.2.80
-qhp.QtCreator.customFilters.QtCreator.name = Qt Creator 1.2.80
-qhp.QtCreator.customFilters.QtCreator.filterAttributes = qtcreator 1.2.80
+qhp.QtCreator.filterAttributes = qtcreator 1.2.91
+qhp.QtCreator.customFilters.QtCreator.name = Qt Creator 1.2.91
+qhp.QtCreator.customFilters.QtCreator.filterAttributes = qtcreator 1.2.91
# macros.qdocconf
@@ -211,5 +211,5 @@ HTML.footer = "
\n" \
"
\n" \
"Copyright © 2009 Nokia Corporation and/or its subsidiary(-ies) \n" \
"Trademarks \n" \
- "Qt Creator 1.2.80
\n" \
+ "Qt Creator 1.2.91
\n" \
"
"
diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts
index e9c3aa13957..4df4895a89c 100644
--- a/share/qtcreator/translations/qtcreator_fr.ts
+++ b/share/qtcreator/translations/qtcreator_fr.ts
@@ -10266,17 +10266,17 @@ p, li { white-space: pre-wrap; }
Filter Configuration
-
+ Configuration du filtre
Limit to prefix
-
+ Limiter au préfixe
Prefix:
-
+ Préfixe:
@@ -10284,36 +10284,36 @@ p, li { white-space: pre-wrap; }
Generic Directory Filter
-
+ Filtre de dossier générique
Filter Configuration
-
+ Configuration du filtre
Choose a directory to add
-
+ Choisir un répertoire à ajouter
%1 filter update: 0 files
-
+ Mise à jour du filtre %1: 0 fichiers
%1 filter update: %n files
-
-
+ Mise à jour du filtre %1: %n fichier
+ Mise à jour du filtre %1: %n fichiers
%1 filter update: canceled
-
+ Mise à jour du filtre %1: annulée
@@ -10321,12 +10321,12 @@ p, li { white-space: pre-wrap; }
Name:
-
+ Nom:
File Types:
-
+ Types de fichiers:
@@ -10336,38 +10336,38 @@ p, li { white-space: pre-wrap; }
Prefix:
-
+ Préfixe:
Specify a short word/abbreviation that can be used to restrict completions to files from this directory tree.
To do this, you type this shortcut and a space in the Locator entry field, and then the word to search for.
-
+ Spécifier a mot court ou une abbréviation qui peut être utilisé pour réstreindre la complétion aux fichiers de cette arborescence. Pour ce faire, entrez ce raccourci et un espace dans le champs Localisation, puis ensuite le mot à chercher.
Limit to prefix
-
+ Limiter au préfixe
Add...
-
+ Ajouter...
Edit...
-
+ Modifier...
Remove
-
+ Supprimer
Directories:
-
+ Dossiers:
@@ -10375,7 +10375,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Files in file system
-
+ Fichiers du système de fichier
@@ -10383,27 +10383,27 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Filter configuration
-
+ Configuration du filtre
Prefix:
-
+ Préfixe:
Limit to prefix
-
+ Limiter au préfixe
Include hidden files
-
+ Inclure les fichiers cachés
Filter:
-
+ Filtre:
@@ -10411,7 +10411,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Open documents
-
+ Ouvrir des documents
@@ -10419,7 +10419,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Available filters
-
+ Filtres disponibles
@@ -10427,7 +10427,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Indexing
-
+ Indexation
@@ -10435,27 +10435,27 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Refresh
-
+ Raffraîchir
Configure...
-
+ Configurer...
Locate...
-
+ Localiser...
Type to locate
-
+ Taper pour localiser
<type here>
-
+ <taper ici>
@@ -10463,37 +10463,37 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Configure Filters
-
+ Configurer les filtres
Add
-
+ Ajouter
Remove
-
+ Supprimer
Edit...
-
+ Modifier...
Refresh Interval:
-
+ Intervalle de raffraichissement:
min
-
+ min
Refresh now!
-
+ Raffraîchir maintenant!
@@ -10501,7 +10501,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
%1 (Prefix: %2)
-
+ %1 (Prefixe: %2)
@@ -10509,32 +10509,32 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Configure Filters
-
+ Configurer les filtres
Add
-
+ Ajouter
Remove
-
+ Supprimer
Edit
-
+ Modifier
Refresh Interval:
-
+ Intervalle de raffraichissement:
min
-
+ min
@@ -10542,102 +10542,102 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
&Pattern:
-
+ &Motif:
&Escaped Pattern:
-
+ Motif &échappé:
&Pattern Syntax:
-
+ Syntaxe du &motif:
&Text:
-
+ &Texte:
Case &Sensitive
-
+ &Sensible à la casse
&Minimal
-
+ &Minimale
Index of Match:
-
+ Index de la correspondance:
Matched Length:
-
+ Longueur de la correspondance:
Regular expression v1
-
+ Expression régulière v1
Regular expression v2
-
+ Expression régulière v2
Wildcard
-
+ Joker
Fixed string
-
+ Chaîne de caractères fixe
Capture %1:
-
+ Capture %1:
Match:
-
+ Correspondance:
Regular Expression
-
+ Expression régulière
Enter pattern from code...
-
+ Entrer un motif depuis le code...
Clear patterns
-
+ Effacer les motifs
Clear texts
-
+ Effacer les textes
Enter pattern from code
-
+ Entrer le motif depuis le code
Pattern
-
+ Motif
@@ -10645,27 +10645,27 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Creates a Qt Resource file (.qrc).
-
+ Crée une fichier ressource Qt (.qrc).
Qt Resource file
-
+ Fichier de ressource Qt
Qt
-
+ Qt
&Undo
-
+ &Annuler
&Redo
-
+ &Refaire
@@ -10673,7 +10673,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
untitled
-
+ sans titre
@@ -10681,17 +10681,17 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Save Changes
-
+ Sauvegarder les changements
The following files have unsaved changes:
-
+ Les fichiers suivants contiennent des modifications non enregistrées:
Automatically save all files before building
-
+ Sauvegarder automatiquement tous les fichiers avant de compiler
@@ -10699,12 +10699,12 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Options
-
+ Options
0
-
+ 0
@@ -10712,62 +10712,63 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Add Files
-
+ Ajouter des fichiers
Add Prefix
-
+ Ajouter un préfixe
Invalid file
-
+ Fichier invalide
Copy
-
+ Copier
Skip
-
+ ignorer ?
+ Passer
Abort
-
+ Abandonner
The file %1 is not in a subdirectory of the resource file. Continuing will result in an invalid resource file.
-
+ Le fichier %1 n'est pas dans un sous-dossier du fichier de ressource. Continuer résulterait en un fichier de ressource invalide.
Choose copy location
-
+ Choisir le chemin de la copie
Overwrite failed
-
+ L'écrasement a échoué
Could not overwrite file %1.
-
+ L'écrasement du fichier %1 a échoué.
Copying failed
-
+ Échec de la copie
Could not copy the file to %1.
-
+ La copie du fichier dans "%1" a échoué.
@@ -10775,72 +10776,72 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Add Files...
-
+ Ajouter des fichiers...
Change Alias...
-
+ Changer l'alias...
Add Prefix...
-
+ Ajouter un prefixe...
Change Prefix...
-
+ Changer le préfixe...
Change Language...
-
+ Changer la langue...
Remove Item
-
+ Supprimer l'élément
Open file
-
+ Ouvrir le fichier
All files (*)
-
+ Tous les fichiers (*)
Change Prefix
-
+ Changer le préfixe
Input Prefix:
-
+ Entrée du préfixe:
Change Language
-
+ Changer la langue
Language:
-
+ Langue:
Change File Alias
-
+ Changer l'alias du fichier
Alias:
-
+ Alias:
@@ -10848,62 +10849,62 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Keyboard Shortcuts
-
+ Rarccourcis clavier
Filter:
-
+ Filtre:
Command
-
+ Commande
Label
-
+ Libellé
Shortcut
-
+ Raccourci
Defaults
-
+ Restaurer
Import...
-
+ Importer...
Export...
-
+ Exporter...
Key Sequence
-
+ Combinaison de touches
Shortcut:
-
+ Raccourci:
Reset
-
+ Remise à zéro
Remove
-
+ Effacer
@@ -10911,7 +10912,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Debugging Helper Build Log
-
+ Journal de compilation de l'assistant de deboggage
@@ -10919,7 +10920,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Snippets
-
+ Extraits de code
@@ -10927,7 +10928,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Snippets
-
+ Extraits de code
@@ -10935,22 +10936,22 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Start Debugger
-
+ Lancer le débogueur
Executable:
-
+ Nom de l'exécutable:
Arguments:
-
+ Arguments:
Break at 'main':
-
+ S'arrêter sur 'main':
@@ -10958,27 +10959,27 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Start Debugger
-
+ Lancer le débogueur
Host and port:
-
+ Hôte et port:
Architecture:
-
+ Architecture:
Use server start script:
-
+ Utiliser le script de démarrage du serveur :
Server start script:
-
+ Script de démarrage du serveur :
@@ -10986,32 +10987,32 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Prompt to submit
-
+ Demander à chaque soumission
Subversion Command:
-
+ Commande Subversion:
Authentication
-
+ Identification
User name:
-
+ Nom d'utilisateur:
Password:
-
+ Mot de passe:
Subversion
-
+ Subversion
@@ -11019,7 +11020,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Subversion Command
-
+ Commande Subversion
@@ -11027,12 +11028,12 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Subversion Output
-
+ Sortie de Subversion
Subversion
-
+ Subversion
@@ -11040,7 +11041,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
&Subversion
-
+ &Subversion
@@ -11055,7 +11056,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Alt+S,Alt+A
-
+ Alt+S,Alt+A
@@ -11070,72 +11071,72 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Revert
-
+ Rétablir
Revert "%1"
-
+ Rétablir "%1"
Diff Project
-
+ Faire un diff sur le projet
Diff Current File
-
+ Faire un diff du fichier courant
Diff "%1"
-
+ Faire un diff de "%1"
Alt+S,Alt+D
-
+ Alt+S,Alt+D
Commit All Files
-
+ Faire un commit de tous les fichiers
Commit Current File
-
+ Faire un commit du fichier courant
Commit "%1"
-
+ Faire un commit de "%1"
Alt+S,Alt+C
-
+ Alt+S,Alt+C
Filelog Current File
-
+ Journal du fichier courant
Filelog "%1"
-
+ Journal du fichier "%1"
Annotate Current File
-
+ Annoter le fichier courant
Annotate "%1"
-
+ Annoter "%1"
@@ -11155,12 +11156,12 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Commit
-
+ Faire un commit
Diff Selected Files
-
+ Faire un diff sur tous les fichiers sélectionnés
@@ -11175,7 +11176,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Closing Subversion Editor
- Fermer l'éditeur Subversion
+ Fermeture de l'éditeur Subversion
@@ -11185,12 +11186,12 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
The commit message check failed. Do you want to commit the change?
-
+ La vérification du message de commit a échoué. Voulez-vous soumettre vos modifications ?
The file has been changed. Do you want to revert it?
-
+ Le fichier a été modifié. Voulez-vous le rétablir ?
@@ -11232,8 +11233,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
%1 Executing: %2 %3
<timestamp> Executing: <executable> <arguments>
- %1 Exécute : %2 %3
-
+ %1 Exécution de : %2 %3
@@ -11261,7 +11261,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Subversion Submit
- Submit Subversion
+ Soumission sur Subversion
@@ -11270,7 +11270,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
%1 found
- %1 éléments trouvés
+ %1 élément(s) trouvé(s)
@@ -11385,7 +11385,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
In leading white space
- Espaces de début de ligne
+ Espaces en début de ligne
@@ -11443,7 +11443,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
Display &folding markers
-
+ Affiche les marqueurs de &pliage
@@ -11521,8 +11521,7 @@ To do this, you type this shortcut and a space in the Locator entry field, and t
The following encodings are likely to fit:
-
-Les encodages suivants pourraient fonctionner :
+ Les encodages suivants pourraient convenir :
@@ -11689,7 +11688,7 @@ Les encodages suivants pourraient fonctionner :
Triggers a quick fix in this scope
-
+ Lancer une réparation rapide dans ce contexte
@@ -11707,7 +11706,7 @@ Les encodages suivants pourraient fonctionner :
&Redo
-
+ &Refaire
@@ -11747,97 +11746,97 @@ Les encodages suivants pourraient fonctionner :
Ctrl+E, Ctrl+W
-
+ Ctrl+E, Ctrl+W
(Un)Comment &Selection
-
+ (Dé)Commenter la &Sélection
Ctrl+/
-
+ Ctrl+/
Cut &Line
-
+ Couper la &Ligne
Shift+Del
-
+ Shift+Suppr
Delete &Line
-
+ Effacer la &Ligne
Collapse
-
+ Plier
Ctrl+<
-
+ Ctrl+<
Expand
-
+ Étendre
Ctrl+>
-
+ Ctrl+>
(Un)&Collapse All
-
+ (Dé)&Plier tout
Increase Font Size
-
+ Augmenter la taille de la police
Ctrl++
-
+ Ctrl++
Decrease Font Size
-
+ Diminuer la taille de la police
Ctrl+-
-
+ Ctrl+-
Goto Block Start
-
+ Aller au début du bloc
Ctrl+[
-
+ Ctrl+[
Goto Block End
-
+ Aller à la fin du bloc
Ctrl+]
-
+ Ctrl+]
@@ -11847,7 +11846,7 @@ Les encodages suivants pourraient fonctionner :
Ctrl+{
-
+ Ctrl+{
@@ -11857,7 +11856,7 @@ Les encodages suivants pourraient fonctionner :
Ctrl+}
-
+ Ctrl+}
@@ -11867,7 +11866,7 @@ Les encodages suivants pourraient fonctionner :
Ctrl+U
-
+ Ctrl+U
@@ -11877,52 +11876,52 @@ Les encodages suivants pourraient fonctionner :
Ctrl+Shift+U
-
+ Ctrl+Shift+U
Move Line Up
-
+ Déplacer la ligne au-dessus
Ctrl+Shift+Up
-
+ Ctrl+Shift+Up
Move Line Down
-
+ Déplacer la ligne en-dessous
Ctrl+Shift+Down
-
+ Ctrl+Shift+Down
Copy Line Up
-
+ Copier la ligne au-dessus
Ctrl+Alt+Up
-
+ Ctrl+Alt+Up
Copy Line Down
-
+ Copier la ligne en-dessous
Ctrl+Alt+Down
-
+ Ctrl+Alt+Down
<line number>
-
+ <numéro de ligne>
@@ -11956,7 +11955,7 @@ Les encodages suivants pourraient fonctionner :
Search Scope
contexte/portée/autre ?
- Contexte de la recherche
+ Portée de la recherche
@@ -12186,17 +12185,17 @@ Les encodages suivants pourraient fonctionner :
Insert name...
- Inserez nom...
+ Inserez le nom...
Prompt to submit
-
+ Afficher avant de soumettre
Submit Message Check failed
-
+ La vérification du message de soumission a échoué
@@ -12276,7 +12275,7 @@ nom <email> alias </email>
Would you like to remove this file from the version control system (%1)?
Note: This might remove the local file.
Voulez-vous retirer ce fichier du système de gestion de versions (%1)?
-Note : Ceci risque de supprimer le fichier sur le disque.
+Note : Ceci risque de supprimer le fichier du disque.
@@ -12296,7 +12295,7 @@ Note : Ceci risque de supprimer le fichier sur le disque.
<Description>
- <Description>
+ <Description>
@@ -12351,12 +12350,12 @@ p, li { white-space: pre-wrap; }
Patch 1
-
+ Patch 1
Patch 2
-
+ Patch 2
@@ -12364,27 +12363,27 @@ p, li { white-space: pre-wrap; }
main
-
+ main
Text1:
-
+ Texte 1:
N/A
-
+ Indisponible
Text2:
-
+ Texte 2:
Text3:
-
+ Texte 3:
diff --git a/src/app/Info.plist b/src/app/Info.plist
index db37f1b65e9..6633f429d69 100644
--- a/src/app/Info.plist
+++ b/src/app/Info.plist
@@ -184,8 +184,8 @@
CFBundleIdentifier
com.nokia.qtcreator
CFBundleVersion
- 1.2.80
+ 1.2.91
CFBundleShortVersionString
- 1.2.80
+ 1.2.91
diff --git a/src/app/app.pro b/src/app/app.pro
index 69f5aa6fdce..b1830edff2f 100644
--- a/src/app/app.pro
+++ b/src/app/app.pro
@@ -17,7 +17,7 @@ win32 {
} else:macx {
CONFIG(debug, debug|release):LIBS *= -lExtensionSystem_debug -lAggregation_debug
else:LIBS *= -lExtensionSystem -lAggregation
-
+ LIBS += -framework CoreFoundation
ICON = qtcreator.icns
QMAKE_INFO_PLIST = Info.plist
FILETYPES.files = profile.icns prifile.icns
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 599459eb05c..f6a0dc45b3c 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -48,6 +48,20 @@
#ifdef Q_OS_MAC
# include
+# include
+
+// Helper function CoreFoundation -> Qt
+static QString stringFromCFString(CFStringRef value) {
+ QString retVal;
+ CFIndex maxLength = 2 * CFStringGetLength(value) + 1/*zero term*/; // max UTF8
+ char *cstring = new char[maxLength];
+ if (CFStringGetCString(CFStringRef(value), cstring, maxLength, kCFStringEncodingUTF8)) {
+ retVal = QString::fromUtf8(cstring);
+ }
+ delete cstring;
+ return retVal;
+}
+
#endif
enum { OptionIndent = 4, DescriptionIndent = 24 };
@@ -216,7 +230,29 @@ int main(int argc, char **argv)
QTranslator translator;
QTranslator qtTranslator;
- const QString &locale = QLocale::system().name();
+ QString locale = QLocale::system().name();
+#ifdef Q_OS_MAC
+ // because QLocale's system locale is basically useless on the Mac.
+ // Try to get the real system setting via core foundation
+ CFLocaleRef maclocale = CFLocaleCopyCurrent();
+ CFTypeRef value = CFLocaleGetValue(maclocale, kCFLocaleLanguageCode);
+ QString preferredLanguage = stringFromCFString(CFStringRef(value));
+ if (!preferredLanguage.isEmpty())
+ locale = preferredLanguage;
+ CFRelease(maclocale);
+ CFArrayRef languages = (CFArrayRef)CFPreferencesCopyValue(
+ CFSTR("AppleLanguages"),
+ kCFPreferencesAnyApplication,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesAnyHost);
+// CFShow(languages);
+ if (CFArrayGetCount(languages) > 0) {
+ QString preferredLanguage = stringFromCFString(CFStringRef(CFArrayGetValueAtIndex(languages, 0)));
+ if (!preferredLanguage.isEmpty())
+ locale = preferredLanguage;
+ }
+ CFRelease(languages);
+#endif
const QString &creatorTrPath = QCoreApplication::applicationDirPath()
+ QLatin1String(SHARE_PATH "/translations");
if (translator.load(QLatin1String("qtcreator_") + locale, creatorTrPath)) {
diff --git a/src/plugins/bineditor/BinEditor.pluginspec b/src/plugins/bineditor/BinEditor.pluginspec
index 41ad4dcf0f3..7a78f5dcb49 100644
--- a/src/plugins/bineditor/BinEditor.pluginspec
+++ b/src/plugins/bineditor/BinEditor.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,7 +19,7 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Binary editor component.
http://qt.nokia.com
-
-
+
+
diff --git a/src/plugins/bineditor/bineditor.cpp b/src/plugins/bineditor/bineditor.cpp
index 306de5d80ad..453e0d2f5b5 100644
--- a/src/plugins/bineditor/bineditor.cpp
+++ b/src/plugins/bineditor/bineditor.cpp
@@ -33,6 +33,9 @@
#include
#include
+#include
+#include
+
#include
#include
#include
@@ -77,6 +80,7 @@ BinEditor::BinEditor(QWidget *parent)
{
m_ieditor = 0;
m_inLazyMode = false;
+ m_baseAddr = 0;
m_blockSize = 4096;
init();
m_unmodifiedState = 0;
@@ -88,7 +92,7 @@ BinEditor::BinEditor(QWidget *parent)
m_cursorVisible = false;
m_caseSensitiveSearch = false;
setFocusPolicy(Qt::WheelFocus);
- m_addressString = QString(9, QLatin1Char(':'));
+ m_addressString = QString(16 + 3, QLatin1Char(':'));
}
BinEditor::~BinEditor()
@@ -108,7 +112,7 @@ void BinEditor::init()
m_numVisibleLines = viewport()->height() / m_lineHeight;
m_textWidth = 16 * m_charWidth + m_charWidth;
int m_numberWidth = fm.width(QChar(QLatin1Char('9')));
- m_labelWidth = 8 * m_numberWidth + 2 * m_charWidth;
+ m_labelWidth = 16 * m_numberWidth + 4 * m_charWidth;
int expectedCharWidth = m_columnWidth / 3;
const char *hex = "0123456789abcdef";
@@ -129,13 +133,19 @@ void BinEditor::init()
}
-void BinEditor::addLazyData(int block, const QByteArray &data)
+void BinEditor::addLazyData(quint64 block, const QByteArray &data)
{
Q_ASSERT(m_inLazyMode);
Q_ASSERT(data.size() == m_blockSize);
- m_lazyData.insert(block, data);
- m_lazyRequests.remove(block);
- viewport()->update();
+ const quint64 addr = block * m_blockSize;
+ if (addr >= m_baseAddr && addr <= m_baseAddr + m_size - 1) {
+ if (m_lazyData.size() * m_blockSize >= 64 * 1024 * 1024)
+ m_lazyData.clear();
+ const int translatedBlock = (addr - m_baseAddr) / m_blockSize;
+ m_lazyData.insert(translatedBlock, data);
+ m_lazyRequests.remove(translatedBlock);
+ viewport()->update();
+ }
}
bool BinEditor::requestDataAt(int pos, bool synchronous) const
@@ -144,11 +154,15 @@ bool BinEditor::requestDataAt(int pos, bool synchronous) const
return true;
int block = pos / m_blockSize;
- QMap::const_iterator it = m_lazyData.find(block);
+ QMap::const_iterator it = m_modifiedData.find(block);
+ if (it != m_modifiedData.constEnd())
+ return true;
+ it = m_lazyData.find(block);
if (it == m_lazyData.end()) {
if (!m_lazyRequests.contains(block)) {
m_lazyRequests.insert(block);
- emit const_cast(this)->lazyDataRequested(block, synchronous);
+ emit const_cast(this)->
+ lazyDataRequested(m_baseAddr / m_blockSize + block, synchronous);
if (!m_lazyRequests.contains(block))
return true; // synchronous data source
}
@@ -162,10 +176,8 @@ char BinEditor::dataAt(int pos) const
{
if (!m_inLazyMode)
return m_data.at(pos);
-
int block = pos / m_blockSize;
- return m_lazyData.value(block, m_emptyBlock).at(pos - (block*m_blockSize));
-
+ return blockData(block).at(pos - (block*m_blockSize));
}
void BinEditor::changeDataAt(int pos, char c)
@@ -175,8 +187,17 @@ void BinEditor::changeDataAt(int pos, char c)
return;
}
int block = pos / m_blockSize;
- if (m_lazyData.contains(block))
- m_lazyData[block][pos - (block*m_blockSize)] = c;
+ QMap::iterator it = m_modifiedData.find(block);
+ if (it != m_modifiedData.end()) {
+ it.value()[pos - (block*m_blockSize)] = c;
+ } else {
+ it = m_lazyData.find(block);
+ if (it != m_lazyData.end()) {
+ QByteArray data = it.value();
+ data[pos - (block*m_blockSize)] = c;
+ m_modifiedData.insert(block, data);
+ }
+ }
}
QByteArray BinEditor::dataMid(int from, int length) const
@@ -189,7 +210,7 @@ QByteArray BinEditor::dataMid(int from, int length) const
QByteArray data;
do {
- data += m_lazyData.value(block++, m_emptyBlock);
+ data += blockData(block++);
} while (block * m_blockSize < end);
return data.mid(from - ((from / m_blockSize) * m_blockSize), length);
@@ -203,7 +224,9 @@ QByteArray BinEditor::blockData(int block) const
data.resize(m_blockSize);
return data;
}
- return m_lazyData.value(block, m_emptyBlock);
+ QMap::const_iterator it = m_modifiedData.find(block);
+ return it != m_modifiedData.constEnd()
+ ? it.value() : m_lazyData.value(block, m_emptyBlock);
}
@@ -294,7 +317,9 @@ bool BinEditor::isReadOnly() const
void BinEditor::setData(const QByteArray &data)
{
m_inLazyMode = false;
+ m_baseAddr = 0;
m_lazyData.clear();
+ m_modifiedData.clear();
m_lazyRequests.clear();
m_data = data;
m_size = data.size();
@@ -316,21 +341,49 @@ QByteArray BinEditor::data() const
return m_data;
}
-bool BinEditor::applyModifications(QByteArray &data) const
+bool BinEditor::save(const QString &oldFileName, const QString &newFileName)
{
- if (!m_inLazyMode) {
- data = m_data;
- return true;
- }
- if (data.size() != m_size)
- return false;
- for (QMap::const_iterator it = m_lazyData.begin(); it != m_lazyData.end(); ++it) {
- ::memcpy(data.data() + it.key() * m_blockSize, it->constData(), m_blockSize);
+ if (m_inLazyMode) {
+ if (oldFileName != newFileName) {
+ QString tmpName;
+ {
+ QTemporaryFile tmp;
+ if (!tmp.open())
+ return false;
+ tmpName = tmp.fileName();
+ }
+ if (!QFile::copy(oldFileName, tmpName))
+ return false;
+ if (QFile::exists(newFileName) && !QFile::remove(newFileName))
+ return false;
+ if (!QFile::rename(tmpName, newFileName))
+ return false;
+ }
+ QFile output(newFileName);
+ if (!output.open(QIODevice::ReadWrite)) // QtBug: WriteOnly truncates.
+ return false;
+ const qint64 size = output.size();
+ for (QMap::const_iterator it = m_modifiedData.constBegin();
+ it != m_modifiedData.constEnd(); ++it) {
+ if (!output.seek(it.key() * m_blockSize))
+ return false;
+ if (output.write(it.value()) < m_blockSize)
+ return false;
+ }
+ if (size % m_blockSize != 0 && !output.resize(size))
+ return false;
+ } else {
+ QFile output(newFileName);
+ if (!output.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ return false;
+ if (output.write(m_data) < m_size)
+ return false;
}
+ setModified(false);
return true;
}
-void BinEditor::setLazyData(int cursorPosition, int size, int blockSize)
+void BinEditor::setLazyData(quint64 startAddr, int range, int blockSize)
{
m_inLazyMode = true;
m_blockSize = blockSize;
@@ -338,8 +391,16 @@ void BinEditor::setLazyData(int cursorPosition, int size, int blockSize)
m_emptyBlock = QByteArray(blockSize, '\0');
m_data.clear();
m_lazyData.clear();
+ m_modifiedData.clear();
m_lazyRequests.clear();
- m_size = size;
+
+ // In lazy mode, users can edit data in the range
+ // [startAddr - range/2, startAddr + range/2].
+ m_baseAddr = static_cast(range/2) > startAddr
+ ? 0 : startAddr - range/2;
+ m_baseAddr = (m_baseAddr / blockSize) * blockSize;
+ m_size = m_baseAddr != 0 && static_cast(range) >= -m_baseAddr
+ ? -m_baseAddr : range;
m_unmodifiedState = 0;
m_undoStack.clear();
@@ -347,7 +408,7 @@ void BinEditor::setLazyData(int cursorPosition, int size, int blockSize)
init();
- m_cursorPosition = cursorPosition;
+ m_cursorPosition = startAddr - m_baseAddr;
verticalScrollBar()->setValue(m_cursorPosition / 16);
emit cursorPositionChanged(m_cursorPosition);
@@ -471,8 +532,9 @@ int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensiti
QByteArrayMatcher matcher(pattern);
int block = from / m_blockSize;
-
- while (from < m_size) {
+ const int end =
+ qMin(static_cast(from) + SearchStride, m_size);
+ while (from < end) {
if (!requestDataAt(block * m_blockSize, true))
return -1;
QByteArray data = blockData(block);
@@ -488,7 +550,7 @@ int BinEditor::dataIndexOf(const QByteArray &pattern, int from, bool caseSensiti
++block;
from = block * m_blockSize - trailing;
}
- return -1;
+ return end == m_size ? -1 : -2;
}
int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSensitive) const
@@ -505,8 +567,8 @@ int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSen
char *b = buffer.data();
int block = from / m_blockSize;
-
- while (from > 0) {
+ const int lowerBound = qMax(0, from - SearchStride);
+ while (from > lowerBound) {
if (!requestDataAt(block * m_blockSize, true))
return -1;
QByteArray data = blockData(block);
@@ -522,11 +584,12 @@ int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSen
--block;
from = block * m_blockSize + (m_blockSize-1) + trailing;
}
- return -1;
+ return lowerBound == 0 ? -1 : -2;
}
-int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::FindFlags findFlags)
+int BinEditor::find(const QByteArray &pattern_arg, int from,
+ QTextDocument::FindFlags findFlags)
{
if (pattern_arg.isEmpty())
return 0;
@@ -541,7 +604,7 @@ int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::Find
bool backwards = (findFlags & QTextDocument::FindBackward);
int found = backwards ? dataLastIndexOf(pattern, from, caseSensitiveSearch)
: dataIndexOf(pattern, from, caseSensitiveSearch);
-
+
int foundHex = -1;
QByteArray hexPattern = calculateHexPattern(pattern_arg);
if (!hexPattern.isEmpty()) {
@@ -549,7 +612,8 @@ int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::Find
: dataIndexOf(hexPattern, from);
}
- int pos = (found >= 0 && (foundHex < 0 || found < foundHex)) ? found : foundHex;
+ int pos = foundHex == -1 || (found >= 0 && (foundHex == -2 || found < foundHex))
+ ? found : foundHex;
if (pos >= m_size)
pos = -1;
@@ -593,20 +657,21 @@ void BinEditor::drawItems(QPainter *painter, int x, int y, const QString &itemSt
}
}
-QString BinEditor::addressString(uint address)
+QString BinEditor::addressString(quint64 address)
{
QChar *addressStringData = m_addressString.data();
const char *hex = "0123456789abcdef";
- for (int h = 0; h < 4; ++h) {
- int shift = 4*(7-h);
- addressStringData[h] = hex[(address & (0xf<>shift];
- }
- for (int h = 4; h < 8; ++h) {
- int shift = 4*(7-h);
- addressStringData[h+1] = hex[(address & (0xf<>shift];
+
+ // Take colons into account.
+ const int indices[16] = {
+ 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18
+ };
+
+ for (int b = 0; b < 8; ++b) {
+ addressStringData[indices[15 - b*2]] = hex[(address >> (8*b)) & 0xf];
+ addressStringData[indices[14 - b*2]] = hex[(address >> (8*b + 4)) & 0xf];
}
return m_addressString;
-
}
void BinEditor::paintEvent(QPaintEvent *e)
@@ -663,7 +728,8 @@ void BinEditor::paintEvent(QPaintEvent *e)
continue;
- painter.drawText(-xoffset, i * m_lineHeight + m_ascent, addressString(((uint) line) * 16));
+ painter.drawText(-xoffset, i * m_lineHeight + m_ascent,
+ addressString(m_baseAddr + ((uint) line) * 16));
int cursor = -1;
if (line * 16 <= m_cursorPosition && m_cursorPosition < line * 16 + 16)
diff --git a/src/plugins/bineditor/bineditor.h b/src/plugins/bineditor/bineditor.h
index 0b9184b7c4c..4b7aa1653ff 100644
--- a/src/plugins/bineditor/bineditor.h
+++ b/src/plugins/bineditor/bineditor.h
@@ -31,8 +31,10 @@
#define BINEDITOR_H
#include
+#include
#include
#include
+#include
#include
#include
@@ -64,10 +66,10 @@ public:
inline int dataSize() const { return m_size; }
inline bool inLazyMode() const { return m_inLazyMode; }
- Q_INVOKABLE void setLazyData(int cursorPosition, int size, int blockSize = 4096);
+ Q_INVOKABLE void setLazyData(quint64 startAddr, int range, int blockSize = 4096);
inline int lazyDataBlockSize() const { return m_blockSize; }
- Q_INVOKABLE void addLazyData(int block, const QByteArray &data);
- bool applyModifications(QByteArray &data) const;
+ Q_INVOKABLE void addLazyData(quint64 block, const QByteArray &data);
+ bool save(const QString &oldFileName, const QString &newFileName);
void zoomIn(int range = 1);
void zoomOut(int range = 1);
@@ -86,7 +88,8 @@ public:
void setReadOnly(bool);
bool isReadOnly() const;
- int find(const QByteArray &pattern, int from = 0, QTextDocument::FindFlags findFlags = 0);
+ int find(const QByteArray &pattern, int from = 0,
+ QTextDocument::FindFlags findFlags = 0);
void selectAll();
void clear();
@@ -106,8 +109,9 @@ public:
bool isUndoAvailable() const { return m_undoStack.size(); }
bool isRedoAvailable() const { return m_redoStack.size(); }
- QString addressString(uint address);
+ QString addressString(quint64 address);
+ static const int SearchStride = 1024 * 1024;
public Q_SLOTS:
void setFontSettings(const TextEditor::FontSettings &fs);
@@ -121,7 +125,7 @@ Q_SIGNALS:
void copyAvailable(bool);
void cursorPositionChanged(int position);
- void lazyDataRequested(int block, bool syncronous);
+ void lazyDataRequested(quint64 block, bool synchronous);
protected:
void scrollContentsBy(int dx, int dy);
@@ -142,6 +146,7 @@ private:
QByteArray m_data;
QMap m_lazyData;
int m_blockSize;
+ QMap m_modifiedData;
mutable QSet m_lazyRequests;
QByteArray m_emptyBlock;
QByteArray m_lowerBlock;
@@ -169,6 +174,7 @@ private:
int m_numLines;
int m_numVisibleLines;
+ quint64 m_baseAddr;
bool m_cursorVisible;
int m_cursorPosition;
diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp
index ddbb6250a25..9782b9bb6d4 100644
--- a/src/plugins/bineditor/bineditorplugin.cpp
+++ b/src/plugins/bineditor/bineditorplugin.cpp
@@ -61,7 +61,11 @@ class BinEditorFind : public Find::IFindSupport
{
Q_OBJECT
public:
- BinEditorFind(BinEditor *editor) { m_editor = editor; m_incrementalStartPos = -1; }
+ BinEditorFind(BinEditor *editor)
+ {
+ m_editor = editor;
+ m_incrementalStartPos = m_contPos = -1;
+ }
~BinEditorFind() {}
bool supportsReplace() const { return false; }
@@ -70,7 +74,11 @@ public:
return IFindSupport::FindBackward | IFindSupport::FindCaseSensitively;
}
- void resetIncrementalSearch() { m_incrementalStartPos = -1; }
+ void resetIncrementalSearch()
+ {
+ m_incrementalStartPos = m_contPos = -1;
+ }
+
void clearResults() { m_editor->highlightSearchResults(QByteArray()); }
QString currentFindString() const { return QString(); }
QString completedFindString() const { return QString(); }
@@ -82,41 +90,68 @@ public:
return pos;
}
- int found = m_editor->find(pattern, pos, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags));
- if (found < 0)
- found = m_editor->find(pattern,
- (findFlags & Find::IFindSupport::FindBackward)?m_editor->dataSize()-1:0,
- Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags));
- return found;
+ return m_editor->find(pattern, pos, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags));
}
- bool findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags) {
+ Result findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags) {
QByteArray pattern = txt.toLatin1();
+ if (pattern != m_lastPattern)
+ resetIncrementalSearch(); // Because we don't search for nibbles.
+ m_lastPattern = pattern;
if (m_incrementalStartPos < 0)
m_incrementalStartPos = m_editor->selectionStart();
- int pos = m_incrementalStartPos;
+ if (m_contPos == -1)
+ m_contPos = m_incrementalStartPos;
findFlags &= ~Find::IFindSupport::FindBackward;
- int found = find(pattern, pos, findFlags);
- if (found >= 0)
+ int found = find(pattern, m_contPos, findFlags);
+ Result result;
+ if (found >= 0) {
+ result = Found;
m_editor->highlightSearchResults(pattern, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags));
- else
- m_editor->highlightSearchResults(QByteArray(), 0);
- return found >= 0;
+ m_contPos = -1;
+ } else {
+ if (found == -2) {
+ result = NotYetFound;
+ m_contPos +=
+ findFlags & Find::IFindSupport::FindBackward
+ ? -BinEditor::SearchStride : BinEditor::SearchStride;
+ } else {
+ result = NotFound;
+ m_contPos = -1;
+ m_editor->highlightSearchResults(QByteArray(), 0);
+ }
+ }
+ return result;
}
- bool findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags) {
+ Result findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags) {
QByteArray pattern = txt.toLatin1();
bool wasReset = (m_incrementalStartPos < 0);
- int pos = m_editor->cursorPosition();
- if (findFlags & Find::IFindSupport::FindBackward)
- pos = m_editor->selectionStart()-1;
- int found = find(pattern, pos, findFlags);
- if (found)
+ if (m_contPos == -1) {
+ m_contPos = m_editor->cursorPosition();
+ if (findFlags & Find::IFindSupport::FindBackward)
+ m_contPos = m_editor->selectionStart()-1;
+ }
+ int found = find(pattern, m_contPos, findFlags);
+ Result result;
+ if (found >= 0) {
+ result = Found;
m_incrementalStartPos = found;
- if (wasReset && found >= 0)
- m_editor->highlightSearchResults(pattern, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags));
- return found >= 0;
+ m_contPos = -1;
+ if (wasReset)
+ m_editor->highlightSearchResults(pattern, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags));
+ } else if (found == -2) {
+ result = NotYetFound;
+ m_contPos += findFlags & Find::IFindSupport::FindBackward
+ ? -BinEditor::SearchStride : BinEditor::SearchStride;
+ } else {
+ result = NotFound;
+ m_contPos = -1;
+ }
+
+ return result;
}
+
bool replaceStep(const QString &, const QString &,
Find::IFindSupport::FindFlags) { return false;}
int replaceAll(const QString &, const QString &,
@@ -125,6 +160,8 @@ public:
private:
BinEditor *m_editor;
int m_incrementalStartPos;
+ int m_contPos; // Only valid if last result was NotYetFound.
+ QByteArray m_lastPattern;
};
@@ -137,48 +174,35 @@ public:
m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
{
m_editor = parent;
- connect(m_editor, SIGNAL(lazyDataRequested(int, bool)), this, SLOT(provideData(int)));
+ connect(m_editor, SIGNAL(lazyDataRequested(quint64, bool)), this, SLOT(provideData(quint64)));
}
~BinEditorFile() {}
virtual QString mimeType() const { return m_mimeType; }
bool save(const QString &fileName = QString()) {
- QFile file(fileName);
-
- QByteArray data;
- if (m_editor->inLazyMode()) {
- QFile read(m_fileName);
- if (!read.open(QIODevice::ReadOnly))
- return false;
- data = read.readAll();
- read.close();
- if (!m_editor->applyModifications(data))
- return false;
- } else {
- data = m_editor->data();
- }
- if (file.open(QIODevice::WriteOnly)) {
- file.write(data);
- file.close();
- m_editor->setModified(false);
- m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName());
+ if (m_editor->save(m_fileName, fileName)) {
m_fileName = fileName;
+ m_editor->editorInterface()->
+ setDisplayName(QFileInfo(fileName).fileName());
emit changed();
return true;
+ } else {
+ return false;
}
- return false;
}
bool open(const QString &fileName) {
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
m_fileName = fileName;
- if (file.isSequential()) {
+ if (file.isSequential() && file.size() <= 64 * 1024 * 1024) {
m_editor->setData(file.readAll());
} else {
- m_editor->setLazyData(0, file.size());
- m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName());
+ m_editor->setLazyData(0, qMin(file.size(),
+ static_cast(INT_MAX-16)));
+ m_editor->editorInterface()->
+ setDisplayName(QFileInfo(fileName).fileName());
}
file.close();
return true;
@@ -187,7 +211,7 @@ public:
}
private slots:
- void provideData(int block) {
+ void provideData(quint64 block) {
QFile file(m_fileName);
if (file.open(QIODevice::ReadOnly)) {
int blockSize = m_editor->lazyDataBlockSize();
diff --git a/src/plugins/bookmarks/Bookmarks.pluginspec b/src/plugins/bookmarks/Bookmarks.pluginspec
index 68fef93b4bd..7e74335bd0b 100644
--- a/src/plugins/bookmarks/Bookmarks.pluginspec
+++ b/src/plugins/bookmarks/Bookmarks.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Bookmarks in text editors.
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec
index ae9cd238fbd..b2274b4cc8b 100644
--- a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec
+++ b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
CMake support
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/coreplugin/Core.pluginspec b/src/plugins/coreplugin/Core.pluginspec
index 5ef4f956652..88232587e1a 100644
--- a/src/plugins/coreplugin/Core.pluginspec
+++ b/src/plugins/coreplugin/Core.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index a21e52ab061..2583370df34 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.h
@@ -35,7 +35,7 @@ namespace Constants {
#define IDE_VERSION_MAJOR 1
#define IDE_VERSION_MINOR 2
-#define IDE_VERSION_RELEASE 80
+#define IDE_VERSION_RELEASE 91
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
diff --git a/src/plugins/coreplugin/editormanager/ieditor.h b/src/plugins/coreplugin/editormanager/ieditor.h
index 56c4e6fbc6d..5248b298a70 100644
--- a/src/plugins/coreplugin/editormanager/ieditor.h
+++ b/src/plugins/coreplugin/editormanager/ieditor.h
@@ -40,6 +40,7 @@ class CORE_EXPORT IEditor : public IContext
{
Q_OBJECT
public:
+
IEditor(QObject *parent = 0) : IContext(parent) {}
virtual ~IEditor() {}
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index e42d5c03423..af8576b8ac4 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -160,7 +160,7 @@ MainWindow::MainWindow() :
QCoreApplication::setOrganizationName(QLatin1String("Nokia"));
QSettings::setDefaultFormat(QSettings::IniFormat);
QString baseName = qApp->style()->objectName();
-#ifdef Q_WS_X11
+#ifdef Q_WS_X11
if (baseName == QLatin1String("windows")) {
// Sometimes we get the standard windows 95 style as a fallback
// e.g. if we are running on a KDE4 desktop
@@ -325,7 +325,7 @@ bool MainWindow::init(QString *errorMessage)
void MainWindow::modeChanged(Core::IMode *mode)
{
- if (mode == m_outputMode) {
+ if (mode == m_outputMode) {
int idx = OutputPaneManager::instance()->m_widgetComboBox->itemData(OutputPaneManager::instance()->m_widgetComboBox->currentIndex()).toInt();
IOutputPane *out = OutputPaneManager::instance()->m_pageMap.value(idx);
if (out && out->canFocus())
@@ -678,6 +678,7 @@ void MainWindow::registerDefaultActions()
cmd = am->registerAction(m_optionsAction, Constants::OPTIONS, m_globalContext);
#ifdef Q_WS_MAC
cmd->setDefaultKeySequence(QKeySequence("Ctrl+,"));
+ cmd->action()->setMenuRole(QAction::PreferencesRole);
#endif
mtools->addAction(cmd, Constants::G_DEFAULT_THREE);
connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
@@ -735,7 +736,11 @@ void MainWindow::registerDefaultActions()
cmd = am->registerAction(tmpaction, Constants::ABOUT_QTCREATOR, m_globalContext);
mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
tmpaction->setEnabled(true);
+#ifdef Q_WS_MAC
+ cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
+#endif
connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutQtCreator()));
+
//About Plugins Action
tmpaction = new QAction(tr("About &Plugins..."), this);
cmd = am->registerAction(tmpaction, Constants::ABOUT_PLUGINS, m_globalContext);
diff --git a/src/plugins/cpaster/CodePaster.pluginspec b/src/plugins/cpaster/CodePaster.pluginspec
index 564793e22ba..b5c583b2702 100644
--- a/src/plugins/cpaster/CodePaster.pluginspec
+++ b/src/plugins/cpaster/CodePaster.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Codepaster plugin for pushing/fetching diff from server
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/cppeditor/CppEditor.pluginspec b/src/plugins/cppeditor/CppEditor.pluginspec
index f9817bfa1c3..8eee10b864c 100644
--- a/src/plugins/cppeditor/CppEditor.pluginspec
+++ b/src/plugins/cppeditor/CppEditor.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
C/C++ editor component.
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp
index 95e25b4b257..d2cda6f77df 100644
--- a/src/plugins/cppeditor/cpphighlighter.cpp
+++ b/src/plugins/cppeditor/cpphighlighter.cpp
@@ -73,6 +73,8 @@ void CppHighlighter::highlightBlock(const QString &text)
userData->setCollapseMode(TextBlockUserData::NoCollapse);
}
TextEditDocumentLayout::clearParentheses(currentBlock());
+ if (text.length()) // the empty line can still contain whitespace
+ setFormat(0, text.length(), visualSpaceFormat);
return;
}
@@ -171,7 +173,7 @@ void CppHighlighter::highlightBlock(const QString &text)
}
// mark the trailing white spaces
- if (! tokens.isEmpty()) {
+ {
const SimpleToken tk = tokens.last();
const int lastTokenEnd = tk.position() + tk.length();
if (text.length() > lastTokenEnd)
diff --git a/src/plugins/cpptools/CppTools.pluginspec b/src/plugins/cpptools/CppTools.pluginspec
index bce24e53817..9c97cd3dadb 100644
--- a/src/plugins/cpptools/CppTools.pluginspec
+++ b/src/plugins/cpptools/CppTools.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Tools for analyzing C/C++ code.
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/cvs/CVS.pluginspec b/src/plugins/cvs/CVS.pluginspec
index 94e7421af52..1af1e886c44 100644
--- a/src/plugins/cvs/CVS.pluginspec
+++ b/src/plugins/cvs/CVS.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
CVS integration.
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/debugger/Debugger.pluginspec b/src/plugins/debugger/Debugger.pluginspec
index 23f3babcccb..a410898c925 100644
--- a/src/plugins/debugger/Debugger.pluginspec
+++ b/src/plugins/debugger/Debugger.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,10 +19,10 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Debugger integration.
http://qt.nokia.com
-
-
-
-
+
+
+
+
Disable Cdb debugger engine
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 44c739362d4..3c6ac42e0c0 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -563,11 +563,11 @@ void CdbDebugEnginePrivate::clearDisplay()
m_debuggerManagerAccess->registerHandler()->removeAll();
}
-bool CdbDebugEngine::startDebugger(const QSharedPointer &sp)
+void CdbDebugEngine::startDebugger(const QSharedPointer &sp)
{
if (m_d->m_hDebuggeeProcess) {
warning(QLatin1String("Internal error: Attempt to start debugger while another process is being debugged."));
- return false;
+ emit startFailed();
}
m_d->clearDisplay();
@@ -627,7 +627,11 @@ bool CdbDebugEngine::startDebugger(const QSharedPointer
} else {
warning(errorMessage);
}
- return rc;
+
+ if (rc)
+ emit startSuccessful();
+ else
+ emit startFailed();
}
bool CdbDebugEngine::startAttachDebugger(qint64 pid, DebuggerStartMode sm, QString *errorMessage)
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 521b7b17201..18b66041652 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -62,7 +62,7 @@ public:
virtual void shutdown();
virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
- virtual bool startDebugger(const QSharedPointer &startParameters);
+ virtual void startDebugger(const QSharedPointer &startParameters);
virtual void exitDebugger();
virtual void detachDebugger();
virtual void updateWatchData(const WatchData &data);
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 3cdc4f16f56..c9be97b7260 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -87,5 +87,7 @@ include(cdb/cdb.pri)
include(gdb/gdb.pri)
include(script/script.pri)
include(tcf/tcf.pri)
+include(symbian/symbian.pri)
include(shared/shared.pri)
+
OTHER_FILES += Debugger.pluginspec
diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp
index ad1b6d67710..ede60b4c7e0 100644
--- a/src/plugins/debugger/debuggeragents.cpp
+++ b/src/plugins/debugger/debuggeragents.cpp
@@ -57,7 +57,7 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
-/*!
+/*!
\class MemoryViewAgent
Objects form this class are created in response to user actions in
@@ -84,30 +84,30 @@ MemoryViewAgent::~MemoryViewAgent()
m_editor->deleteLater();
}
-void MemoryViewAgent::init(quint64 addr)
+void MemoryViewAgent::init(quint64 addr)
{
Core::EditorManager *editorManager = Core::EditorManager::instance();
QString titlePattern = tr("Memory $");
m_editor = editorManager->openEditorWithContents(
Core::Constants::K_DEFAULT_BINARY_EDITOR,
&titlePattern);
- connect(m_editor->widget(), SIGNAL(lazyDataRequested(int,bool)),
- this, SLOT(fetchLazyData(int,bool)));
+ connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
+ this, SLOT(fetchLazyData(quint64,bool)));
editorManager->activateEditor(m_editor);
QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
- Q_ARG(int, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize));
+ Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
}
-void MemoryViewAgent::fetchLazyData(int block, bool sync)
+void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
{
Q_UNUSED(sync); // FIXME: needed support for incremental searching
- m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
+ m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
}
void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
{
QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
- Q_ARG(int, addr / BinBlockSize), Q_ARG(QByteArray, ba));
+ Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
}
diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h
index 2ee788ccedc..7e52f96fae9 100644
--- a/src/plugins/debugger/debuggeragents.h
+++ b/src/plugins/debugger/debuggeragents.h
@@ -63,7 +63,7 @@ public slots:
// Called from Engine
void addLazyData(quint64 addr, const QByteArray &data);
// Called from Editor
- void fetchLazyData(int block, bool sync);
+ void fetchLazyData(quint64 block, bool sync);
private:
void init(quint64 startaddr);
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index a17056ec1f8..5222fb8c1ae 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -103,6 +103,8 @@ namespace Internal {
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList *);
+IDebuggerEngine *createSymbianEngine(DebuggerManager *parent, QList *);
+
QDebug operator<<(QDebug str, const DebuggerStartParameters &p)
{
QDebug nospace = str.nospace();
@@ -180,9 +182,10 @@ void DebuggerStartParameters::clear()
///////////////////////////////////////////////////////////////////////
static IDebuggerEngine *gdbEngine = 0;
-static IDebuggerEngine *winEngine = 0;
static IDebuggerEngine *scriptEngine = 0;
+static IDebuggerEngine *symbianEngine = 0;
static IDebuggerEngine *tcfEngine = 0;
+static IDebuggerEngine *winEngine = 0;
DebuggerManager::DebuggerManager()
: m_startParameters(new DebuggerStartParameters),
@@ -195,9 +198,10 @@ DebuggerManager::~DebuggerManager()
{
#define doDelete(ptr) delete ptr; ptr = 0
doDelete(gdbEngine);
- doDelete(winEngine);
doDelete(scriptEngine);
+ doDelete(symbianEngine);
doDelete(tcfEngine);
+ doDelete(winEngine);
#undef doDelete
}
@@ -444,6 +448,8 @@ QList DebuggerManager::initializeEngines(unsigned enabledTy
QList rc;
if (enabledTypeFlags & GdbEngineType)
gdbEngine = createGdbEngine(this, &rc);
+ if (enabledTypeFlags & SymbianEngineType)
+ symbianEngine = createSymbianEngine(this, &rc);
winEngine = createWinEngine(this, (enabledTypeFlags & CdbEngineType), &rc);
if (enabledTypeFlags & ScriptEngineType)
scriptEngine = createScriptEngine(this, &rc);
@@ -693,9 +699,10 @@ void DebuggerManager::updateWatchData(const WatchData &data)
m_engine->updateWatchData(data);
}
-static inline QString msgEngineNotAvailable(const char *engine)
+static QString msgEngineNotAvailable(const char *engine)
{
- return DebuggerManager::tr("The application requires the debugger engine '%1', which is disabled.").arg(QLatin1String(engine));
+ return DebuggerManager::tr("The application requires the debugger engine '%1', "
+ "which is disabled.").arg(QLatin1String(engine));
}
static IDebuggerEngine *debuggerEngineForToolChain(ProjectExplorer::ToolChain::ToolChainType tc)
@@ -737,7 +744,16 @@ static IDebuggerEngine *determineDebuggerEngine(const QString &executable,
return scriptEngine;
}
- if (IDebuggerEngine *tce = debuggerEngineForToolChain(static_cast(toolChainType)))
+ if (executable.endsWith(_(".sym"))) {
+ if (!symbianEngine) {
+ *errorMessage = msgEngineNotAvailable("Symbian Engine");
+ return 0;
+ }
+ return symbianEngine;
+ }
+
+ if (IDebuggerEngine *tce = debuggerEngineForToolChain(
+ static_cast(toolChainType)))
return tce;
#ifndef Q_OS_WIN
@@ -772,7 +788,8 @@ static IDebuggerEngine *determineDebuggerEngine(int /* pid */,
int toolChainType,
QString *errorMessage)
{
- if (IDebuggerEngine *tce = debuggerEngineForToolChain(static_cast(toolChainType)))
+ if (IDebuggerEngine *tce = debuggerEngineForToolChain(
+ static_cast(toolChainType)))
return tce;
#ifdef Q_OS_WIN
// Preferably Windows debugger
@@ -844,11 +861,15 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl,
setBusyCursor(false);
setStatus(DebuggerProcessStartingUp);
- if (!m_engine->startDebugger(m_startParameters)) {
- setStatus(DebuggerProcessNotReady);
- debuggingFinished();
- return;
- }
+ connect(m_engine, SIGNAL(startFailed()), this, SLOT(startFailed()));
+ m_engine->startDebugger(m_startParameters);
+}
+
+void DebuggerManager::startFailed()
+{
+ disconnect(m_engine, SIGNAL(startFailed()), this, SLOT(startFailed()));
+ setStatus(DebuggerProcessNotReady);
+ debuggingFinished();
}
void DebuggerManager::cleanupViews()
@@ -1334,14 +1355,18 @@ void DebuggerManager::modulesDockToggled(bool on)
void DebuggerManager::showDebuggerOutput(int channel, const QString &msg)
{
- QTC_ASSERT(m_outputWindow, return);
- m_outputWindow->showOutput(channel, msg);
+ if (m_outputWindow)
+ m_outputWindow->showOutput(channel, msg);
+ else
+ qDebug() << "OUTPUT: " << channel << msg;
}
void DebuggerManager::showDebuggerInput(int channel, const QString &msg)
{
- QTC_ASSERT(m_outputWindow, return);
- m_outputWindow->showInput(channel, msg);
+ if (m_outputWindow)
+ m_outputWindow->showInput(channel, msg);
+ else
+ qDebug() << "INPUT: " << channel << msg;
}
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index de2a192abd1..e857f7bdb82 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -172,12 +172,18 @@ class CdbDebugEngine;
struct CdbDebugEnginePrivate;
// Flags for initialization
-enum DebuggerEngineTypeFlags {
- GdbEngineType = 0x1,
- ScriptEngineType = 0x2,
- CdbEngineType = 0x4,
- TcfEngineType = 0x8,
- AllEngineTypes = (GdbEngineType|ScriptEngineType|CdbEngineType|TcfEngineType)
+enum DebuggerEngineTypeFlags
+{
+ GdbEngineType = 0x01,
+ ScriptEngineType = 0x02,
+ CdbEngineType = 0x04,
+ TcfEngineType = 0x08,
+ SymbianEngineType = 0x10,
+ AllEngineTypes = GdbEngineType
+ | ScriptEngineType
+ | CdbEngineType
+ | TcfEngineType
+ | SymbianEngineType
};
// The construct below is not nice but enforces a bit of order. The
@@ -324,6 +330,8 @@ public slots:
void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
private slots:
+ void showDebuggerOutput(const QString &msg)
+ { showDebuggerOutput(LogDebug, msg); }
void showDebuggerOutput(int channel, const QString &msg);
void showDebuggerInput(int channel, const QString &msg);
void showApplicationOutput(const QString &data);
@@ -343,6 +351,7 @@ private slots:
void attemptBreakpointSynchronization();
void reloadFullStack();
void stepByInstructionTriggered();
+ void startFailed();
private:
//
@@ -421,6 +430,7 @@ private:
BreakpointData *findBreakpoint(const QString &fileName, int lineNumber);
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
+ // FIXME: Remove engine-specific state
QSharedPointer m_startParameters;
DebuggerRunControl *m_runControl;
QString m_dumperLib;
diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp
index 0f9b8b2d80c..59e9d0e451b 100644
--- a/src/plugins/debugger/debuggerrunner.cpp
+++ b/src/plugins/debugger/debuggerrunner.cpp
@@ -43,7 +43,8 @@
#include
-using namespace Debugger::Internal;
+namespace Debugger {
+namespace Internal {
using ProjectExplorer::RunConfiguration;
using ProjectExplorer::RunControl;
@@ -120,10 +121,10 @@ QWidget *DebuggerRunner::configurationWidget(RunConfigurationPtr runConfiguratio
DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
- DebuggerStartMode mode,
- const QSharedPointer &startParameters,
- QSharedPointer runConfiguration) :
- RunControl(runConfiguration),
+ DebuggerStartMode mode,
+ const QSharedPointer &startParameters,
+ QSharedPointer runConfiguration)
+ : RunControl(runConfiguration),
m_mode(mode),
m_startParameters(startParameters),
m_manager(manager),
@@ -140,44 +141,44 @@ DebuggerRunControl::DebuggerRunControl(DebuggerManager *manager,
Qt::QueuedConnection);
connect(this, SIGNAL(stopRequested()),
m_manager, SLOT(exitDebugger()));
+
+ if (!runConfiguration)
+ return;
+
+ // Enhance parameters by info from the project, but do not clobber
+ // arguments given in the dialogs
+ if (m_startParameters->executable.isEmpty())
+ m_startParameters->executable = runConfiguration->executable();
+ if (m_startParameters->environment.empty())
+ m_startParameters->environment = runConfiguration->environment().toStringList();
+ if (m_startParameters->workingDir.isEmpty())
+ m_startParameters->workingDir = runConfiguration->workingDirectory();
+ if (m_mode != StartExternal)
+ m_startParameters->processArgs = runConfiguration->commandLineArguments();
+ switch (m_startParameters->toolChainType) {
+ case ProjectExplorer::ToolChain::UNKNOWN:
+ case ProjectExplorer::ToolChain::INVALID:
+ m_startParameters->toolChainType = runConfiguration->toolChainType();
+ break;
+ default:
+ break;
+ }
+ if (const ProjectExplorer::Project *project = runConfiguration->project()) {
+ m_startParameters->buildDir =
+ project->buildDirectory(project->activeBuildConfiguration());
+ }
+ m_startParameters->useTerminal =
+ runConfiguration->runMode() == ApplicationRunConfiguration::Console;
+ m_dumperLibrary = runConfiguration->dumperLibrary();
+ m_dumperLibraryLocations = runConfiguration->dumperLibraryLocations();
}
void DebuggerRunControl::start()
{
m_running = true;
- ApplicationRunConfigurationPtr rc =
- runConfiguration().objectCast();
- if (rc) {
- // Enhance parameters by info from the project, but do not clobber
- // arguments given in the dialogs
- if (m_startParameters->executable.isEmpty())
- m_startParameters->executable = rc->executable();
- if (m_startParameters->environment.empty())
- m_startParameters->environment = rc->environment().toStringList();
- if (m_startParameters->workingDir.isEmpty())
- m_startParameters->workingDir = rc->workingDirectory();
- if (m_mode != StartExternal)
- m_startParameters->processArgs = rc->commandLineArguments();
- switch (m_startParameters->toolChainType) {
- case ProjectExplorer::ToolChain::UNKNOWN:
- case ProjectExplorer::ToolChain::INVALID:
- m_startParameters->toolChainType = rc->toolChainType();
- break;
- default:
- break;
- }
- m_manager->setQtDumperLibraryName(rc->dumperLibrary());
- m_manager->setQtDumperLibraryLocations(rc->dumperLibraryLocations());
- if (const ProjectExplorer::Project *project = rc->project()) {
- m_startParameters->buildDir = project->buildDirectory(project->activeBuildConfiguration());
- }
- m_startParameters->useTerminal = rc->runMode() == ApplicationRunConfiguration::Console;
- }
-
- //emit addToOutputWindow(this, tr("Debugging %1").arg(m_executable));
+ m_manager->setQtDumperLibraryName(m_dumperLibrary);
+ m_manager->setQtDumperLibraryLocations(m_dumperLibraryLocations);
m_manager->startNewDebugger(this, m_startParameters);
- emit started();
- //debuggingFinished();
}
void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data)
@@ -187,7 +188,6 @@ void DebuggerRunControl::slotAddToOutputWindowInline(const QString &data)
void DebuggerRunControl::stop()
{
- //qDebug() << "DebuggerRunControl::stop";
m_running = false;
emit stopRequested();
}
@@ -195,13 +195,13 @@ void DebuggerRunControl::stop()
void DebuggerRunControl::debuggingFinished()
{
m_running = false;
- //qDebug() << "DebuggerRunControl::finished";
- //emit addToOutputWindow(this, tr("Debugging %1 finished").arg(m_executable));
emit finished();
}
bool DebuggerRunControl::isRunning() const
{
- //qDebug() << "DebuggerRunControl::isRunning" << m_running;
return m_running;
}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/debuggerrunner.h b/src/plugins/debugger/debuggerrunner.h
index 0e0b0ac1e77..81f84588899 100644
--- a/src/plugins/debugger/debuggerrunner.h
+++ b/src/plugins/debugger/debuggerrunner.h
@@ -51,7 +51,8 @@ typedef QSharedPointer
typedef QSharedPointer
ApplicationRunConfigurationPtr;
-class DebuggerRunner : public ProjectExplorer::IRunConfigurationRunner
+class DebuggerRunner
+ : public ProjectExplorer::IRunConfigurationRunner
{
Q_OBJECT
@@ -59,7 +60,7 @@ public:
explicit DebuggerRunner(DebuggerManager *manager);
// ProjectExplorer::IRunConfigurationRunner
- virtual bool canRun(RunConfigurationPtr runConfiguration, const QString &mode);
+ bool canRun(RunConfigurationPtr runConfiguration, const QString &mode);
virtual ProjectExplorer::RunControl *run(RunConfigurationPtr runConfiguration, const QString &mode);
virtual QString displayName() const;
@@ -79,15 +80,16 @@ private:
};
// This is a job description
-class DebuggerRunControl : public ProjectExplorer::RunControl
+class DebuggerRunControl
+ : public ProjectExplorer::RunControl
{
Q_OBJECT
public:
- explicit DebuggerRunControl(DebuggerManager *manager,
- DebuggerStartMode mode,
- const QSharedPointer &sp,
- ApplicationRunConfigurationPtr runConfiguration);
+ DebuggerRunControl(DebuggerManager *manager,
+ DebuggerStartMode mode,
+ const QSharedPointer &sp,
+ ApplicationRunConfigurationPtr runConfiguration);
DebuggerStartMode startMode() const { return m_mode; }
@@ -109,27 +111,30 @@ private:
const QSharedPointer m_startParameters;
DebuggerManager *m_manager;
bool m_running;
+ QString m_dumperLibrary;
+ QStringList m_dumperLibraryLocations;
};
// A default run configuration for external executables or attaching to
// running processes by id.
-class DefaultApplicationRunConfiguration : public ProjectExplorer::ApplicationRunConfiguration
+class DefaultApplicationRunConfiguration
+ : public ProjectExplorer::ApplicationRunConfiguration
{
Q_OBJECT
public:
explicit DefaultApplicationRunConfiguration(const QString &executable = QString());
- virtual QString executable() const { return m_executable; }
- virtual RunMode runMode() const { return Gui; }
- virtual QString workingDirectory() const { return QString(); }
- virtual QStringList commandLineArguments() const { return QStringList(); }
+ virtual QString executable() const { return m_executable; }
+ virtual RunMode runMode() const { return Gui; }
+ virtual QString workingDirectory() const { return QString(); }
+ virtual QStringList commandLineArguments() const { return QStringList(); }
virtual ProjectExplorer::Environment environment() const
{ return ProjectExplorer::Environment(); }
- virtual QString dumperLibrary() const { return QString(); }
+ virtual QString dumperLibrary() const { return QString(); }
virtual QStringList dumperLibraryLocations() const { return QStringList(); }
virtual ProjectExplorer::ToolChain::ToolChainType toolChainType() const
{ return ProjectExplorer::ToolChain::UNKNOWN; }
- virtual QWidget *configurationWidget() { return 0; }
+ virtual QWidget *configurationWidget() { return 0; }
private:
const QString m_executable;
diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri
index 5154397aaec..9433d4be8d8 100644
--- a/src/plugins/debugger/gdb/gdb.pri
+++ b/src/plugins/debugger/gdb/gdb.pri
@@ -1,4 +1,5 @@
HEADERS += \
+ $$PWD/gdbprocessbase.h \
$$PWD/gdbmi.h \
$$PWD/gdbengine.h \
$$PWD/gdboptionspage.h \
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 89669c9df5e..452e9908ec4 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -138,13 +138,27 @@ static QByteArray parsePlainConsoleStream(const GdbResultRecord &record)
return out.mid(pos + 3);
}
+///////////////////////////////////////////////////////////////////////
+//
+// GdbProcess
+//
+///////////////////////////////////////////////////////////////////////
+
+void GdbProcess::attach(GdbEngine *engine) const
+{
+ QFileInfo fi(engine->startParameters().executable);
+ QString fileName = fi.absoluteFilePath();
+ engine->postCommand(_("-file-exec-and-symbols ") + fileName,
+ &GdbEngine::handleFileExecAndSymbols, "handleFileExecAndSymbols");
+}
+
///////////////////////////////////////////////////////////////////////
//
// GdbEngine
//
///////////////////////////////////////////////////////////////////////
-GdbEngine::GdbEngine(DebuggerManager *parent) :
+GdbEngine::GdbEngine(DebuggerManager *parent, GdbProcessBase *gdbProc) :
#ifdef Q_OS_WIN // Do injection loading with MinGW (call loading does not work with 64bit)
m_dumperInjectionLoad(true),
#else
@@ -153,6 +167,7 @@ GdbEngine::GdbEngine(DebuggerManager *parent) :
q(parent),
qq(parent->engineInterface())
{
+ m_gdbProc = gdbProc;
m_stubProc.setMode(Core::Utils::ConsoleProcess::Debug);
#ifdef Q_OS_UNIX
m_stubProc.setSettings(Core::ICore::instance()->settings());
@@ -164,20 +179,23 @@ GdbEngine::GdbEngine(DebuggerManager *parent) :
GdbEngine::~GdbEngine()
{
// prevent sending error messages afterwards
- m_gdbProc.disconnect(this);
+ m_gdbProc->disconnect(this);
+ delete m_gdbProc;
}
void GdbEngine::initializeConnections()
{
// Gdb Process interaction
- connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
+ connect(m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(gdbProcError(QProcess::ProcessError)));
- connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
+ connect(m_gdbProc, SIGNAL(readyReadStandardOutput()),
this, SLOT(readGdbStandardOutput()));
- connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
+ connect(m_gdbProc, SIGNAL(readyReadStandardError()),
this, SLOT(readGdbStandardError()));
- connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
+ connect(m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
q, SLOT(exitDebugger()));
+ connect(m_gdbProc, SIGNAL(started()),
+ this, SLOT(startDebugger2()));
connect(&m_stubProc, SIGNAL(processError(QString)),
this, SLOT(stubError(QString)));
@@ -265,6 +283,7 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
"invoked program '%1' is missing, or you may have insufficient "
"permissions to invoke the program.")
.arg(theDebuggerStringSetting(GdbLocation));
+ emitStartFailed();
break;
case QProcess::Crashed:
kill = false;
@@ -614,7 +633,7 @@ void GdbEngine::stubError(const QString &msg)
void GdbEngine::readGdbStandardError()
{
- qWarning() << "Unexpected gdb stderr:" << m_gdbProc.readAllStandardError();
+ qWarning() << "Unexpected gdb stderr:" << m_gdbProc->readAllStandardError();
}
void GdbEngine::readGdbStandardOutput()
@@ -622,7 +641,7 @@ void GdbEngine::readGdbStandardOutput()
int newstart = 0;
int scan = m_inbuffer.size();
- m_inbuffer.append(m_gdbProc.readAllStandardOutput());
+ m_inbuffer.append(m_gdbProc->readAllStandardOutput());
while (newstart < m_inbuffer.size()) {
int start = newstart;
@@ -651,7 +670,7 @@ void GdbEngine::interruptInferior()
{
qq->notifyInferiorStopRequested();
- if (m_gdbProc.state() == QProcess::NotRunning) {
+ if (m_gdbProc->state() == QProcess::NotRunning) {
debugMessage(_("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB"));
qq->notifyInferiorExited();
return;
@@ -698,7 +717,7 @@ void GdbEngine::postCommand(const QString &command, GdbCommandFlags flags,
GdbCommandCallback callback, const char *callbackName,
const QVariant &cookie)
{
- if (m_gdbProc.state() == QProcess::NotRunning) {
+ if (m_gdbProc->state() == QProcess::NotRunning) {
debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + command);
return;
}
@@ -742,10 +761,8 @@ void GdbEngine::flushCommand(GdbCommand &cmd)
if (cmd.flags & EmbedToken)
cmd.command = cmd.command.arg(currentToken());
- m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
- //emit gdbInputAvailable(QString(), " " + currentTime());
- //emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
emit gdbInputAvailable(LogInput, cmd.command);
+ executeDebuggerCommand(cmd.command);
}
void GdbEngine::handleResultRecord(const GdbResultRecord &record)
@@ -829,12 +846,12 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
void GdbEngine::executeDebuggerCommand(const QString &command)
{
- if (m_gdbProc.state() == QProcess::NotRunning) {
- debugMessage(_("NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: ") + command);
+ if (m_gdbProc->state() != QProcess::Running) {
+ debugMessage(_("GDB PROCESS NOT RUNNING, PLAIN CMD IGNORED: ") + command);
return;
}
- m_gdbProc.write(command.toLocal8Bit() + "\r\n");
+ m_gdbProc->write(command.toLatin1() + "\r\n");
}
void GdbEngine::handleTargetCore(const GdbResultRecord &, const QVariant &)
@@ -1061,7 +1078,6 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
return;
}
-
//MAC: bool isFirstStop = data.findChild("bkptno").data() == "1";
//!MAC: startSymbolName == data.findChild("frame").findChild("func")
if (m_waitingForFirstBreakpointToBeHit) {
@@ -1275,6 +1291,15 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
}
}
+ // FIXME: Hack, remove as soon as we get real stack traces.
+ if (m_gdbProc->isAdapter()) {
+ StackFrame f;
+ f.file = QString::fromLocal8Bit(fullName.data());
+ f.line = frame.findChild("line").data().toInt();
+ f.address = _(frame.findChild("addr").data());
+ q->gotoLocation(f, true);
+ }
+
//
// Stack
//
@@ -1434,15 +1459,16 @@ void GdbEngine::detachDebugger()
void GdbEngine::exitDebugger()
{
- debugMessage(_("GDBENGINE EXITDEBUGGER: %1").arg(m_gdbProc.state()));
- if (m_gdbProc.state() == QProcess::Starting) {
+ debugMessage(_("GDBENGINE EXITDEBUGGER: %1").arg(m_gdbProc->state()));
+ if (m_gdbProc->state() == QProcess::Starting) {
debugMessage(_("WAITING FOR GDB STARTUP TO SHUTDOWN: %1")
- .arg(m_gdbProc.state()));
- m_gdbProc.waitForStarted();
+ .arg(m_gdbProc->state()));
+ // FIXME: handle this!
+ //m_gdbProc->waitForStarted();
}
- if (m_gdbProc.state() == QProcess::Running) {
+ if (m_gdbProc->state() == QProcess::Running) {
debugMessage(_("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
- .arg(m_gdbProc.state()));
+ .arg(m_gdbProc->state()));
if (q->status() != DebuggerInferiorStopped
&& q->status() != DebuggerProcessStartingUp) {
QTC_ASSERT(q->status() == DebuggerInferiorRunning,
@@ -1455,17 +1481,17 @@ void GdbEngine::exitDebugger()
postCommand(_("kill"));
postCommand(_("-gdb-exit"), CB(handleExit));
// 20s can easily happen when loading webkit debug information
- if (!m_gdbProc.waitForFinished(20000)) {
+ if (!m_gdbProc->waitForFinished(20000)) {
debugMessage(_("FORCING TERMINATION: %1")
- .arg(m_gdbProc.state()));
- m_gdbProc.terminate();
- m_gdbProc.waitForFinished(20000);
+ .arg(m_gdbProc->state()));
+ m_gdbProc->terminate();
+ m_gdbProc->waitForFinished(20000);
}
}
- if (m_gdbProc.state() != QProcess::NotRunning) {
+ if (m_gdbProc->state() != QProcess::NotRunning) {
debugMessage(_("PROBLEM STOPPING DEBUGGER: STATE %1")
- .arg(m_gdbProc.state()));
- m_gdbProc.kill();
+ .arg(m_gdbProc->state()));
+ m_gdbProc->kill();
}
m_outputCollector.shutdown();
@@ -1479,18 +1505,20 @@ int GdbEngine::currentFrame() const
return qq->stackHandler()->currentIndex();
}
-bool GdbEngine::startDebugger(const QSharedPointer &sp)
+void GdbEngine::startDebugger(const QSharedPointer &sp)
{
+ m_startParameters = *sp;
// This should be set by the constructor or in exitDebugger().
QTC_ASSERT(m_debuggingHelperState == DebuggingHelperUninitialized,
initializeVariables());
QStringList gdbArgs;
- if (m_gdbProc.state() != QProcess::NotRunning) {
- debugMessage(_("GDB IS ALREADY RUNNING, STATE: %1").arg(m_gdbProc.state()));
- m_gdbProc.kill();
- return false;
+ if (m_gdbProc->state() != QProcess::NotRunning) {
+ debugMessage(_("GDB IS ALREADY RUNNING, STATE: %1").arg(m_gdbProc->state()));
+ m_gdbProc->kill();
+ emitStartFailed();
+ return;
}
//gdbArgs.prepend(_("--quiet"));
@@ -1501,62 +1529,73 @@ bool GdbEngine::startDebugger(const QSharedPointer &sp)
// nothing to do
} else if (q->startMode() == StartRemote) {
// Start the remote server
- if (sp->serverStartScript.isEmpty()) {
+ if (m_startParameters.serverStartScript.isEmpty()) {
q->showStatusMessage(_("No server start script given. "
"Assuming server runs already."));
} else {
- if (!sp->workingDir.isEmpty())
- m_uploadProc.setWorkingDirectory(sp->workingDir);
- if (!sp->environment.isEmpty())
- m_uploadProc.setEnvironment(sp->environment);
- m_uploadProc.start(_("/bin/sh ") + sp->serverStartScript);
+ if (!m_startParameters.workingDir.isEmpty())
+ m_uploadProc.setWorkingDirectory(m_startParameters.workingDir);
+ if (!m_startParameters.environment.isEmpty())
+ m_uploadProc.setEnvironment(m_startParameters.environment);
+ m_uploadProc.start(_("/bin/sh ") + m_startParameters.serverStartScript);
m_uploadProc.waitForStarted();
}
- } else if (sp->useTerminal) {
+ } else if (m_startParameters.useTerminal) {
m_stubProc.stop(); // We leave the console open, so recycle it now.
- m_stubProc.setWorkingDirectory(sp->workingDir);
- m_stubProc.setEnvironment(sp->environment);
- if (!m_stubProc.start(sp->executable, sp->processArgs))
- return false; // Error message for user is delivered via a signal.
+ m_stubProc.setWorkingDirectory(m_startParameters.workingDir);
+ m_stubProc.setEnvironment(m_startParameters.environment);
+ if (!m_stubProc.start(m_startParameters.executable,
+ m_startParameters.processArgs)) {
+ // Error message for user is delivered via a signal.
+ emitStartFailed();
+ return;
+ }
} else {
if (!m_outputCollector.listen()) {
QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"),
tr("Cannot set up communication with child process: %1")
.arg(m_outputCollector.errorString()));
- return false;
+ emitStartFailed();
+ return;
}
gdbArgs.prepend(_("--tty=") + m_outputCollector.serverName());
- if (!sp->workingDir.isEmpty())
- m_gdbProc.setWorkingDirectory(sp->workingDir);
- if (!sp->environment.isEmpty())
- m_gdbProc.setEnvironment(sp->environment);
+ if (!m_startParameters.workingDir.isEmpty())
+ m_gdbProc->setWorkingDirectory(m_startParameters.workingDir);
+ if (!m_startParameters.environment.isEmpty())
+ m_gdbProc->setEnvironment(m_startParameters.environment);
}
#if 0
qDebug() << "Command:" << q->settings()->m_gdbCmd;
- qDebug() << "WorkingDirectory:" << m_gdbProc.workingDirectory();
+ qDebug() << "WorkingDirectory:" << m_gdbProc->workingDirectory();
qDebug() << "ScriptFile:" << q->settings()->m_scriptFile;
- qDebug() << "Environment:" << m_gdbProc.environment();
+ qDebug() << "Environment:" << m_gdbProc->environment();
qDebug() << "Arguments:" << gdbArgs;
- qDebug() << "BuildDir:" << sp->buildDir;
- qDebug() << "ExeFile:" << sp->executable;
+ qDebug() << "BuildDir:" << m_startParameters.buildDir;
+ qDebug() << "ExeFile:" << m_startParameters.executable;
#endif
QString loc = theDebuggerStringSetting(GdbLocation);
q->showStatusMessage(tr("Starting Debugger: ") + loc + _c(' ') + gdbArgs.join(_(" ")));
- m_gdbProc.start(loc, gdbArgs);
- if (!m_gdbProc.waitForStarted()) {
- QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"),
- tr("Cannot start debugger: %1").arg(m_gdbProc.errorString()));
- m_outputCollector.shutdown();
- m_stubProc.blockSignals(true);
- m_stubProc.stop();
- m_stubProc.blockSignals(false);
- return false;
- }
+ m_gdbProc->start(loc, gdbArgs);
+}
+void GdbEngine::emitStartFailed()
+{
+ // QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"),
+ // tr("Cannot start debugger: %1").arg(m_gdbProc->errorString()));
+ m_outputCollector.shutdown();
+ m_stubProc.blockSignals(true);
+ m_stubProc.stop();
+ m_stubProc.blockSignals(false);
+ emit startFailed();
+}
+
+void GdbEngine::startDebugger2()
+{
+ debugMessage(_("STARTUP, PHASE 2"));
q->showStatusMessage(tr("Gdb Running..."));
postCommand(_("show version"), CB(handleShowVersion));
@@ -1637,54 +1676,56 @@ bool GdbEngine::startDebugger(const QSharedPointer &sp)
}
if (q->startMode() == AttachExternal || q->startMode() == AttachCrashedExternal) {
- postCommand(_("attach %1").arg(sp->attachPID), CB(handleAttach));
+ postCommand(_("attach %1").arg(m_startParameters.attachPID), CB(handleAttach));
// Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints();
} else if (q->startMode() == AttachCore) {
- QFileInfo fi(sp->executable);
+ QFileInfo fi(m_startParameters.executable);
QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
- QFileInfo fi2(sp->coreFile);
+ QFileInfo fi2(m_startParameters.coreFile);
// quoting core name below fails in gdb 6.8-debian
QString coreName = fi2.absoluteFilePath();
postCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols));
postCommand(_("target core ") + coreName, CB(handleTargetCore));
qq->breakHandler()->removeAllBreakpoints();
} else if (q->startMode() == StartRemote) {
- postCommand(_("set architecture %1").arg(sp->remoteArchitecture));
+ postCommand(_("set architecture %1").arg(m_startParameters.remoteArchitecture));
qq->breakHandler()->setAllPending();
- //QFileInfo fi(sp->executable);
+ //QFileInfo fi(m_startParameters.executable);
//QString fileName = fi.absoluteFileName();
- QString fileName = sp->executable;
+ QString fileName = m_startParameters.executable;
postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName), CB(handleFileExecAndSymbols));
// works only for > 6.8
postCommand(_("set target-async on"), CB(handleSetTargetAsync));
- } else if (sp->useTerminal) {
+ } else if (m_startParameters.useTerminal) {
qq->breakHandler()->setAllPending();
} else if (q->startMode() == StartInternal || q->startMode() == StartExternal) {
- QFileInfo fi(sp->executable);
- QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
- postCommand(_("-file-exec-and-symbols ") + fileName, CB(handleFileExecAndSymbols));
- //postCommand(_("file ") + fileName, handleFileExecAndSymbols);
- #ifdef Q_OS_MAC
- postCommand(_("sharedlibrary apply-load-rules all"));
- #endif
- if (!sp->processArgs.isEmpty())
- postCommand(_("-exec-arguments ") + sp->processArgs.join(_(" ")));
- #ifndef Q_OS_MAC
- if (!m_dumperInjectionLoad)
- postCommand(_("set auto-solib-add off"));
- postCommand(_("info target"), CB(handleStart));
- #else
- // On MacOS, breaking in at the entry point wreaks havoc.
- postCommand(_("tbreak main"));
- m_waitingForFirstBreakpointToBeHit = true;
- qq->notifyInferiorRunningRequested();
- postCommand(_("-exec-run"), CB(handleExecRun));
- #endif
+ m_gdbProc->attach(this);
+ if (m_gdbProc->isAdapter()) {
+ qq->notifyInferiorRunningRequested();
+ postCommand(_("-exec-continue"), CB(handleExecContinue));
+ } else {
+ #ifdef Q_OS_MAC
+ postCommand(_("sharedlibrary apply-load-rules all"));
+ #endif
+ if (!m_startParameters.processArgs.isEmpty())
+ postCommand(_("-exec-arguments ") + m_startParameters.processArgs.join(_(" ")));
+ #ifdef Q_OS_MAC
+ // On MacOS, breaking in at the entry point wreaks havoc.
+ postCommand(_("tbreak main"));
+ m_waitingForFirstBreakpointToBeHit = true;
+ qq->notifyInferiorRunningRequested();
+ postCommand(_("-exec-run"), CB(handleExecRun));
+ #else
+ if (!m_dumperInjectionLoad)
+ postCommand(_("set auto-solib-add off"));
+ postCommand(_("info target"), CB(handleStart));
+ #endif
+ }
qq->breakHandler()->setAllPending();
}
- return true;
+ emit startSuccessful();
}
void GdbEngine::continueInferior()
@@ -1749,7 +1790,6 @@ void GdbEngine::handleAttach(const GdbResultRecord &, const QVariant &)
void GdbEngine::handleSetTargetAsync(const GdbResultRecord &record, const QVariant &)
{
if (record.resultClass == GdbResultDone) {
- //postCommand(_("info target"), handleStart);
qq->notifyInferiorRunningRequested();
postCommand(_("target remote %1").arg(q->startParameters()->remoteChannel),
CB(handleTargetRemote));
@@ -2001,7 +2041,8 @@ void GdbEngine::sendInsertBreakpoint(int index)
}
// The argument is simply a C-quoted version of the argument to the
// non-MI "break" command, including the "original" quoting it wants.
- where = _("\"\\\"") + GdbMi::escapeCString(where) + _("\\\":") + data->lineNumber + _c('"');
+ where = _("\"\\\"%1\\\":%2\"")
+ .arg(GdbMi::escapeCString(where)).arg(data->lineNumber);
} else {
where = data->funcName;
}
@@ -2018,6 +2059,8 @@ void GdbEngine::sendInsertBreakpoint(int index)
// cmd += "-c " + data->condition + " ";
#else
QString cmd = _("-break-insert -f ");
+ if (m_gdbProc->isAdapter())
+ cmd = _("-break-insert ");
//if (!data->condition.isEmpty())
// cmd += _("-c ") + data->condition + ' ';
#endif
@@ -4198,7 +4241,7 @@ void GdbEngine::handleFetchDisassemblerByAddress0(const GdbResultRecord &record,
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList *opts)
{
opts->push_back(new GdbOptionsPage);
- return new GdbEngine(parent);
+ return new GdbEngine(parent, new GdbProcess);
}
} // namespace Internal
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 2694ec01fbd..53ae548e277 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -31,7 +31,9 @@
#define DEBUGGER_GDBENGINE_H
#include "idebuggerengine.h"
+#include "debuggermanager.h" // only for StartParameters
#include "gdbmi.h"
+#include "gdbprocessbase.h"
#include "outputcollector.h"
#include "watchutils.h"
@@ -56,6 +58,7 @@ QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
+
class DebuggerManager;
class IDebuggerManagerAccessForEngines;
class GdbResultRecord;
@@ -72,13 +75,50 @@ enum DebuggingHelperState
DebuggingHelperUnavailable,
};
+class GdbProcess : public GdbProcessBase
+{
+public:
+ GdbProcess(QObject *parent = 0)
+ : GdbProcessBase(parent)
+ {
+ connect(&m_proc, SIGNAL(error(QProcess::ProcessError)),
+ this, SIGNAL(error(QProcess::ProcessError)));
+ connect(&m_proc, SIGNAL(readyReadStandardOutput()),
+ this, SIGNAL(readyReadStandardOutput()));
+ connect(&m_proc, SIGNAL(readyReadStandardError()),
+ this, SIGNAL(readyReadStandardError()));
+ connect(&m_proc, SIGNAL(started()),
+ this, SIGNAL(started()));
+ connect(&m_proc, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SIGNAL(finished(int, QProcess::ExitStatus)));
+ }
+
+ void start(const QString &program, const QStringList &args,
+ QIODevice::OpenMode mode) { m_proc.start(program, args, mode); }
+ void kill() { m_proc.kill(); }
+ void terminate() { m_proc.terminate(); }
+ bool waitForStarted(int msecs) { return m_proc.waitForStarted(msecs); }
+ bool waitForFinished(int msecs) { return m_proc.waitForFinished(msecs); }
+ QProcess::ProcessState state() const { return m_proc.state(); }
+ QString errorString() const { return m_proc.errorString(); }
+ QByteArray readAllStandardError() { return m_proc.readAllStandardError(); }
+ QByteArray readAllStandardOutput() { return m_proc.readAllStandardOutput(); }
+ qint64 write(const char *data) { return m_proc.write(data); }
+ void setWorkingDirectory(const QString &dir) { m_proc.setWorkingDirectory(dir); }
+ void setEnvironment(const QStringList &env) { m_proc.setEnvironment(env); }
+ bool isAdapter() const { return false; }
+ void attach(GdbEngine *engine) const;
+
+private:
+ QProcess m_proc;
+};
class GdbEngine : public IDebuggerEngine
{
Q_OBJECT
public:
- GdbEngine(DebuggerManager *parent);
+ GdbEngine(DebuggerManager *parent, GdbProcessBase *gdbProc);
~GdbEngine();
signals:
@@ -87,6 +127,11 @@ signals:
void applicationOutputAvailable(const QString &output);
private:
+ friend class GdbProcess;
+ friend class SymbianAdapter;
+
+ const DebuggerStartParameters &startParameters() const
+ { return m_startParameters; }
//
// IDebuggerEngine implementation
//
@@ -98,7 +143,8 @@ private:
void shutdown();
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
- bool startDebugger(const QSharedPointer &sp);
+ void startDebugger(const QSharedPointer &sp);
+ Q_SLOT void startDebugger2();
void exitDebugger();
void detachDebugger();
@@ -166,6 +212,7 @@ public: // otherwise the Qt flag macros are unhappy
};
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
+
private:
typedef void (GdbEngine::*GdbCommandCallback)(const GdbResultRecord &record, const QVariant &cookie);
@@ -210,6 +257,7 @@ private slots:
void stubStarted();
void stubError(const QString &msg);
void uploadProcError(QProcess::ProcessError error);
+ void emitStartFailed();
private:
int terminationIndex(const QByteArray &buffer, int &length);
@@ -251,7 +299,7 @@ private:
QByteArray m_inbuffer;
- QProcess m_gdbProc;
+ GdbProcessBase *m_gdbProc;
QProcess m_uploadProc;
Core::Utils::ConsoleProcess m_stubProc;
@@ -395,6 +443,7 @@ private:
DebuggerManager * const q;
IDebuggerManagerAccessForEngines * const qq;
+ DebuggerStartParameters m_startParameters;
// make sure to re-initialize new members in initializeVariables();
};
diff --git a/src/plugins/debugger/gdb/gdbprocessbase.h b/src/plugins/debugger/gdb/gdbprocessbase.h
new file mode 100644
index 00000000000..71483cd2ee5
--- /dev/null
+++ b/src/plugins/debugger/gdb/gdbprocessbase.h
@@ -0,0 +1,80 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_PROCESSBASE_H
+#define DEBUGGER_PROCESSBASE_H
+
+#include
+#include
+
+namespace Debugger {
+namespace Internal {
+
+class GdbEngine;
+
+// GdbProcessBase is inherited by GdbProcess and the gdb/trk Adapter.
+// In the GdbProcess case it's just a wrapper around a QProcess running
+// gdb, in the Adapter case it's the interface to the gdb process in
+// the whole rfomm/gdb/gdbserver combo.
+class GdbProcessBase : public QObject
+{
+ Q_OBJECT
+
+public:
+ GdbProcessBase(QObject *parent = 0) : QObject(parent) {}
+
+ virtual void start(const QString &program, const QStringList &args,
+ QIODevice::OpenMode mode = QIODevice::ReadWrite) = 0;
+ virtual void kill() = 0;
+ virtual void terminate() = 0;
+ //virtual bool waitForStarted(int msecs = 30000) = 0;
+ virtual bool waitForFinished(int msecs = 30000) = 0;
+ virtual QProcess::ProcessState state() const = 0;
+ virtual QString errorString() const = 0;
+ virtual QByteArray readAllStandardError() = 0;
+ virtual QByteArray readAllStandardOutput() = 0;
+ virtual qint64 write(const char *data) = 0;
+ virtual void setWorkingDirectory(const QString &dir) = 0;
+ virtual void setEnvironment(const QStringList &env) = 0;
+ virtual bool isAdapter() const = 0;
+
+ virtual void attach(GdbEngine *engine) const = 0;
+
+signals:
+ void error(QProcess::ProcessError);
+ void started();
+ void readyReadStandardOutput();
+ void readyReadStandardError();
+ void finished(int, QProcess::ExitStatus);
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_PROCESSBASE_H
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index 89ff3029319..7ae53804a23 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -55,12 +55,14 @@ class WatchData;
class IDebuggerEngine : public QObject
{
+ Q_OBJECT
+
public:
IDebuggerEngine(QObject *parent = 0) : QObject(parent) {}
virtual void shutdown() = 0;
virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) = 0;
- virtual bool startDebugger(const QSharedPointer &startParameters) = 0;
+ virtual void startDebugger(const QSharedPointer &startParameters) = 0;
virtual void exitDebugger() = 0;
virtual void detachDebugger() {}
virtual void updateWatchData(const WatchData &data) = 0;
@@ -101,6 +103,10 @@ public:
virtual void fetchDisassembler(DisassemblerViewAgent *, const StackFrame &) {}
virtual void setRegisterValue(int regnr, const QString &value)
{ Q_UNUSED(regnr); Q_UNUSED(value); }
+
+signals:
+ void startSuccessful();
+ void startFailed();
};
} // namespace Internal
diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp
index 3f31ca421b0..45742e96798 100644
--- a/src/plugins/debugger/script/scriptengine.cpp
+++ b/src/plugins/debugger/script/scriptengine.cpp
@@ -217,7 +217,7 @@ void ScriptEngine::exitDebugger()
qq->notifyInferiorExited();
}
-bool ScriptEngine::startDebugger(const QSharedPointer &sp)
+void ScriptEngine::startDebugger(const QSharedPointer &sp)
{
if (!m_scriptEngine)
m_scriptEngine = new QScriptEngine(this);
@@ -233,15 +233,17 @@ bool ScriptEngine::startDebugger(const QSharedPointer &
QFileInfo fi(sp->executable);
m_scriptFileName = fi.absoluteFilePath();
QFile scriptFile(m_scriptFileName);
- if (!scriptFile.open(QIODevice::ReadOnly))
- return false;
+ if (!scriptFile.open(QIODevice::ReadOnly)) {
+ emit startFailed();
+ return;
+ }
QTextStream stream(&scriptFile);
m_scriptContents = stream.readAll();
scriptFile.close();
attemptBreakpointSynchronization();
qq->notifyInferiorRunningRequested();
QTimer::singleShot(0, this, SLOT(runInferior()));
- return true;
+ emit startSuccessful();
}
void ScriptEngine::continueInferior()
diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h
index 1f82a6ed583..32e8d3fe4b1 100644
--- a/src/plugins/debugger/script/scriptengine.h
+++ b/src/plugins/debugger/script/scriptengine.h
@@ -75,7 +75,7 @@ private:
void shutdown();
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
- bool startDebugger(const QSharedPointer &sp);
+ void startDebugger(const QSharedPointer &sp);
void exitDebugger();
diff --git a/src/plugins/debugger/symbian/symbian.pri b/src/plugins/debugger/symbian/symbian.pri
new file mode 100644
index 00000000000..afc2dbf9eef
--- /dev/null
+++ b/src/plugins/debugger/symbian/symbian.pri
@@ -0,0 +1,16 @@
+HEADERS += \
+ $$PWD/trkutils.h \
+ $$PWD/trkclient.h \
+ $$PWD/symbianadapter.h \
+ #$$PWD/gdboptionspage.h \
+
+SOURCES += \
+ $$PWD/trkutils.cpp \
+ $$PWD/trkclient.cpp \
+ $$PWD/symbianadapter.cpp \
+ $$PWD/symbianengine.cpp \
+ #$$PWD/gdboptionspage.cpp \
+
+#FORMS += $$PWD/gdboptionspage.ui
+
+#RESOURCES += $$PWD/gdb.qrc
diff --git a/src/plugins/debugger/symbian/symbianadapter.cpp b/src/plugins/debugger/symbian/symbianadapter.cpp
new file mode 100644
index 00000000000..212e1d5e18e
--- /dev/null
+++ b/src/plugins/debugger/symbian/symbianadapter.cpp
@@ -0,0 +1,1429 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "symbianadapter.h"
+#ifndef STANDALONE_RUNNER
+#include "gdb/gdbengine.h"
+#endif
+
+#define TrkCB(s) TrkCallback(this, &SymbianAdapter::s)
+
+
+using namespace trk;
+
+enum { KnownRegisters = RegisterPSGdb + 1};
+
+static const char *registerNames[KnownRegisters] =
+{
+ "A1", "A2", "A3", "A4",
+ 0, 0, 0, 0,
+ 0, 0, 0, "AP",
+ "IP", "SP", "LR", "PC",
+ "PSTrk", 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, "PSGdb"
+};
+
+static QByteArray dumpRegister(int n, uint value)
+{
+ QByteArray ba;
+ ba += ' ';
+ if (n < KnownRegisters && registerNames[n]) {
+ ba += registerNames[n];
+ } else {
+ ba += '#';
+ ba += QByteArray::number(n);
+ }
+ ba += "=" + hexxNumber(value);
+ return ba;
+}
+
+namespace Debugger {
+namespace Internal {
+
+trk::Endianness m_registerEndianness = LittleEndian;
+
+SymbianAdapter::SymbianAdapter()
+{
+ m_running = false;
+ m_gdbAckMode = true;
+ m_verbose = 2;
+ m_serialFrame = false;
+ m_bufferedMemoryRead = true;
+ m_rfcommDevice = "/dev/rfcomm0";
+
+ uid_t userId = getuid();
+ m_gdbServerName = QString("127.0.0.1:%1").arg(2222 + userId);
+
+ connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
+ this, SIGNAL(readyReadStandardError()));
+ connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
+ this, SIGNAL(readyReadStandardOutput()));
+ connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(handleGdbError(QProcess::ProcessError)));
+ connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(handleGdbFinished(int, QProcess::ExitStatus)));
+ connect(&m_gdbProc, SIGNAL(started()),
+ this, SLOT(handleGdbStarted()));
+ connect(&m_gdbProc, SIGNAL(stateChanged(QProcess::ProcessState)),
+ this, SLOT(handleGdbStateChanged(QProcess::ProcessState)));
+
+ connect(&m_rfcommProc, SIGNAL(readyReadStandardError()),
+ this, SLOT(handleRfcommReadyReadStandardError()));
+ connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(handleRfcommReadyReadStandardOutput()));
+ connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(handleRfcommError(QProcess::ProcessError)));
+ connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(handleRfcommFinished(int, QProcess::ExitStatus)));
+ connect(&m_gdbProc, SIGNAL(started()),
+ this, SLOT(handleRfcommStarted()));
+ connect(&m_gdbProc, SIGNAL(stateChanged(QProcess::ProcessState)),
+ this, SLOT(handleRfcommStateChanged(QProcess::ProcessState)));
+
+ if (m_verbose > 1)
+ m_trkDevice.setVerbose(true);
+ m_trkDevice.setSerialFrame(m_serialFrame);
+
+ connect(&m_trkDevice, SIGNAL(logMessage(QString)),
+ this, SLOT(trkLogMessage(QString)));
+}
+
+SymbianAdapter::~SymbianAdapter()
+{
+ m_gdbServer.close();
+ logMessage("Shutting down.\n");
+}
+
+void SymbianAdapter::trkLogMessage(const QString &msg)
+{
+ logMessage("TRK " + msg);
+}
+
+void SymbianAdapter::setGdbServerName(const QString &name)
+{
+ m_gdbServerName = name;
+}
+
+QString SymbianAdapter::gdbServerIP() const
+{
+ int pos = m_gdbServerName.indexOf(':');
+ if (pos == -1)
+ return m_gdbServerName;
+ return m_gdbServerName.left(pos);
+}
+
+uint SymbianAdapter::gdbServerPort() const
+{
+ int pos = m_gdbServerName.indexOf(':');
+ if (pos == -1)
+ return 0;
+ return m_gdbServerName.mid(pos + 1).toUInt();
+}
+
+QByteArray SymbianAdapter::trkContinueMessage()
+{
+ QByteArray ba;
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid);
+ return ba;
+}
+
+QByteArray SymbianAdapter::trkReadRegisterMessage()
+{
+ QByteArray ba;
+ appendByte(&ba, 0); // Register set, only 0 supported
+ appendShort(&ba, 0);
+ appendShort(&ba, RegisterCount - 1); // last register
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid);
+ return ba;
+}
+
+QByteArray SymbianAdapter::trkReadMemoryMessage(uint addr, uint len)
+{
+ QByteArray ba;
+ appendByte(&ba, 0x08); // Options, FIXME: why?
+ appendShort(&ba, len);
+ appendInt(&ba, addr);
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid);
+ return ba;
+}
+
+void SymbianAdapter::startInferior()
+{
+ QString errorMessage;
+ if (!m_trkDevice.open(m_rfcommDevice, &errorMessage)) {
+ emit output("LOOPING");
+ QTimer::singleShot(1000, this, SLOT(startInferior()));
+ return;
+ }
+
+ m_trkDevice.sendTrkInitialPing();
+ sendTrkMessage(0x01); // Connect
+ sendTrkMessage(0x05, TrkCB(handleSupportMask));
+ sendTrkMessage(0x06, TrkCB(handleCpuType));
+ sendTrkMessage(0x04, TrkCB(handleTrkVersions)); // Versions
+ //sendTrkMessage(0x09); // Unrecognized command
+ //sendTrkMessage(0x4a, 0,
+ // "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); // ?
+
+ QByteArray file("C:\\sys\\bin\\filebrowseapp.exe");
+ appendString(&ba, file, TargetByteOrder);
+ sendTrkMessage(0x40, TrkCB(handleCreateProcess), ba); // Create Item
+ //sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(startGdbServer));
+}
+
+void SymbianAdapter::logMessage(const QString &msg)
+{
+ if (m_verbose)
+ emit output(msg);
+}
+
+//
+// Gdb
+//
+void SymbianAdapter::handleGdbConnection()
+{
+ logMessage("HANDLING GDB CONNECTION");
+
+ m_gdbConnection = m_gdbServer.nextPendingConnection();
+ connect(m_gdbConnection, SIGNAL(disconnected()),
+ m_gdbConnection, SLOT(deleteLater()));
+ connect(m_gdbConnection, SIGNAL(readyRead()),
+ this, SLOT(readGdbServerCommand()));
+}
+
+static inline QString msgGdbPacket(const QString &p)
+{
+ return QLatin1String("gdb: ") + p;
+}
+
+void SymbianAdapter::readGdbServerCommand()
+{
+ QByteArray packet = m_gdbConnection->readAll();
+ m_gdbReadBuffer.append(packet);
+
+ logMessage("gdb: -> " + QString::fromAscii(packet));
+ if (packet != m_gdbReadBuffer)
+ logMessage("buffer: " + m_gdbReadBuffer);
+
+ QByteArray &ba = m_gdbReadBuffer;
+ while (ba.size()) {
+ char code = ba.at(0);
+ ba = ba.mid(1);
+
+ if (code == '+') {
+ //logMessage("ACK");
+ continue;
+ }
+
+ if (code == '-') {
+ logMessage("NAK: Retransmission requested");
+ continue;
+ }
+
+ if (code == char(0x03)) {
+ logMessage("INTERRUPT RECEIVED");
+ interruptInferior();
+ continue;
+ }
+
+ if (code != '$') {
+ logMessage("Broken package (2) " + quoteUnprintableLatin1(ba)
+ + hexNumber(code));
+ continue;
+ }
+
+ int pos = ba.indexOf('#');
+ if (pos == -1) {
+ logMessage("Invalid checksum format in "
+ + quoteUnprintableLatin1(ba));
+ continue;
+ }
+
+ bool ok = false;
+ uint checkSum = ba.mid(pos + 1, 2).toUInt(&ok, 16);
+ if (!ok) {
+ logMessage("Invalid checksum format 2 in "
+ + quoteUnprintableLatin1(ba));
+ return;
+ }
+
+ //logMessage(QString("Packet checksum: %1").arg(checkSum));
+ byte sum = 0;
+ for (int i = 0; i < pos; ++i)
+ sum += ba.at(i);
+
+ if (sum != checkSum) {
+ logMessage(QString("ERROR: Packet checksum wrong: %1 %2 in "
+ + quoteUnprintableLatin1(ba)).arg(checkSum).arg(sum));
+ }
+
+ QByteArray cmd = ba.left(pos);
+ ba.remove(0, pos + 3);
+ handleGdbServerCommand(cmd);
+ }
+}
+
+bool SymbianAdapter::sendGdbServerPacket(const QByteArray &packet, bool doFlush)
+{
+ if (!m_gdbConnection) {
+ logMessage(QString::fromLatin1("Cannot write to gdb: No connection (%1)")
+ .arg(QString::fromLatin1(packet)));
+ return false;
+ }
+ if (m_gdbConnection->state() != QAbstractSocket::ConnectedState) {
+ logMessage(QString::fromLatin1("Cannot write to gdb: Not connected (%1)")
+ .arg(QString::fromLatin1(packet)));
+ return false;
+ }
+ if (m_gdbConnection->write(packet) == -1) {
+ logMessage(QString::fromLatin1("Cannot write to gdb: %1 (%2)")
+ .arg(m_gdbConnection->errorString()).arg(QString::fromLatin1(packet)));
+ return false;
+ }
+ if (doFlush)
+ m_gdbConnection->flush();
+ return true;
+}
+
+void SymbianAdapter::sendGdbServerAck()
+{
+ if (!m_gdbAckMode)
+ return;
+ QByteArray packet = "+";
+ logMessage("gdb: <- " + packet);
+ sendGdbServerPacket(packet, false);
+}
+
+void SymbianAdapter::sendGdbServerMessage(const QByteArray &msg, const QByteArray &logNote)
+{
+ byte sum = 0;
+ for (int i = 0; i != msg.size(); ++i)
+ sum += msg.at(i);
+
+ char checkSum[30];
+ qsnprintf(checkSum, sizeof(checkSum) - 1, "%02x ", sum);
+
+ //logMessage(QString("Packet checksum: %1").arg(sum));
+
+ QByteArray packet;
+ packet.append("$");
+ packet.append(msg);
+ packet.append('#');
+ packet.append(checkSum);
+ int pad = qMax(0, 24 - packet.size());
+ logMessage("gdb: <- " + packet + QByteArray(pad, ' ') + logNote);
+ sendGdbServerPacket(packet, true);
+}
+
+void SymbianAdapter::sendGdbServerMessageAfterTrkResponse(const QByteArray &msg,
+ const QByteArray &logNote)
+{
+ QByteArray ba = msg + char(1) + logNote;
+ sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(reportToGdb), "", ba); // Answer gdb
+}
+
+void SymbianAdapter::reportToGdb(const TrkResult &result)
+{
+ QByteArray message = result.cookie.toByteArray();
+ QByteArray note;
+ int pos = message.lastIndexOf(char(1)); // HACK
+ if (pos != -1) {
+ note = message.mid(pos + 1);
+ message = message.left(pos);
+ }
+ message.replace("@CODESEG@", hexNumber(m_session.codeseg));
+ message.replace("@DATASEG@", hexNumber(m_session.dataseg));
+ message.replace("@PID@", hexNumber(m_session.pid));
+ message.replace("@TID@", hexNumber(m_session.tid));
+ sendGdbServerMessage(message, note);
+}
+
+QByteArray SymbianAdapter::trkBreakpointMessage(uint addr, uint len, bool armMode)
+{
+ QByteArray ba;
+ appendByte(&ba, 0x82); // unused option
+ appendByte(&ba, armMode /*bp.mode == ArmMode*/ ? 0x00 : 0x01);
+ appendInt(&ba, addr);
+ appendInt(&ba, len);
+ appendInt(&ba, 0x00000001);
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, 0xFFFFFFFF);
+ return ba;
+}
+
+void SymbianAdapter::handleGdbServerCommand(const QByteArray &cmd)
+{
+ // http://sourceware.org/gdb/current/onlinedocs/gdb_34.html
+ if (0) {}
+
+ else if (cmd == "!") {
+ sendGdbServerAck();
+ //sendGdbServerMessage("", "extended mode not enabled");
+ sendGdbServerMessage("OK", "extended mode enabled");
+ }
+
+ else if (cmd.startsWith("?")) {
+ logMessage(msgGdbPacket(QLatin1String("Query halted")));
+ // Indicate the reason the target halted.
+ // The reply is the same as for step and continue.
+ sendGdbServerAck();
+ // The command below will trigger fetching a stack trace while
+ // the process does not seem to be fully functional. Most notably
+ // the PC points to a 0x9..., which is not in "our" range
+ //sendGdbServerMessage("T05library:r;", "target halted (library load)");
+ //sendGdbServerMessage("S05", "target halted (trap)");
+ sendGdbServerMessage("S00", "target halted (trap)");
+ //sendGdbServerMessage("O" + QByteArray("Starting...").toHex());
+ }
+
+ else if (cmd == "c") {
+ logMessage(msgGdbPacket(QLatin1String("Continue")));
+ sendGdbServerAck();
+ QByteArray ba;
+ appendByte(&ba, 0); // options
+ appendInt(&ba, 0); // start address
+ appendInt(&ba, 0); // end address
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid);
+ sendTrkMessage(0x18, TrkCallback(), ba);
+ }
+
+ else if (cmd.startsWith("C")) {
+ logMessage(msgGdbPacket(QLatin1String("Continue with signal")));
+ // C sig[;addr] Continue with signal sig (hex signal number)
+ //Reply: See section D.3 Stop Reply Packets, for the reply specifications.
+ sendGdbServerAck();
+ bool ok = false;
+ uint signalNumber = cmd.mid(1).toInt(&ok, 16);
+ QByteArray ba;
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid);
+ sendTrkMessage(0x18, TrkCB(handleSignalContinue), ba, signalNumber); // Continue
+ }
+
+ else if (cmd.startsWith("D")) {
+ sendGdbServerAck();
+ sendGdbServerMessage("OK", "shutting down");
+ }
+
+ else if (cmd == "g") {
+ logMessage(msgGdbPacket(QLatin1String("Read registers")));
+ // Read general registers.
+ //sendGdbServerMessage("00000000", "read registers");
+ sendGdbServerAck();
+ sendTrkMessage(0x12, TrkCB(handleAndReportReadRegisters),
+ trkReadRegisterMessage());
+ }
+
+ else if (cmd.startsWith("Hc")) {
+ logMessage(msgGdbPacket(QLatin1String("Set thread & continue")));
+ // Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
+ // for step and continue operations
+ //$Hc-1#09
+ sendGdbServerAck();
+ sendGdbServerMessage("OK", "Set current thread for step & continue");
+ }
+
+ else if (cmd.startsWith("Hg")) {
+ logMessage(msgGdbPacket(QLatin1String("Set thread")));
+ // Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
+ // for 'other operations. 0 - any thread
+ //$Hg0#df
+ sendGdbServerAck();
+ m_session.currentThread = cmd.mid(2).toInt(0, 16);
+ sendGdbServerMessage("OK", "Set current thread "
+ + QByteArray::number(m_session.currentThread));
+ }
+
+ else if (cmd == "k") {
+ logMessage(msgGdbPacket(QLatin1String("kill")));
+ // kill
+ sendGdbServerAck();
+ QByteArray ba;
+ appendByte(&ba, 0); // ?
+ appendByte(&ba, 0); // Sub-command: Delete Process
+ appendInt(&ba, m_session.pid);
+ sendTrkMessage(0x41, TrkCallback(), ba, "Delete process"); // Delete Item
+ sendGdbServerMessageAfterTrkResponse("", "process killed");
+ }
+
+ else if (cmd.startsWith("m")) {
+ logMessage(msgGdbPacket(QLatin1String("Read memory")));
+ // m addr,length
+ sendGdbServerAck();
+ uint addr = 0, len = 0;
+ do {
+ const int pos = cmd.indexOf(',');
+ if (pos == -1)
+ break;
+ bool ok;
+ addr = cmd.mid(1, pos - 1).toUInt(&ok, 16);
+ if (!ok)
+ break;
+ len = cmd.mid(pos + 1).toUInt(&ok, 16);
+ if (!ok)
+ break;
+ } while (false);
+ if (len) {
+ readMemory(addr, len);
+ } else {
+ sendGdbServerMessage("E20", "Error " + cmd);
+ }
+ }
+ else if (cmd.startsWith("p")) {
+ logMessage(msgGdbPacket(QLatin1String("read register")));
+ // 0xf == current instruction pointer?
+ //sendGdbServerMessage("0000", "current IP");
+ sendGdbServerAck();
+ #if 0
+ A1 = 0, first integer-like argument
+ A4 = 3, last integer-like argument
+ AP = 11,
+ IP = 12,
+ SP = 13, Contains address of top of stack
+ LR = 14, address to return to from a function call
+ PC = 15, Contains program counter
+ F0 = 16, first floating point register
+ F3 = 19, last floating point argument register
+ F7 = 23, last floating point register
+ FPS = 24, floating point status register
+ PS = 25, Contains processor status
+ WR0, WMMX data registers.
+ WR15 = WR0 + 15,
+ WC0, WMMX control registers.
+ WCSSF = WC0 + 2,
+ WCASF = WC0 + 3,
+ WC7 = WC0 + 7,
+ WCGR0, WMMX general purpose registers.
+ WCGR3 = WCGR0 + 3,
+ WCGR7 = WCGR0 + 7,
+ NUM_REGS,
+
+ // Other useful registers.
+ FP = 11, Frame register in ARM code, if used.
+ THUMB_FP = 7, Frame register in Thumb code, if used.
+ NUM_ARG_REGS = 4,
+ LAST_ARG = A4,
+ NUM_FP_ARG_REGS = 4,
+ LAST_FP_ARG = F3
+ #endif
+ bool ok = false;
+ const uint registerNumber = cmd.mid(1).toInt(&ok, 16);
+ QByteArray logMsg = "Read Register";
+ if (registerNumber == RegisterPSGdb) {
+ QByteArray ba;
+ appendInt(&ba, m_snapshot.registers[RegisterPSTrk], m_registerEndianness);
+ logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]);
+ sendGdbServerMessage(ba.toHex(), logMsg);
+ } else if (registerNumber < RegisterCount) {
+ QByteArray ba;
+ appendInt(&ba, m_snapshot.registers[registerNumber], m_registerEndianness);
+ logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]);
+ sendGdbServerMessage(ba.toHex(), logMsg);
+ } else {
+ sendGdbServerMessage("0000", "read single unknown register #" + QByteArray::number(registerNumber));
+ //sendGdbServerMessage("E01", "read single unknown register");
+ }
+ }
+
+ else if (cmd == "qAttached") {
+ //$qAttached#8f
+ // 1: attached to an existing process
+ // 0: created a new process
+ sendGdbServerAck();
+ sendGdbServerMessage("0", "new process created");
+ //sendGdbServerMessage("1", "attached to existing process");
+ //sendGdbServerMessage("E01", "new process created");
+ }
+
+ else if (cmd.startsWith("qC")) {
+ logMessage(msgGdbPacket(QLatin1String("query thread id")));
+ // Return the current thread ID
+ //$qC#b4
+ sendGdbServerAck();
+ sendGdbServerMessageAfterTrkResponse("QC@TID@");
+ }
+
+ else if (cmd.startsWith("qSupported")) {
+ //$qSupported#37
+ //$qSupported:multiprocess+#c6
+ //logMessage("Handling 'qSupported'");
+ sendGdbServerAck();
+ if (0)
+ sendGdbServerMessage(QByteArray(), "nothing supported");
+ else
+ sendGdbServerMessage(
+ "PacketSize=7cf;"
+ "QPassSignals+;"
+ "qXfer:libraries:read+;"
+ //"qXfer:auxv:read+;"
+ "qXfer:features:read+");
+ }
+
+ else if (cmd == "qPacketInfo") {
+ // happens with gdb 6.4.50.20060226-cvs / CodeSourcery
+ // deprecated by qSupported?
+ sendGdbServerAck();
+ sendGdbServerMessage("", "FIXME: nothing?");
+ }
+
+ else if (cmd == "qOffsets") {
+ sendGdbServerAck();
+ sendGdbServerMessageAfterTrkResponse("TextSeg=@CODESEG@;DataSeg=@DATASEG@");
+ }
+
+ else if (cmd == "qSymbol::") {
+ if (m_verbose)
+ logMessage(msgGdbPacket(QLatin1String("notify can handle symbol lookup")));
+ // Notify the target that GDB is prepared to serve symbol lookup requests.
+ sendGdbServerAck();
+ if (1)
+ sendGdbServerMessage("OK", "no further symbols needed");
+ else
+ sendGdbServerMessage("qSymbol:" + QByteArray("_Z7E32Mainv").toHex(), "ask for more");
+ }
+
+ else if (cmd.startsWith("qXfer:features:read:target.xml:")) {
+ // $qXfer:features:read:target.xml:0,7ca#46...Ack
+ sendGdbServerAck();
+ sendGdbServerMessage("lsymbianelf ");
+ }
+
+ else if (cmd == "QStartNoAckMode") {
+ //$qSupported#37
+ //logMessage("Handling 'QStartNoAckMode'");
+ sendGdbServerAck();
+ sendGdbServerMessage("OK", "ack no-ack mode");
+ m_gdbAckMode = false;
+ }
+
+ else if (cmd.startsWith("QPassSignals")) {
+ // list of signals to pass directly to inferior
+ // $QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;4c;#8f
+ // happens only if "QPassSignals+;" is qSupported
+ sendGdbServerAck();
+ // FIXME: use the parameters
+ sendGdbServerMessage("OK", "passing signals accepted");
+ }
+
+ else if (cmd == "s" || cmd.startsWith("vCont;s")) {
+ logMessage(msgGdbPacket(QLatin1String("Step range")));
+ logMessage(" from " + hexxNumber(m_snapshot.registers[RegisterPC]));
+ sendGdbServerAck();
+ m_running = true;
+ QByteArray ba;
+ appendByte(&ba, 0x01); // options
+ appendInt(&ba, m_snapshot.registers[RegisterPC]); // start address
+ //appendInt(&ba, m_snapshot.registers[RegisterPC] + 4); // end address
+ appendInt(&ba, -1); // end address
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid);
+ sendTrkMessage(0x19, TrkCB(handleStepRange), ba, "Step range");
+ // FIXME: should be triggered by "real" stop"
+ //sendGdbServerMessageAfterTrkResponse("S05", "target halted");
+ }
+
+ else if (cmd == "vCont?") {
+ // actions supported by the vCont packet
+ sendGdbServerAck();
+ //sendGdbServerMessage("OK"); // we don't support vCont.
+ sendGdbServerMessage("vCont;c;C;s;S");
+ }
+
+ else if (cmd == "vCont;c") {
+ // vCont[;action[:thread-id]]...'
+ sendGdbServerAck();
+ m_running = true;
+ sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
+ }
+
+ else if (cmd.startsWith("vKill")) {
+ // kill
+ sendGdbServerAck();
+ QByteArray ba;
+ appendByte(&ba, 0); // Sub-command: Delete Process
+ appendInt(&ba, m_session.pid);
+ sendTrkMessage(0x41, TrkCallback(), ba, "Delete process"); // Delete Item
+ sendGdbServerMessageAfterTrkResponse("", "process killed");
+ }
+
+ else if (0 && cmd.startsWith("Z0,")) {
+ // Tell gdb we don't support software breakpoints
+ sendGdbServerMessage("");
+ }
+
+ else if (cmd.startsWith("Z0,") || cmd.startsWith("Z1,")) {
+ sendGdbServerAck();
+ // Insert breakpoint
+ logMessage(msgGdbPacket(QLatin1String("Insert breakpoint")));
+ // $Z0,786a4ccc,4#99
+ const int pos = cmd.lastIndexOf(',');
+ bool ok = false;
+ const uint addr = cmd.mid(3, pos - 3).toInt(&ok, 16);
+ const uint len = cmd.mid(pos + 1).toInt(&ok, 16);
+ //qDebug() << "ADDR: " << hexNumber(addr) << " LEN: " << len;
+ logMessage(QString::fromLatin1("Inserting breakpoint at 0x%1, %2")
+ .arg(addr, 0, 16).arg(len));
+
+ //---IDE------------------------------------------------------
+ // Command: 0x1B Set Break
+ //BreakType: 0x82
+ // Options: 0x00
+ // Address: 0x78674340 (2020033344) i.e + 0x00000340
+ // Length: 0x00000001 (1)
+ // Count: 0x00000000 (0)
+ //ProcessID: 0x000001b5 (437)
+ // ThreadID: 0xffffffff (-1)
+ // [1B 09 82 00 78 67 43 40 00 00 00 01 00 00 00 00
+ // 00 00 01 B5 FF FF FF FF]
+ const QByteArray ba = trkBreakpointMessage(addr, len, m_session.pid);
+ sendTrkMessage(0x1B, TrkCB(handleAndReportSetBreakpoint), ba, addr);
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 09 00 00 00 00 0A]
+ }
+
+ else if (cmd.startsWith("z0,") || cmd.startsWith("z1,")) {
+ sendGdbServerAck();
+ // Remove breakpoint
+ logMessage(msgGdbPacket(QLatin1String("Remove breakpoint")));
+ // $z0,786a4ccc,4#99
+ const int pos = cmd.lastIndexOf(',');
+ bool ok = false;
+ const uint addr = cmd.mid(3, pos - 3).toInt(&ok, 16);
+ const uint len = cmd.mid(pos + 1).toInt(&ok, 16);
+ const uint bp = m_session.addressToBP[addr];
+ if (bp == 0) {
+ logMessage(QString::fromLatin1("NO RECORDED BP AT 0x%1, %2")
+ .arg(addr, 0, 16).arg(len));
+ sendGdbServerMessage("E00");
+ } else {
+ //---IDE------------------------------------------------------
+ // Command: 0x1C Clear Break
+ // [1C 25 00 00 00 0A 78 6A 43 40]
+ m_session.addressToBP.remove(addr);
+ QByteArray ba;
+ appendByte(&ba, 0x00);
+ appendShort(&ba, bp);
+ appendInt(&ba, addr);
+ sendTrkMessage(0x1C, TrkCB(handleClearBreakpoint), ba, addr);
+ }
+ }
+
+ else if (cmd.startsWith("qPart:") || cmd.startsWith("qXfer:")) {
+ QByteArray data = cmd.mid(1 + cmd.indexOf(':'));
+ // "qPart:auxv:read::0,147": Read OS auxiliary data (see info aux)
+ bool handled = false;
+ if (data.startsWith("auxv:read::")) {
+ const int offsetPos = data.lastIndexOf(':') + 1;
+ const int commaPos = data.lastIndexOf(',');
+ if (commaPos != -1) {
+ bool ok1 = false, ok2 = false;
+ const int offset = data.mid(offsetPos, commaPos - offsetPos)
+ .toInt(&ok1, 16);
+ const int length = data.mid(commaPos + 1).toInt(&ok2, 16);
+ if (ok1 && ok2) {
+ const QString msg = QString::fromLatin1("Read of OS auxilary "
+ "vector (%1, %2) not implemented.").arg(offset).arg(length);
+ logMessage(msgGdbPacket(msg));
+ sendGdbServerMessage("E20", msg.toLatin1());
+ handled = true;
+ }
+ }
+ } // auxv read
+ if (!handled) {
+ const QString msg = QLatin1String("FIXME unknown 'XFER'-request: ")
+ + QString::fromAscii(cmd);
+ logMessage(msgGdbPacket(msg));
+ sendGdbServerMessage("E20", msg.toLatin1());
+ }
+ } // qPart/qXfer
+ else {
+ logMessage(msgGdbPacket(QLatin1String("FIXME unknown: ")
+ + QString::fromAscii(cmd)));
+ }
+}
+
+void SymbianAdapter::executeCommand(const QString &msg)
+{
+ if (msg == "EI") {
+ sendGdbMessage("-exec-interrupt");
+ } else if (msg == "C") {
+ sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
+ } else if (msg == "R") {
+ sendTrkMessage(0x18, TrkCB(handleReadRegisters),
+ trkReadRegisterMessage(), "READ REGS");
+ } else if (msg == "I") {
+ interruptInferior();
+ } else {
+ logMessage("EXECUTING GDB COMMAND " + msg);
+ sendGdbMessage(msg);
+ }
+}
+
+void SymbianAdapter::sendTrkMessage(byte code, TrkCallback callback,
+ const QByteArray &data, const QVariant &cookie)
+{
+ m_trkDevice.sendTrkMessage(code, callback, data, cookie);
+}
+
+void SymbianAdapter::sendTrkAck(byte token)
+{
+ logMessage(QString("SENDING ACKNOWLEDGEMENT FOR TOKEN %1").arg(int(token)));
+ m_trkDevice.sendTrkAck(token);
+}
+
+void SymbianAdapter::handleTrkError(const QString &msg)
+{
+ logMessage("## TRK ERROR: " + msg);
+}
+
+void SymbianAdapter::handleTrkResult(const TrkResult &result)
+{
+ if (result.isDebugOutput) {
+ sendTrkAck(result.token);
+ logMessage(QLatin1String("APPLICATION OUTPUT: ") +
+ QString::fromAscii(result.data));
+ sendGdbServerMessage("O" + result.data.toHex());
+ return;
+ }
+ logMessage("READ TRK " + result.toString());
+ QByteArray prefix = "READ BUF: ";
+ QByteArray str = result.toString().toUtf8();
+ switch (result.code) {
+ case 0x80: // ACK
+ break;
+ case 0xff: { // NAK. This mostly means transmission error, not command failed.
+ QString logMsg;
+ QTextStream(&logMsg) << prefix << "NAK: for token=" << result.token
+ << " ERROR: " << errorMessage(result.data.at(0)) << ' ' << str;
+ logMessage(logMsg);
+ break;
+ }
+ case 0x90: { // Notified Stopped
+ // 90 01 78 6a 40 40 00 00 07 23 00 00 07 24 00 00
+ const char *data = result.data.data();
+ const uint addr = extractInt(data);
+ const uint pid = extractInt(data + 4);
+ const uint tid = extractInt(data + 8);
+ logMessage(prefix + QString::fromLatin1("NOTE: PID %1/TID %2 "
+ "STOPPED at 0x%3").arg(pid).arg(tid).arg(addr, 0, 16));
+ sendTrkAck(result.token);
+ if (addr) {
+ // Todo: Do not send off GdbMessages if a synced gdb
+ // query is pending, queue instead
+ if (m_running) {
+ m_running = false;
+ sendGdbServerMessage("S05", "Target stopped");
+ }
+ } else {
+ logMessage(QLatin1String("Ignoring stop at 0"));
+ }
+ break;
+ }
+ case 0x91: { // Notify Exception (obsolete)
+ logMessage(prefix + "NOTE: EXCEPTION " + str);
+ sendTrkAck(result.token);
+ break;
+ }
+ case 0x92: { //
+ logMessage(prefix + "NOTE: INTERNAL ERROR: " + str);
+ sendTrkAck(result.token);
+ break;
+ }
+
+ // target->host OS notification
+ case 0xa0: { // Notify Created
+ const char *data = result.data.data();
+ const byte error = result.data.at(0);
+ // type: 1 byte; for dll item, this value is 2.
+ const byte type = result.data.at(1);
+ const uint pid = extractInt(data + 2);
+ const uint tid = extractInt(data + 6);
+ const uint codeseg = extractInt(data + 10);
+ const uint dataseg = extractInt(data + 14);
+ const uint len = extractShort(data + 18);
+ const QByteArray name = result.data.mid(20, len); // library name
+ m_session.modules += QString::fromAscii(name);
+ QString logMsg;
+ QTextStream str(&logMsg);
+ str << prefix << " NOTE: LIBRARY LOAD: token=" << result.token;
+ if (error)
+ str << " ERROR: " << int(error);
+ str << " TYPE: " << int(type) << " PID: " << pid << " TID: " << tid;
+ str << " CODE: " << hexxNumber(codeseg);
+ str << " DATA: " << hexxNumber(dataseg);
+ str << " NAME: '" << name << '\'';
+ logMessage(logMsg);
+ // This lets gdb trigger a register update etc
+ //sendGdbServerMessage("T05library:r;");
+ sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
+ break;
+ }
+ case 0xa1: { // NotifyDeleted
+ const ushort itemType = extractByte(result.data.data() + 1);
+ const ushort len = result.data.size() > 12
+ ? extractShort(result.data.data() + 10) : ushort(0);
+ const QString name = len
+ ? QString::fromAscii(result.data.mid(12, len)) : QString();
+ if (!name.isEmpty())
+ m_session.modules.removeAll(name);
+ logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3")
+ .arg(QString::fromAscii(prefix))
+ .arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS"))
+ .arg(name));
+ sendTrkAck(result.token);
+ if (itemType == 0) {
+ sendGdbServerMessage("W00", "Process exited");
+ //sendTrkMessage(0x02, TrkCB(handleDisconnect));
+ }
+ break;
+ }
+ case 0xa2: { // NotifyProcessorStarted
+ logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str);
+ sendTrkAck(result.token);
+ break;
+ }
+ case 0xa6: { // NotifyProcessorStandby
+ logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str);
+ sendTrkAck(result.token);
+ break;
+ }
+ case 0xa7: { // NotifyProcessorReset
+ logMessage(prefix + "NOTE: PROCESSOR RESET: " + str);
+ sendTrkAck(result.token);
+ break;
+ }
+ default: {
+ logMessage(prefix + "INVALID: " + str);
+ break;
+ }
+ }
+}
+
+void SymbianAdapter::handleCpuType(const TrkResult &result)
+{
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 03 00 04 00 00 04 00 00 00]
+ m_session.cpuMajor = result.data[1];
+ m_session.cpuMinor = result.data[2];
+ m_session.bigEndian = result.data[3];
+ m_session.defaultTypeSize = result.data[4];
+ m_session.fpTypeSize = result.data[5];
+ m_session.extended1TypeSize = result.data[6];
+ //m_session.extended2TypeSize = result.data[6];
+ QString logMsg;
+ QTextStream(&logMsg) << "HANDLE CPU TYPE: CPU=" << m_session.cpuMajor << '.'
+ << m_session.cpuMinor << " bigEndian=" << m_session.bigEndian
+ << " defaultTypeSize=" << m_session.defaultTypeSize
+ << " fpTypeSize=" << m_session.fpTypeSize
+ << " extended1TypeSize=" << m_session.extended1TypeSize;
+ logMessage(logMsg);
+}
+
+void SymbianAdapter::handleCreateProcess(const TrkResult &result)
+{
+ // 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]
+ 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 SymbianAdapter::handleReadRegisters(const TrkResult &result)
+{
+ logMessage(" RESULT: " + result.toString());
+ // [80 0B 00 00 00 00 00 C9 24 FF BC 00 00 00 00 00
+ // 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...]
+ if (result.errorCode()) {
+ logMessage("ERROR: " + result.errorString());
+ return;
+ }
+ const char *data = result.data.data() + 1; // Skip ok byte
+ for (int i = 0; i < RegisterCount; ++i)
+ m_snapshot.registers[i] = extractInt(data + 4 * i);
+}
+
+void SymbianAdapter::handleAndReportReadRegisters(const TrkResult &result)
+{
+ handleReadRegisters(result);
+ QByteArray ba;
+ for (int i = 0; i < 16; ++i) {
+ const uint reg = m_registerEndianness == LittleEndian
+ ? swapEndian(m_snapshot.registers[i]) : m_snapshot.registers[i];
+ ba += hexNumber(reg, 8);
+ }
+ QByteArray logMsg = "REGISTER CONTENTS: ";
+ if (m_verbose > 1) {
+ for (int i = 0; i < RegisterCount; ++i) {
+ logMsg += dumpRegister(i, m_snapshot.registers[i]);
+ logMsg += ' ';
+ }
+ }
+ sendGdbServerMessage(ba, logMsg);
+}
+
+static QString msgMemoryReadError(int code, uint addr, uint len = 0)
+{
+ const QString lenS = len ? QString::number(len) : QLatin1String("");
+ return QString::fromLatin1("Memory read error %1 at: 0x%2 %3")
+ .arg(code).arg(addr, 0 ,16).arg(lenS);
+}
+
+void SymbianAdapter::handleReadMemoryBuffered(const TrkResult &result)
+{
+ if (extractShort(result.data.data() + 1) + 3 != result.data.size())
+ logMessage("\n BAD MEMORY RESULT: " + result.data.toHex() + "\n");
+ const uint blockaddr = result.cookie.toUInt();
+ if (const int errorCode = result.errorCode()) {
+ logMessage(msgMemoryReadError(errorCode, blockaddr));
+ return;
+ }
+ const QByteArray ba = result.data.mid(3);
+ m_snapshot.memory.insert(blockaddr, ba);
+}
+
+// Format log message for memory access with some smartness about registers
+QByteArray SymbianAdapter::memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const
+{
+ QByteArray logMsg = "memory contents";
+ if (m_verbose > 1) {
+ logMsg += " addr: " + hexxNumber(addr);
+ // indicate dereferencing of registers
+ if (len == 4) {
+ if (addr == m_snapshot.registers[RegisterPC]) {
+ logMsg += "[PC]";
+ } else if (addr == m_snapshot.registers[RegisterPSTrk]) {
+ logMsg += "[PSTrk]";
+ } else if (addr == m_snapshot.registers[RegisterSP]) {
+ logMsg += "[SP]";
+ } else if (addr == m_snapshot.registers[RegisterLR]) {
+ logMsg += "[LR]";
+ } else if (addr > m_snapshot.registers[RegisterSP] &&
+ (addr - m_snapshot.registers[RegisterSP]) < 10240) {
+ logMsg += "[SP+"; // Stack area ...stack seems to be top-down
+ logMsg += QByteArray::number(addr - m_snapshot.registers[RegisterSP]);
+ logMsg += ']';
+ }
+ }
+ logMsg += " length ";
+ logMsg += QByteArray::number(len);
+ logMsg += " :";
+ logMsg += stringFromArray(ba, 16).toAscii();
+ }
+ return logMsg;
+}
+
+void SymbianAdapter::reportReadMemoryBuffered(const TrkResult &result)
+{
+ const qulonglong cookie = result.cookie.toULongLong();
+ const uint addr = cookie >> 32;
+ const uint len = uint(cookie);
+
+ // Gdb accepts less memory according to documentation.
+ // Send E on complete failure.
+ QByteArray ba;
+ uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
+ for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
+ const Snapshot::Memory::const_iterator it = m_snapshot.memory.constFind(blockaddr);
+ if (it == m_snapshot.memory.constEnd())
+ break;
+ ba.append(it.value());
+ }
+ const int previousChunkOverlap = addr % MemoryChunkSize;
+ if (previousChunkOverlap != 0 && ba.size() > previousChunkOverlap)
+ ba.remove(0, previousChunkOverlap);
+ if (ba.size() > int(len))
+ ba.truncate(len);
+
+ if (ba.isEmpty()) {
+ ba = "E20";
+ sendGdbServerMessage(ba, msgMemoryReadError(32, addr, len).toLatin1());
+ } else {
+ sendGdbServerMessage(ba.toHex(), memoryReadLogMessage(addr, len, ba));
+ }
+}
+
+void SymbianAdapter::handleReadMemoryUnbuffered(const TrkResult &result)
+{
+ //logMessage("UNBUFFERED MEMORY READ: " + stringFromArray(result.data));
+ const uint blockaddr = result.cookie.toUInt();
+ if (extractShort(result.data.data() + 1) + 3 != result.data.size())
+ logMessage("\n BAD MEMORY RESULT: " + result.data.toHex() + "\n");
+ if (const int errorCode = result.errorCode()) {
+ const QByteArray ba = "E20";
+ sendGdbServerMessage(ba, msgMemoryReadError(32, blockaddr).toLatin1());
+ } else {
+ const QByteArray ba = result.data.mid(3);
+ sendGdbServerMessage(ba.toHex(), memoryReadLogMessage(blockaddr, ba.size(), ba));
+ }
+}
+
+void SymbianAdapter::handleStepRange(const TrkResult &result)
+{
+ // [80 0f 00]
+ if (result.errorCode()) {
+ logMessage("ERROR: " + result.errorString());
+ return;
+ }
+ logMessage("STEPPING FINISHED ");
+ //sendGdbServerMessage("S05", "Stepping finished");
+}
+
+void SymbianAdapter::handleAndReportSetBreakpoint(const TrkResult &result)
+{
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 09 00 00 00 00 0A]
+ uint bpnr = extractByte(result.data.data());
+ uint addr = result.cookie.toUInt();
+ m_session.addressToBP[addr] = bpnr;
+ logMessage("SET BREAKPOINT " + hexxNumber(bpnr) + " "
+ + stringFromArray(result.data.data()));
+ sendGdbServerMessage("OK");
+ //sendGdbServerMessage("OK");
+}
+
+void SymbianAdapter::handleClearBreakpoint(const TrkResult &result)
+{
+ logMessage("CLEAR BREAKPOINT ");
+ if (result.errorCode()) {
+ logMessage("ERROR: " + result.errorString());
+ //return;
+ }
+ //---TRK------------------------------------------------------
+ // Command: 0x80 Acknowledge
+ // Error: 0x00
+ // [80 09 00 00 00 00 0A]
+ // FIXME:
+ sendGdbServerMessage("OK");
+}
+
+void SymbianAdapter::handleSignalContinue(const TrkResult &result)
+{
+ int signalNumber = result.cookie.toInt();
+ logMessage(" HANDLE SIGNAL CONTINUE: " + stringFromArray(result.data));
+ logMessage("NUMBER" + QString::number(signalNumber));
+ sendGdbServerMessage("O" + QByteArray("Console output").toHex());
+ sendGdbServerMessage("W81"); // "Process exited with result 1
+}
+
+void SymbianAdapter::handleSupportMask(const TrkResult &result)
+{
+ const char *data = result.data.data();
+ QByteArray str;
+ for (int i = 0; i < 32; ++i) {
+ //str.append(" [" + formatByte(data[i]) + "]: ");
+ for (int j = 0; j < 8; ++j)
+ if (data[i] & (1 << j))
+ str.append(QByteArray::number(i * 8 + j, 16));
+ }
+ logMessage("SUPPORTED: " + str);
+ }
+
+void SymbianAdapter::handleTrkVersions(const TrkResult &result)
+{
+ QString logMsg;
+ QTextStream str(&logMsg);
+ str << "Versions: ";
+ if (result.data.size() >= 5) {
+ str << "Trk version " << int(result.data.at(1)) << '.'
+ << int(result.data.at(2))
+ << ", Protocol version " << int(result.data.at(3))
+ << '.' << int(result.data.at(4));
+ }
+ logMessage(logMsg);
+}
+
+void SymbianAdapter::handleDisconnect(const TrkResult & /*result*/)
+{
+ logMessage(QLatin1String("Trk disconnected"));
+}
+
+void SymbianAdapter::readMemory(uint addr, uint len)
+{
+ Q_ASSERT(len < (2 << 16));
+
+ // We try to get medium-sized chunks of data from the device
+ if (m_verbose > 2)
+ logMessage(QString::fromLatin1("readMemory %1 bytes from 0x%2 blocksize=%3")
+ .arg(len).arg(addr, 0, 16).arg(MemoryChunkSize));
+
+ if (m_bufferedMemoryRead) {
+ uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
+ for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
+ if (!m_snapshot.memory.contains(blockaddr)) {
+ if (m_verbose)
+ logMessage(QString::fromLatin1("Requesting buffered "
+ "memory %1 bytes from 0x%2")
+ .arg(MemoryChunkSize).arg(blockaddr, 0, 16));
+ sendTrkMessage(0x10, TrkCB(handleReadMemoryBuffered),
+ trkReadMemoryMessage(blockaddr, MemoryChunkSize),
+ QVariant(blockaddr));
+ }
+ }
+ const qulonglong cookie = (qulonglong(addr) << 32) + len;
+ sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(reportReadMemoryBuffered),
+ QByteArray(), cookie);
+ } else {
+ if (m_verbose)
+ logMessage(QString::fromLatin1("Requesting unbuffered memory %1 "
+ "bytes from 0x%2").arg(len).arg(addr, 0, 16));
+ sendTrkMessage(0x10, TrkCB(handleReadMemoryUnbuffered),
+ trkReadMemoryMessage(addr, len), QVariant(addr));
+ }
+}
+
+void SymbianAdapter::interruptInferior()
+{
+ QByteArray ba;
+ // stop the thread (2) or the process (1) or the whole system (0)
+ // We choose 2, as 1 does not seem to work.
+ appendByte(&ba, 2);
+ appendInt(&ba, m_session.pid);
+ appendInt(&ba, m_session.tid); // threadID: 4 bytes Variable number of bytes.
+ sendTrkMessage(0x1a, TrkCallback(), ba, "Interrupting...");
+}
+
+void SymbianAdapter::handleGdbError(QProcess::ProcessError error)
+{
+ emit output(QString("GDB: Process Error %1: %2").arg(error).arg(errorString()));
+}
+
+void SymbianAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ emit output(QString("GDB: ProcessFinished %1 %2").arg(exitCode).arg(exitStatus));
+}
+
+void SymbianAdapter::handleGdbStarted()
+{
+ emit output(QString("GDB: Process Started"));
+ emit started();
+}
+
+void SymbianAdapter::handleGdbStateChanged(QProcess::ProcessState newState)
+{
+ emit output(QString("GDB: Process State %1").arg(newState));
+}
+
+void SymbianAdapter::run()
+{
+ emit output("### Starting SymbianAdapter");
+ m_rfcommProc.start("rfcomm listen " + m_rfcommDevice + " 1");
+ m_rfcommProc.waitForStarted();
+
+ if (m_rfcommProc.state() != QProcess::Running) {
+ emit finished(-44, QProcess::CrashExit);
+ return;
+ }
+
+ connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)),
+ this, SLOT(handleTrkResult(trk::TrkResult)));
+ connect(&m_trkDevice, SIGNAL(error(QString)),
+ this, SLOT(handleTrkError(QString)));
+
+ startInferior();
+}
+
+void SymbianAdapter::startGdb()
+{
+ if (!m_gdbServer.listen(QHostAddress(gdbServerIP()), gdbServerPort())) {
+ logMessage(QString("Unable to start the gdb server at %1: %2.")
+ .arg(m_gdbServerName).arg(m_gdbServer.errorString()));
+ emit finished(-45, QProcess::CrashExit);
+ return;
+ }
+
+ logMessage(QString("Gdb server running on %1.\nRegister endianness: %3.")
+ .arg(m_gdbServerName).arg(m_registerEndianness));
+
+ connect(&m_gdbServer, SIGNAL(newConnection()),
+ this, SLOT(handleGdbConnection()));
+
+ logMessage("STARTING GDB");
+ QStringList gdbArgs;
+ gdbArgs.append("--nx"); // Do not read .gdbinit file
+ gdbArgs.append("-i");
+ gdbArgs.append("mi");
+ m_gdbProc.start(QDir::currentPath() + "/cs-gdb", gdbArgs);
+}
+
+void SymbianAdapter::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");
+}
+
+//
+// GdbProcessBase
+//
+
+void SymbianAdapter::handleRfcommReadyReadStandardError()
+{
+ QByteArray ba = m_rfcommProc.readAllStandardError();
+ emit output(QString("RFCONN stderr: %1").arg(QString::fromLatin1(ba)));
+}
+
+void SymbianAdapter::handleRfcommReadyReadStandardOutput()
+{
+ QByteArray ba = m_rfcommProc.readAllStandardOutput();
+ emit output(QString("RFCONN stdout: %1").arg(QString::fromLatin1(ba)));
+}
+
+
+void SymbianAdapter::handleRfcommError(QProcess::ProcessError error)
+{
+ emit output(QString("RFCOMM: Process Error %1: %2").arg(error).arg(errorString()));
+}
+
+void SymbianAdapter::handleRfcommFinished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ emit output(QString("RFCOMM: ProcessFinished %1 %2").arg(exitCode).arg(exitStatus));
+}
+
+void SymbianAdapter::handleRfcommStarted()
+{
+ emit output(QString("RFCOMM: Process Started"));
+}
+
+void SymbianAdapter::handleRfcommStateChanged(QProcess::ProcessState newState)
+{
+ emit output(QString("RFCOMM: Process State %1").arg(newState));
+}
+
+//
+// GdbProcessBase
+//
+
+void SymbianAdapter::start(const QString &program, const QStringList &args,
+ QIODevice::OpenMode mode)
+{
+ Q_UNUSED(mode);
+ qDebug() << "SYMBIAN START" << program << args << mode;
+ run();
+}
+
+void SymbianAdapter::kill()
+{
+ m_gdbProc.kill();
+}
+
+void SymbianAdapter::terminate()
+{
+ m_gdbProc.terminate();
+}
+
+bool SymbianAdapter::waitForFinished(int msecs)
+{
+ return m_gdbProc.waitForFinished(msecs);
+}
+
+QProcess::ProcessState SymbianAdapter::state() const
+{
+ return m_gdbProc.state();
+}
+
+QString SymbianAdapter::errorString() const
+{
+ return m_gdbProc.errorString();
+}
+
+QByteArray SymbianAdapter::readAllStandardError()
+{
+ return m_gdbProc.readAllStandardError();
+}
+
+QByteArray SymbianAdapter::readAllStandardOutput()
+{
+ return m_gdbProc.readAllStandardOutput();
+}
+
+qint64 SymbianAdapter::write(const char *data)
+{
+ return m_gdbProc.write(data);
+}
+
+void SymbianAdapter::setWorkingDirectory(const QString &dir)
+{
+ m_gdbProc.setWorkingDirectory(dir);
+}
+
+void SymbianAdapter::setEnvironment(const QStringList &env)
+{
+ m_gdbProc.setEnvironment(env);
+}
+
+void SymbianAdapter::attach(GdbEngine *engine) const
+{
+#ifdef STANDALONE_RUNNER
+#else
+ QString fileName = engine->startParameters().executable;
+ engine->postCommand(_("add-symbol-file \"%1\" %2").arg(fileName)
+ .arg(m_session.codeseg));
+ engine->postCommand(_("symbol-file \"%1\"").arg(fileName));
+ engine->postCommand(_("target remote ") + gdbServerName());
+ engine->attemptBreakpointSynchronization();
+#endif
+}
+
+} // namespace Internal
+} // namespace Debugger
diff --git a/src/plugins/debugger/symbian/symbianadapter.h b/src/plugins/debugger/symbian/symbianadapter.h
new file mode 100644
index 00000000000..713692d44fa
--- /dev/null
+++ b/src/plugins/debugger/symbian/symbianadapter.h
@@ -0,0 +1,245 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_SYMBIANADAPTER_H
+#define DEBUGGER_SYMBIANADAPTER_H
+
+#include "trkutils.h"
+#include "trkclient.h"
+#include "../gdb/gdbprocessbase.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace Debugger {
+namespace Internal {
+
+struct GdbResult
+{
+ QByteArray data;
+};
+
+///////////////////////////////////////////////////////////////////////
+//
+// SymbianAdapter
+//
+///////////////////////////////////////////////////////////////////////
+
+class SymbianAdapter : public GdbProcessBase
+{
+ Q_OBJECT
+
+public:
+ typedef trk::TrkResult TrkResult;
+ typedef trk::TrkFunctor1 TrkCallback;
+ typedef trk::TrkFunctor1 GdbCallback;
+
+ SymbianAdapter();
+ ~SymbianAdapter();
+ void setGdbServerName(const QString &name);
+ QString gdbServerName() const { return m_gdbServerName; }
+ QString gdbServerIP() const;
+ uint gdbServerPort() const;
+ void setVerbose(int verbose) { m_verbose = verbose; }
+ void setSerialFrame(bool b) { m_serialFrame = b; }
+ void setBufferedMemoryRead(bool b) { m_bufferedMemoryRead = b; }
+ trk::Session &session() { return m_session; }
+
+public slots:
+ void startInferior();
+ void run();
+
+signals:
+ void output(const QString &msg);
+ void startSuccessful();
+ void startFailed();
+
+private slots:
+ void startGdb();
+
+private:
+ friend class RunnerGui;
+
+ QString m_rfcommDevice; // /dev/rfcomm0
+ QString m_gdbServerName; // 127.0.0.1:(2222+uid)
+
+ QProcess m_gdbProc;
+ QProcess m_rfcommProc;
+ bool m_running;
+
+public:
+ //
+ // Implementation of GdbProcessBase
+ //
+ void start(const QString &program, const QStringList &args,
+ QIODevice::OpenMode mode = QIODevice::ReadWrite);
+ void kill();
+ void terminate();
+ bool waitForFinished(int msecs = 30000);
+ QProcess::ProcessState state() const;
+ QString errorString() const;
+ QByteArray readAllStandardError();
+ QByteArray readAllStandardOutput();
+ qint64 write(const char *data);
+ void setWorkingDirectory(const QString &dir);
+ void setEnvironment(const QStringList &env);
+ bool isAdapter() const { return true; }
+ void attach(GdbEngine *engine) const;
+
+ //
+ // TRK
+ //
+ void sendTrkMessage(byte code,
+ TrkCallback callback = TrkCallback(),
+ const QByteArray &data = QByteArray(),
+ const QVariant &cookie = QVariant());
+ Q_SLOT void handleTrkResult(const trk::TrkResult &data);
+ Q_SLOT void handleTrkError(const QString &msg);
+
+ // convenience messages
+ void sendTrkAck(byte token);
+
+ void handleCpuType(const TrkResult &result);
+ void handleCreateProcess(const TrkResult &result);
+ void handleClearBreakpoint(const TrkResult &result);
+ void handleSignalContinue(const TrkResult &result);
+ void handleStop(const TrkResult &result);
+ void handleSupportMask(const TrkResult &result);
+ void handleTrkVersions(const TrkResult &result);
+ void handleDisconnect(const TrkResult &result);
+
+ void handleAndReportCreateProcess(const TrkResult &result);
+ void handleAndReportReadRegisters(const TrkResult &result);
+ QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const;
+ QByteArray trkContinueMessage();
+ QByteArray trkReadRegisterMessage();
+ QByteArray trkReadMemoryMessage(uint addr, uint len);
+ QByteArray trkBreakpointMessage(uint addr, uint len, bool armMode = true);
+ void handleAndReportSetBreakpoint(const TrkResult &result);
+ void handleReadMemoryBuffered(const TrkResult &result);
+ void handleReadMemoryUnbuffered(const TrkResult &result);
+ void handleStepRange(const TrkResult &result);
+ void handleReadRegisters(const TrkResult &result);
+ void reportReadMemoryBuffered(const TrkResult &result);
+ void reportToGdb(const TrkResult &result);
+
+ void readMemory(uint addr, uint len);
+ void interruptInferior();
+
+ trk::TrkDevice m_trkDevice;
+
+ //
+ // Gdb
+ //
+ struct GdbCommand
+ {
+ GdbCommand() : flags(0), callback(GdbCallback()), callbackName(0) {}
+
+ int flags;
+ GdbCallback callback;
+ const char *callbackName;
+ QString command;
+ QVariant cookie;
+ //QTime postTime;
+ };
+
+ void sendGdbMessage(const QString &msg,
+ GdbCallback callback = GdbCallback(),
+ const QVariant &cookie = QVariant());
+ Q_SLOT void handleGdbConnection();
+ Q_SLOT void readGdbServerCommand();
+ void readGdbResponse();
+ void handleGdbServerCommand(const QByteArray &cmd);
+ void sendGdbServerMessage(const QByteArray &msg,
+ const QByteArray &logNote = QByteArray());
+ void sendGdbServerMessageAfterTrkResponse(const QByteArray &msg,
+ const QByteArray &logNote = QByteArray());
+ void sendGdbServerAck();
+ bool sendGdbServerPacket(const QByteArray &packet, bool doFlush);
+
+ Q_SLOT void handleGdbError(QProcess::ProcessError error);
+ Q_SLOT void handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus);
+ Q_SLOT void handleGdbStarted();
+ Q_SLOT void handleGdbStateChanged(QProcess::ProcessState newState);
+
+ void logMessage(const QString &msg); // triggers output() if m_verbose
+ Q_SLOT void trkLogMessage(const QString &msg);
+
+ QTcpServer m_gdbServer;
+ QPointer m_gdbConnection;
+ QByteArray m_gdbReadBuffer;
+ bool m_gdbAckMode;
+
+ QHash m_gdbCookieForToken;
+
+ //
+ // Rfcomm
+ //
+ Q_SLOT void handleRfcommReadyReadStandardError();
+ Q_SLOT void handleRfcommReadyReadStandardOutput();
+ Q_SLOT void handleRfcommError(QProcess::ProcessError error);
+ Q_SLOT void handleRfcommFinished(int exitCode, QProcess::ExitStatus exitStatus);
+ Q_SLOT void handleRfcommStarted();
+ Q_SLOT void handleRfcommStateChanged(QProcess::ProcessState newState);
+
+ // Debuggee state
+ Q_SLOT void executeCommand(const QString &msg);
+ trk::Session m_session; // global-ish data (process id, target information)
+ trk::Snapshot m_snapshot; // local-ish data (memory and registers)
+ int m_verbose;
+ bool m_serialFrame;
+ bool m_bufferedMemoryRead;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_SYMBIANADAPTER_H
diff --git a/src/plugins/debugger/symbian/symbianengine.cpp b/src/plugins/debugger/symbian/symbianengine.cpp
new file mode 100644
index 00000000000..cb30e78fd9d
--- /dev/null
+++ b/src/plugins/debugger/symbian/symbianengine.cpp
@@ -0,0 +1,64 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#define QT_NO_CAST_FROM_ASCII
+
+#include "gdb/gdbengine.h"
+#include "symbianadapter.h"
+#include "debuggermanager.h"
+
+//#include "debuggerdialogs.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+
+namespace Debugger {
+namespace Internal {
+
+IDebuggerEngine *createSymbianEngine(DebuggerManager *parent,
+ QList *opts)
+{
+ Q_UNUSED(opts);
+ //opts->push_back(new GdbOptionsPage);
+ SymbianAdapter *adapter = new SymbianAdapter;
+ GdbEngine *engine = new GdbEngine(parent, adapter);
+ QObject::connect(adapter, SIGNAL(output(QString)),
+ parent, SLOT(showDebuggerOutput(QString)));
+ return engine;
+}
+
+} // namespace Internal
+} // namespace Debugger
+
+
diff --git a/tests/manual/trk/trkdevicex.cpp b/src/plugins/debugger/symbian/trkclient.cpp
similarity index 92%
rename from tests/manual/trk/trkdevicex.cpp
rename to src/plugins/debugger/symbian/trkclient.cpp
index d9abfdf1dfb..5ae9766ac5a 100644
--- a/tests/manual/trk/trkdevicex.cpp
+++ b/src/plugins/debugger/symbian/trkclient.cpp
@@ -27,7 +27,7 @@
**
**************************************************************************/
-#include "trkdevicex.h"
+#include "trkclient.h"
#include "trkutils.h"
#include
@@ -35,7 +35,6 @@
#include
#include
#include
-#include
#ifdef Q_OS_WIN
# include
@@ -117,14 +116,12 @@ struct TrkMessage
QByteArray data;
QVariant cookie;
Callback callback;
- bool invokeOnNAK;
};
TrkMessage::TrkMessage(byte c, byte t, Callback cb) :
code(c),
token(t),
- callback(cb),
- invokeOnNAK(false)
+ callback(cb)
{
}
@@ -144,8 +141,7 @@ public:
// Enqueue messages.
void queueTrkMessage(byte code, Callback callback,
- const QByteArray &data, const QVariant &cookie,
- bool invokeOnNAK);
+ const QByteArray &data, const QVariant &cookie);
void queueTrkInitialPing();
// Call this from the device read notification with the results.
@@ -184,14 +180,13 @@ byte TrkWriteQueue::nextTrkWriteToken()
}
void TrkWriteQueue::queueTrkMessage(byte code, Callback callback,
- const QByteArray &data, const QVariant &cookie, bool invokeOnNAK)
+ const QByteArray &data, const QVariant &cookie)
{
const byte token = code == TRK_WRITE_QUEUE_NOOP_CODE ?
byte(0) : nextTrkWriteToken();
TrkMessage msg(code, token, callback);
msg.data = data;
msg.cookie = cookie;
- msg.invokeOnNAK = invokeOnNAK;
trkWriteQueue.append(msg);
}
@@ -233,16 +228,14 @@ void TrkWriteQueue::notifyWriteResult(bool ok)
void TrkWriteQueue::slotHandleResult(const TrkResult &result)
{
trkWriteBusy = false;
- if (result.code != TrkNotifyAck && result.code != TrkNotifyNak)
- return;
+ //if (result.code != TrkNotifyAck && result.code != TrkNotifyNak)
+ // return;
// Find which request the message belongs to and invoke callback
// if ACK or on NAK if desired.
const TokenMessageMap::iterator it = writtenTrkMessages.find(result.token);
if (it == writtenTrkMessages.end())
return;
- const bool invokeCB = it.value().callback
- && (result.code == TrkNotifyAck || it.value().invokeOnNAK);
-
+ const bool invokeCB = it.value().callback;
if (invokeCB) {
TrkResult result1 = result;
result1.cookie = it.value().cookie;
@@ -257,8 +250,18 @@ void TrkWriteQueue::queueTrkInitialPing()
trkWriteQueue.append(TrkMessage(0, 0));
}
-struct TrkDevicePrivate {
+
+///////////////////////////////////////////////////////////////////////
+//
+// TrkDevicePrivate
+//
+///////////////////////////////////////////////////////////////////////
+
+struct TrkDevicePrivate
+{
TrkDevicePrivate();
+
+ TrkWriteQueue queue;
#ifdef Q_OS_WIN
HANDLE hdevice;
#else
@@ -298,11 +301,13 @@ TrkDevicePrivate::TrkDevicePrivate() :
TrkDevice::TrkDevice(QObject *parent) :
QObject(parent),
- d(new TrkDevicePrivate),
- qd(new TrkWriteQueue)
+ d(new TrkDevicePrivate)
+{}
+
+TrkDevice::~TrkDevice()
{
- connect(this, SIGNAL(messageReceived(trk::TrkResult)),
- this, SLOT(slotHandleResult(trk::TrkResult)));
+ close();
+ delete d;
}
bool TrkDevice::open(const QString &port, QString *errorMessage)
@@ -355,14 +360,6 @@ bool TrkDevice::open(const QString &port, QString *errorMessage)
#endif
}
-
-TrkDevice::~TrkDevice()
-{
- close();
- delete d;
- delete qd;
-}
-
void TrkDevice::close()
{
if (!isOpen())
@@ -492,7 +489,7 @@ void TrkDevice::tryTrkRead()
while (extractResult(&d->trkReadBuffer, d->serialFrame, &r, &rawData)) {
//if (verbose())
// logMessage("Read TrkResult " + r.data.toHex());
- qDebug() << "RECEIVE DATA: " << r.data.toHex();
+ d->queue.slotHandleResult(r);
emit messageReceived(r);
if (!rawData.isEmpty())
emit rawDataReceived(rawData);
@@ -513,14 +510,14 @@ void TrkDevice::emitError(const QString &s)
}
void TrkDevice::sendTrkMessage(byte code, Callback callback,
- const QByteArray &data, const QVariant &cookie, bool invokeOnNAK)
+ const QByteArray &data, const QVariant &cookie)
{
- qd->queueTrkMessage(code, callback, data, cookie, invokeOnNAK);
+ d->queue.queueTrkMessage(code, callback, data, cookie);
}
void TrkDevice::sendTrkInitialPing()
{
- qd->queueTrkInitialPing();
+ d->queue.queueTrkInitialPing();
}
bool TrkDevice::sendTrkAck(byte token)
@@ -536,10 +533,10 @@ bool TrkDevice::sendTrkAck(byte token)
void TrkDevice::tryTrkWrite()
{
TrkMessage message;
- if (!qd->pendingMessage(&message))
+ if (!d->queue.pendingMessage(&message))
return;
const bool success = trkWriteRawMessage(message);
- qd->notifyWriteResult(success);
+ d->queue.notifyWriteResult(success);
}
bool TrkDevice::trkWriteRawMessage(const TrkMessage &msg)
@@ -554,10 +551,5 @@ bool TrkDevice::trkWriteRawMessage(const TrkMessage &msg)
return rc;
}
-void TrkDevice::slotHandleResult(const TrkResult &result)
-{
- qd->slotHandleResult(result);
-}
-
} // namespace trk
diff --git a/tests/manual/trk/trkdevicex.h b/src/plugins/debugger/symbian/trkclient.h
similarity index 92%
rename from tests/manual/trk/trkdevicex.h
rename to src/plugins/debugger/symbian/trkclient.h
index 9d0e9da0dcc..5a7a7440775 100644
--- a/tests/manual/trk/trkdevicex.h
+++ b/src/plugins/debugger/symbian/trkclient.h
@@ -46,8 +46,6 @@ namespace trk {
struct TrkResult;
struct TrkMessage;
struct TrkDevicePrivate;
-class TrkWriteQueue;
-struct TrkWriteQueueIODevicePrivate;
/* TrkDevice: Implements a Windows COM or Linux device for
* Trk communications. Provides synchronous write and asynchronous
@@ -106,9 +104,7 @@ public:
void sendTrkMessage(unsigned char code,
Callback callBack = Callback(),
const QByteArray &data = QByteArray(),
- const QVariant &cookie = QVariant(),
- // Invoke callback on receiving NAK, too.
- bool invokeOnNAK = false);
+ const QVariant &cookie = QVariant());
// Enqeue an initial ping
void sendTrkInitialPing();
@@ -116,15 +112,11 @@ public:
// Send an Ack synchronously, bypassing the queue
bool sendTrkAck(unsigned char token);
-private slots:
- void slotHandleResult(const trk::TrkResult &);
-
private:
void tryTrkWrite();
bool trkWriteRawMessage(const TrkMessage &msg);
TrkDevicePrivate *d;
- TrkWriteQueue *qd;
};
} // namespace trk
diff --git a/tests/manual/trk/trkfunctor.h b/src/plugins/debugger/symbian/trkfunctor.h
similarity index 98%
rename from tests/manual/trk/trkfunctor.h
rename to src/plugins/debugger/symbian/trkfunctor.h
index 3dbd027774b..4b0d3669120 100644
--- a/tests/manual/trk/trkfunctor.h
+++ b/src/plugins/debugger/symbian/trkfunctor.h
@@ -27,8 +27,8 @@
**
**************************************************************************/
-#ifndef _TRK_FUNCTOR_H_
-#define _TRK_FUNCTOR_H_
+#ifndef DEBUGGER_TRK_FUNCTOR_H
+#define DEBUGGER_TRK_FUNCTOR_H
#include
diff --git a/tests/manual/trk/trkutils.cpp b/src/plugins/debugger/symbian/trkutils.cpp
similarity index 96%
rename from tests/manual/trk/trkutils.cpp
rename to src/plugins/debugger/symbian/trkutils.cpp
index 81925c07d67..4036b2ad656 100644
--- a/tests/manual/trk/trkutils.cpp
+++ b/src/plugins/debugger/symbian/trkutils.cpp
@@ -43,6 +43,11 @@ QByteArray hexNumber(uint n, int digits)
return QByteArray(digits - ba.size(), '0') + ba;
}
+QByteArray hexxNumber(uint n, int digits)
+{
+ return "0x" + hexNumber(n, digits);
+}
+
TrkResult::TrkResult() :
code(0),
token(0),
@@ -345,5 +350,16 @@ int TrkResult::errorCode() const
return errorCode;
return isNAK ? 0xff : 0;
}
+
+QString TrkResult::errorString() const
+{
+ // NAK means always error, else data sized 1 with a non-null element
+ if (code == 0xff)
+ return "NAK";
+ if (data.size() < 1)
+ return "Unknown error packet";
+ return errorMessage(data.at(0));
+}
+
} // namespace trk
diff --git a/tests/manual/trk/trkutils.h b/src/plugins/debugger/symbian/trkutils.h
similarity index 97%
rename from tests/manual/trk/trkutils.h
rename to src/plugins/debugger/symbian/trkutils.h
index 6bc05db157d..6f1b280eb85 100644
--- a/tests/manual/trk/trkutils.h
+++ b/src/plugins/debugger/symbian/trkutils.h
@@ -144,7 +144,7 @@ struct Session
uint tid;
uint codeseg;
uint dataseg;
- QHash tokenToBreakpointIndex;
+ QHash addressToBP;
// Gdb request
uint currentThread;
@@ -178,6 +178,7 @@ struct TrkResult
QString toString() const;
// 0 for no error.
int errorCode() const;
+ QString errorString() const;
byte code;
byte token;
@@ -193,9 +194,9 @@ ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame);
bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0);
QByteArray errorMessage(byte code);
QByteArray hexNumber(uint n, int digits = 0);
+QByteArray hexxNumber(uint n, int digits = 0); // prepends '0x', too
uint swapEndian(uint in);
-
} // namespace trk
#endif // DEBUGGER_TRK_UTILS
diff --git a/src/plugins/debugger/tcf/tcfengine.cpp b/src/plugins/debugger/tcf/tcfengine.cpp
index 0c98513b8ec..bcadf3c9540 100644
--- a/src/plugins/debugger/tcf/tcfengine.cpp
+++ b/src/plugins/debugger/tcf/tcfengine.cpp
@@ -220,7 +220,7 @@ void TcfEngine::exitDebugger()
qq->notifyInferiorExited();
}
-bool TcfEngine::startDebugger(const QSharedPointer &sp)
+void TcfEngine::startDebugger(const QSharedPointer &sp)
{
qq->notifyInferiorRunningRequested();
const int pos = sp->remoteChannel.indexOf(QLatin1Char(':'));
@@ -228,7 +228,7 @@ bool TcfEngine::startDebugger(const QSharedPointer &sp)
const quint16 port = sp->remoteChannel.mid(pos + 1).toInt();
//QTimer::singleShot(0, this, SLOT(runInferior()));
m_socket->connectToHost(host, port);
- return true;
+ emit startSuccessful();
}
void TcfEngine::continueInferior()
diff --git a/src/plugins/debugger/tcf/tcfengine.h b/src/plugins/debugger/tcf/tcfengine.h
index 3d556427bd9..4487fffd3de 100644
--- a/src/plugins/debugger/tcf/tcfengine.h
+++ b/src/plugins/debugger/tcf/tcfengine.h
@@ -82,7 +82,7 @@ private:
void shutdown();
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
- bool startDebugger(const QSharedPointer &sp);
+ void startDebugger(const QSharedPointer &sp);
void exitDebugger();
void continueInferior();
diff --git a/src/plugins/designer/Designer.pluginspec b/src/plugins/designer/Designer.pluginspec
index 528745a54b6..02cb944268c 100644
--- a/src/plugins/designer/Designer.pluginspec
+++ b/src/plugins/designer/Designer.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Qt Designer integration.
http://qt.nokia.com
-
+
-
+
diff --git a/src/plugins/duieditor/DuiEditor.pluginspec b/src/plugins/duieditor/DuiEditor.pluginspec
index 9400bb5bc94..8272e77dc15 100644
--- a/src/plugins/duieditor/DuiEditor.pluginspec
+++ b/src/plugins/duieditor/DuiEditor.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,7 +19,7 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Editor for DUI.
http://qt.nokia.com
-
-
+
+
diff --git a/src/plugins/fakevim/FakeVim.pluginspec b/src/plugins/fakevim/FakeVim.pluginspec
index 2f343a333d5..b494ce3435e 100644
--- a/src/plugins/fakevim/FakeVim.pluginspec
+++ b/src/plugins/fakevim/FakeVim.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
VI-style keyboard navigation.
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/find/Find.pluginspec b/src/plugins/find/Find.pluginspec
index e18d54902b8..9fa0b7e7ef7 100644
--- a/src/plugins/find/Find.pluginspec
+++ b/src/plugins/find/Find.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Provides the find widget and the hooks for find implementations.
http://qt.nokia.com
-
+
diff --git a/src/plugins/find/basetextfind.cpp b/src/plugins/find/basetextfind.cpp
index 89ec9ccdb3f..5fb4a33d565 100644
--- a/src/plugins/find/basetextfind.cpp
+++ b/src/plugins/find/basetextfind.cpp
@@ -125,7 +125,7 @@ QString BaseTextFind::completedFindString() const
return cursor.selectedText();
}
-bool BaseTextFind::findIncremental(const QString &txt, IFindSupport::FindFlags findFlags)
+IFindSupport::Result BaseTextFind::findIncremental(const QString &txt, IFindSupport::FindFlags findFlags)
{
QTextCursor cursor = textCursor();
if (m_incrementalStartPos < 0)
@@ -137,15 +137,15 @@ bool BaseTextFind::findIncremental(const QString &txt, IFindSupport::FindFlags f
emit highlightAll(txt, findFlags);
else
emit highlightAll(QString(), 0);
- return found;
+ return found ? Found : NotFound;
}
-bool BaseTextFind::findStep(const QString &txt, IFindSupport::FindFlags findFlags)
+IFindSupport::Result BaseTextFind::findStep(const QString &txt, IFindSupport::FindFlags findFlags)
{
bool found = find(txt, findFlags, textCursor());
if (found)
m_incrementalStartPos = textCursor().selectionStart();
- return found;
+ return found ? Found : NotFound;
}
namespace {
diff --git a/src/plugins/find/basetextfind.h b/src/plugins/find/basetextfind.h
index ec4cc0b344d..97aca8f4f6c 100644
--- a/src/plugins/find/basetextfind.h
+++ b/src/plugins/find/basetextfind.h
@@ -53,8 +53,8 @@ public:
QString currentFindString() const;
QString completedFindString() const;
- bool findIncremental(const QString &txt, IFindSupport::FindFlags findFlags);
- bool findStep(const QString &txt, IFindSupport::FindFlags findFlags);
+ Result findIncremental(const QString &txt, IFindSupport::FindFlags findFlags);
+ Result findStep(const QString &txt, IFindSupport::FindFlags findFlags);
bool replaceStep(const QString &before, const QString &after,
IFindSupport::FindFlags findFlags);
int replaceAll(const QString &before, const QString &after,
diff --git a/src/plugins/find/currentdocumentfind.cpp b/src/plugins/find/currentdocumentfind.cpp
index 15f6a944b3b..16457382a2f 100644
--- a/src/plugins/find/currentdocumentfind.cpp
+++ b/src/plugins/find/currentdocumentfind.cpp
@@ -106,15 +106,15 @@ void CurrentDocumentFind::highlightAll(const QString &txt, IFindSupport::FindFla
m_currentFind->highlightAll(txt, findFlags);
}
-bool CurrentDocumentFind::findIncremental(const QString &txt, IFindSupport::FindFlags findFlags)
+IFindSupport::Result CurrentDocumentFind::findIncremental(const QString &txt, IFindSupport::FindFlags findFlags)
{
- QTC_ASSERT(m_currentFind, return false);
+ QTC_ASSERT(m_currentFind, return IFindSupport::NotFound);
return m_currentFind->findIncremental(txt, findFlags);
}
-bool CurrentDocumentFind::findStep(const QString &txt, IFindSupport::FindFlags findFlags)
+IFindSupport::Result CurrentDocumentFind::findStep(const QString &txt, IFindSupport::FindFlags findFlags)
{
- QTC_ASSERT(m_currentFind, return false);
+ QTC_ASSERT(m_currentFind, return IFindSupport::NotFound);
return m_currentFind->findStep(txt, findFlags);
}
diff --git a/src/plugins/find/currentdocumentfind.h b/src/plugins/find/currentdocumentfind.h
index bd0e19e022f..a3b9a7b362b 100644
--- a/src/plugins/find/currentdocumentfind.h
+++ b/src/plugins/find/currentdocumentfind.h
@@ -55,8 +55,8 @@ public:
bool isEnabled() const;
bool candidateIsEnabled() const;
void highlightAll(const QString &txt, IFindSupport::FindFlags findFlags);
- bool findIncremental(const QString &txt, IFindSupport::FindFlags findFlags);
- bool findStep(const QString &txt, IFindSupport::FindFlags findFlags);
+ IFindSupport::Result findIncremental(const QString &txt, IFindSupport::FindFlags findFlags);
+ IFindSupport::Result findStep(const QString &txt, IFindSupport::FindFlags findFlags);
bool replaceStep(const QString &before, const QString &after,
IFindSupport::FindFlags findFlags);
int replaceAll(const QString &before, const QString &after,
diff --git a/src/plugins/find/findtoolbar.cpp b/src/plugins/find/findtoolbar.cpp
index 44ecc6fb237..1c2c59ca503 100644
--- a/src/plugins/find/findtoolbar.cpp
+++ b/src/plugins/find/findtoolbar.cpp
@@ -69,7 +69,8 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
m_replaceNextAction(0),
m_casesensitiveIcon(":/find/images/casesensitively.png"),
m_regexpIcon(":/find/images/regexp.png"),
- m_wholewordsIcon(":/find/images/wholewords.png")
+ m_wholewordsIcon(":/find/images/wholewords.png"),
+ m_findIncrementalTimer(this), m_findStepTimer(this)
{
//setup ui
m_ui.setupUi(this);
@@ -215,6 +216,12 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
connect(m_currentDocumentFind, SIGNAL(candidateChanged()), this, SLOT(adaptToCandidate()));
connect(m_currentDocumentFind, SIGNAL(changed()), this, SLOT(updateToolBar()));
updateToolBar();
+
+ m_findIncrementalTimer.setSingleShot(true);
+ m_findStepTimer.setSingleShot(true);
+ connect(&m_findIncrementalTimer, SIGNAL(timeout()),
+ this, SLOT(invokeFindIncremental()));
+ connect(&m_findStepTimer, SIGNAL(timeout()), this, SLOT(invokeFindStep()));
}
FindToolBar::~FindToolBar()
@@ -373,17 +380,27 @@ void FindToolBar::selectFindText()
void FindToolBar::invokeFindStep()
{
+ m_findStepTimer.stop();
+ m_findIncrementalTimer.stop();
if (m_currentDocumentFind->isEnabled()) {
m_plugin->updateFindCompletion(getFindText());
- m_currentDocumentFind->findStep(getFindText(), effectiveFindFlags());
+ IFindSupport::Result result =
+ m_currentDocumentFind->findStep(getFindText(), effectiveFindFlags());
+ if (result == IFindSupport::NotYetFound)
+ m_findStepTimer.start(50);
}
}
void FindToolBar::invokeFindIncremental()
{
+ m_findIncrementalTimer.stop();
+ m_findStepTimer.stop();
if (m_currentDocumentFind->isEnabled()) {
QString text = getFindText();
- m_currentDocumentFind->findIncremental(text, effectiveFindFlags());
+ IFindSupport::Result result =
+ m_currentDocumentFind->findIncremental(text, effectiveFindFlags());
+ if (result == IFindSupport::NotYetFound)
+ m_findIncrementalTimer.start(50);
if (text.isEmpty())
m_currentDocumentFind->clearResults();
}
@@ -421,6 +438,8 @@ void FindToolBar::invokeReplaceAll()
void FindToolBar::invokeResetIncrementalSearch()
{
+ m_findIncrementalTimer.stop();
+ m_findStepTimer.stop();
if (m_currentDocumentFind->isEnabled())
m_currentDocumentFind->resetIncrementalSearch();
}
diff --git a/src/plugins/find/findtoolbar.h b/src/plugins/find/findtoolbar.h
index 14dbed88524..cbde5eceb52 100644
--- a/src/plugins/find/findtoolbar.h
+++ b/src/plugins/find/findtoolbar.h
@@ -37,6 +37,8 @@
#include
#include
+#include
+
#include
#include
#include
@@ -124,6 +126,9 @@ private:
QPixmap m_casesensitiveIcon;
QPixmap m_regexpIcon;
QPixmap m_wholewordsIcon;
+
+ QTimer m_findIncrementalTimer;
+ QTimer m_findStepTimer;
};
} // namespace Internal
diff --git a/src/plugins/find/ifindsupport.h b/src/plugins/find/ifindsupport.h
index 0e2d5ef2dc7..35b5c7779ed 100644
--- a/src/plugins/find/ifindsupport.h
+++ b/src/plugins/find/ifindsupport.h
@@ -50,6 +50,8 @@ public:
};
Q_DECLARE_FLAGS(FindFlags, FindFlag)
+ enum Result { Found, NotFound, NotYetFound };
+
IFindSupport() : QObject(0) {}
virtual ~IFindSupport() {}
@@ -61,8 +63,8 @@ public:
virtual QString completedFindString() const = 0;
virtual void highlightAll(const QString &txt, FindFlags findFlags);
- virtual bool findIncremental(const QString &txt, FindFlags findFlags) = 0;
- virtual bool findStep(const QString &txt, FindFlags findFlags) = 0;
+ virtual Result findIncremental(const QString &txt, FindFlags findFlags) = 0;
+ virtual Result findStep(const QString &txt, FindFlags findFlags) = 0;
virtual bool replaceStep(const QString &before, const QString &after,
FindFlags findFlags) = 0;
virtual int replaceAll(const QString &before, const QString &after,
diff --git a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec
index 8f3c16125bb..2176c47e1a9 100644
--- a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec
+++ b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Generic support
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/git/ScmGit.pluginspec b/src/plugins/git/ScmGit.pluginspec
index 934ffd5e8c9..0bcbdcc24c4 100644
--- a/src/plugins/git/ScmGit.pluginspec
+++ b/src/plugins/git/ScmGit.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Git integration.
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/helloworld/HelloWorld.pluginspec b/src/plugins/helloworld/HelloWorld.pluginspec
index 4aaf5b9eab7..4ed6d96636b 100644
--- a/src/plugins/helloworld/HelloWorld.pluginspec
+++ b/src/plugins/helloworld/HelloWorld.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Hello World sample plugin.
http://qt.nokia.com
-
+
diff --git a/src/plugins/help/Help.pluginspec b/src/plugins/help/Help.pluginspec
index 3c60befe91f..0009411597e 100644
--- a/src/plugins/help/Help.pluginspec
+++ b/src/plugins/help/Help.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Help system.
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/help/helpfindsupport.cpp b/src/plugins/help/helpfindsupport.cpp
index d6086858f4b..bfb688db571 100644
--- a/src/plugins/help/helpfindsupport.cpp
+++ b/src/plugins/help/helpfindsupport.cpp
@@ -72,17 +72,19 @@ QString HelpFindSupport::completedFindString() const
return QString();
}
-bool HelpFindSupport::findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags)
+Find::IFindSupport::Result HelpFindSupport::findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags)
{
- QTC_ASSERT(m_centralWidget, return false);
+ QTC_ASSERT(m_centralWidget, return NotFound);
findFlags &= ~Find::IFindSupport::FindBackward;
- return m_centralWidget->find(txt, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags), true);
+ return m_centralWidget->find(txt, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags), true)
+ ? Found : NotFound;
}
-bool HelpFindSupport::findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags)
+Find::IFindSupport::Result HelpFindSupport::findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags)
{
- QTC_ASSERT(m_centralWidget, return false);
- return m_centralWidget->find(txt, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags), false);
+ QTC_ASSERT(m_centralWidget, return NotFound);
+ return m_centralWidget->find(txt, Find::IFindSupport::textDocumentFlagsForFindFlags(findFlags), false)
+ ? Found : NotFound;
}
HelpViewerFindSupport::HelpViewerFindSupport(HelpViewer *viewer)
@@ -106,17 +108,17 @@ QString HelpViewerFindSupport::currentFindString() const
#endif
}
-bool HelpViewerFindSupport::findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags)
+Find::IFindSupport::Result HelpViewerFindSupport::findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags)
{
- QTC_ASSERT(m_viewer, return false);
+ QTC_ASSERT(m_viewer, return NotFound);
findFlags &= ~Find::IFindSupport::FindBackward;
- return find(txt, findFlags, true);
+ return find(txt, findFlags, true) ? Found : NotFound;
}
-bool HelpViewerFindSupport::findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags)
+Find::IFindSupport::Result HelpViewerFindSupport::findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags)
{
- QTC_ASSERT(m_viewer, return false);
- return find(txt, findFlags, false);
+ QTC_ASSERT(m_viewer, return NotFound);
+ return find(txt, findFlags, false) ? Found : NotFound;
}
bool HelpViewerFindSupport::find(const QString &txt, Find::IFindSupport::FindFlags findFlags, bool incremental)
diff --git a/src/plugins/help/helpfindsupport.h b/src/plugins/help/helpfindsupport.h
index 94908d39165..1adfb1c9037 100644
--- a/src/plugins/help/helpfindsupport.h
+++ b/src/plugins/help/helpfindsupport.h
@@ -57,8 +57,8 @@ public:
QString currentFindString() const;
QString completedFindString() const;
- bool findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags);
- bool findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags);
+ Result findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags);
+ Result findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags);
bool replaceStep(const QString &, const QString &,
Find::IFindSupport::FindFlags ) { return false; }
int replaceAll(const QString &, const QString &,
@@ -84,8 +84,8 @@ public:
QString currentFindString() const;
QString completedFindString() const { return QString(); }
- bool findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags);
- bool findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags);
+ Result findIncremental(const QString &txt, Find::IFindSupport::FindFlags findFlags);
+ Result findStep(const QString &txt, Find::IFindSupport::FindFlags findFlags);
bool replaceStep(const QString &, const QString &,
Find::IFindSupport::FindFlags ) { return false; }
int replaceAll(const QString &, const QString &,
diff --git a/src/plugins/perforce/Perforce.pluginspec b/src/plugins/perforce/Perforce.pluginspec
index 78c3b8edd08..cc77648b9d2 100644
--- a/src/plugins/perforce/Perforce.pluginspec
+++ b/src/plugins/perforce/Perforce.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Perforce integration.
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/projectexplorer/ProjectExplorer.pluginspec b/src/plugins/projectexplorer/ProjectExplorer.pluginspec
index b064c36d248..70d49c83511 100644
--- a/src/plugins/projectexplorer/ProjectExplorer.pluginspec
+++ b/src/plugins/projectexplorer/ProjectExplorer.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
ProjectExplorer framework that can be extended with different kind of project types.
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec
index 60261b13b8f..fde164aa8d6 100644
--- a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec
+++ b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,10 +19,10 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Qml support
http://qt.nokia.com
-
-
-
-
-
+
+
+
+
+
diff --git a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec
index 78d80c3b4f8..e9a39950cb5 100644
--- a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec
+++ b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,11 +19,11 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Provides project type for Qt 4 pro files and tools.
http://qt.nokia.com
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
index 3488a25f49f..5bae0badb60 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.cpp
@@ -537,36 +537,34 @@ S60DeviceRunControl::S60DeviceRunControl(QSharedPointer runCon
this, SLOT(signsisProcessFailed()));
connect(m_signsis, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(signsisProcessFinished()));
+
+ Qt4Project *project = qobject_cast(runConfiguration->project());
+ QTC_ASSERT(project, return);
+
+ m_serialPortName = runConfiguration->serialPortName();
+ m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName);
+ m_targetName = runConfiguration->targetName();
+ m_baseFileName = runConfiguration->basePackageFilePath();
+ m_workingDirectory = QFileInfo(m_baseFileName).absolutePath();
+ m_qtDir = project->qtVersion(project->activeBuildConfiguration())->versionInfo().value("QT_INSTALL_DATA");
+ m_useCustomSignature = (runConfiguration->signingMode() == S60DeviceRunConfiguration::SignCustom);
+ m_customSignaturePath = runConfiguration->customSignaturePath();
+ m_customKeyPath = runConfiguration->customKeyPath();
+ m_toolsDirectory = S60Manager::instance()->deviceForQtVersion(
+ project->qtVersion(project->activeBuildConfiguration())).toolsRoot
+ + "/epoc32/tools";
+ m_executableFileName = lsFile(runConfiguration->executableFileName());
+ const QString makesisTool = m_toolsDirectory + "/makesis.exe";
+ const QString packageFile = QFileInfo(runConfiguration->packageFileName()).fileName();
}
void S60DeviceRunControl::start()
{
- QSharedPointer rc = runConfiguration().objectCast();
- QTC_ASSERT(!rc.isNull(), return);
-
- Qt4Project *project = qobject_cast(rc->project());
- QTC_ASSERT(project, return);
-
- m_serialPortName = rc->serialPortName();
- m_serialPortFriendlyName = S60Manager::instance()->serialDeviceLister()->friendlyNameForPort(m_serialPortName);
- m_targetName = rc->targetName();
- m_baseFileName = rc->basePackageFilePath();
- m_workingDirectory = QFileInfo(m_baseFileName).absolutePath();
- m_qtDir = project->qtVersion(project->activeBuildConfiguration())->versionInfo().value("QT_INSTALL_DATA");
- m_useCustomSignature = (rc->signingMode() == S60DeviceRunConfiguration::SignCustom);
- m_customSignaturePath = rc->customSignaturePath();
- m_customKeyPath = rc->customKeyPath();
-
emit started();
emit addToOutputWindow(this, tr("Creating %1.sisx ...").arg(QDir::toNativeSeparators(m_baseFileName)));
- emit addToOutputWindow(this, tr("Executable file: %1").arg(lsFile(rc->executableFileName())));
+ emit addToOutputWindow(this, tr("Executable file: %1").arg(m_executableFileName));
- m_toolsDirectory = S60Manager::instance()->deviceForQtVersion(
- project->qtVersion(project->activeBuildConfiguration())).toolsRoot
- + "/epoc32/tools";
- const QString makesisTool = m_toolsDirectory + "/makesis.exe";
- const QString packageFile = QFileInfo(rc->packageFileName()).fileName();
m_makesis->setWorkingDirectory(m_workingDirectory);
emit addToOutputWindow(this, tr("%1 %2").arg(QDir::toNativeSeparators(makesisTool), packageFile));
diff --git a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
index d05b7cc8d9f..8d09f5b2bc8 100644
--- a/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
+++ b/src/plugins/qt4projectmanager/qt-s60/s60devicerunconfiguration.h
@@ -176,6 +176,7 @@ private:
QString m_baseFileName;
QString m_workingDirectory;
QString m_toolsDirectory;
+ QString m_executableFileName;
QString m_qtDir;
bool m_useCustomSignature;
QString m_customSignaturePath;
diff --git a/src/plugins/qt4projectmanager/qtoptionspage.cpp b/src/plugins/qt4projectmanager/qtoptionspage.cpp
index dea944b087b..3ffc91ad55e 100644
--- a/src/plugins/qt4projectmanager/qtoptionspage.cpp
+++ b/src/plugins/qt4projectmanager/qtoptionspage.cpp
@@ -325,7 +325,7 @@ static inline QString msgHtmlHelperToolTip(const QFileInfo &fi)
return QtOptionsPageWidget::tr("File: %1 "
"Last modified: %2 "
"Size: %3 Bytes
").
- arg(fi.absoluteFilePath()).
+ arg(QDir::toNativeSeparators(fi.absoluteFilePath())).
arg(fi.lastModified().toString(Qt::SystemLocaleLongDate)).
arg(fi.size());
}
diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp
index a9b642e1312..55068132db0 100644
--- a/src/plugins/qt4projectmanager/qtversionmanager.cpp
+++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp
@@ -1244,7 +1244,7 @@ QStringList QtVersion::debuggingHelperLibraryLocations() const
{
QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
if (qtInstallData.isEmpty())
- QString::null;
+ return QStringList();
return DebuggingHelperLibrary::debuggingHelperLibraryLocations(qtInstallData);
}
diff --git a/src/plugins/qtscripteditor/QtScriptEditor.pluginspec b/src/plugins/qtscripteditor/QtScriptEditor.pluginspec
index 6eaf3fe9f8e..2c8b772f06f 100644
--- a/src/plugins/qtscripteditor/QtScriptEditor.pluginspec
+++ b/src/plugins/qtscripteditor/QtScriptEditor.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,7 +19,7 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Editor for QtScript.
http://qt.nokia.com
-
-
+
+
diff --git a/src/plugins/quickopen/QuickOpen.pluginspec b/src/plugins/quickopen/QuickOpen.pluginspec
index 86299f76224..db95f0097cc 100644
--- a/src/plugins/quickopen/QuickOpen.pluginspec
+++ b/src/plugins/quickopen/QuickOpen.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Provides the Locator widget and the hooks for QuickOpen filter implementations.
http://qt.nokia.com
-
+
diff --git a/src/plugins/regexp/RegExp.pluginspec b/src/plugins/regexp/RegExp.pluginspec
index 0318e93ef8b..08081797edd 100644
--- a/src/plugins/regexp/RegExp.pluginspec
+++ b/src/plugins/regexp/RegExp.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Regular Expression test widget.
http://qt.nokia.com
-
+
diff --git a/src/plugins/resourceeditor/ResourceEditor.pluginspec b/src/plugins/resourceeditor/ResourceEditor.pluginspec
index a3e0a0dd220..697f61c6741 100644
--- a/src/plugins/resourceeditor/ResourceEditor.pluginspec
+++ b/src/plugins/resourceeditor/ResourceEditor.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Editor for qrc files.
http://qt.nokia.com
-
+
diff --git a/src/plugins/snippets/Snippets.pluginspec b/src/plugins/snippets/Snippets.pluginspec
index 0d3307183fe..fd4881ac94b 100644
--- a/src/plugins/snippets/Snippets.pluginspec
+++ b/src/plugins/snippets/Snippets.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Code snippet plugin.
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/subversion/Subversion.pluginspec b/src/plugins/subversion/Subversion.pluginspec
index 8e7de969ad7..f8bd40f1b92 100644
--- a/src/plugins/subversion/Subversion.pluginspec
+++ b/src/plugins/subversion/Subversion.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,9 +19,9 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Subversion integration.
http://qt.nokia.com
-
-
-
-
+
+
+
+
diff --git a/src/plugins/texteditor/TextEditor.pluginspec b/src/plugins/texteditor/TextEditor.pluginspec
index b64b2b7ce20..691dd6edfa1 100644
--- a/src/plugins/texteditor/TextEditor.pluginspec
+++ b/src/plugins/texteditor/TextEditor.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Text editor framework and the implementation of the basic text editor.
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/texteditor/basetextdocument.cpp b/src/plugins/texteditor/basetextdocument.cpp
index 8de81100d8c..6da82ccdf59 100644
--- a/src/plugins/texteditor/basetextdocument.cpp
+++ b/src/plugins/texteditor/basetextdocument.cpp
@@ -93,7 +93,7 @@ bool BaseTextDocument::save(const QString &fileName)
cursor.beginEditBlock();
if (m_storageSettings.m_cleanWhitespace)
- cleanWhitespace(cursor, m_storageSettings.m_inEntireDocument);
+ cleanWhitespace(cursor, m_storageSettings.m_cleanIndentation, m_storageSettings.m_inEntireDocument);
if (m_storageSettings.m_addFinalNewLine)
ensureFinalNewLine(cursor);
cursor.endEditBlock();
@@ -301,23 +301,28 @@ void BaseTextDocument::setSyntaxHighlighter(QSyntaxHighlighter *highlighter)
-void BaseTextDocument::cleanWhitespace()
+void BaseTextDocument::cleanWhitespace(const QTextCursor &cursor)
{
- QTextCursor cursor(m_document);
- cursor.beginEditBlock();
- cleanWhitespace(cursor, true);
- if (m_storageSettings.m_addFinalNewLine)
- ensureFinalNewLine(cursor);
- cursor.endEditBlock();
+ bool hasSelection = cursor.hasSelection();
+ QTextCursor copyCursor = cursor;
+ copyCursor.beginEditBlock();
+ cleanWhitespace(copyCursor, true, true);
+ if (!hasSelection)
+ ensureFinalNewLine(copyCursor);
+ copyCursor.endEditBlock();
}
-void BaseTextDocument::cleanWhitespace(QTextCursor& cursor, bool inEntireDocument)
+void BaseTextDocument::cleanWhitespace(QTextCursor& cursor, bool cleanIndentation, bool inEntireDocument)
{
TextEditDocumentLayout *documentLayout = qobject_cast(m_document->documentLayout());
- QTextBlock block = m_document->firstBlock();
- while (block.isValid()) {
+ QTextBlock block = m_document->findBlock(cursor.selectionStart());
+ QTextBlock end;
+ if (cursor.hasSelection())
+ end = m_document->findBlock(cursor.selectionEnd()-1).next();
+
+ while (block.isValid() && block != end) {
if (inEntireDocument || block.revision() > documentLayout->lastSaveRevision) {
@@ -327,7 +332,7 @@ void BaseTextDocument::cleanWhitespace(QTextCursor& cursor, bool inEntireDocumen
cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, trailing);
cursor.removeSelectedText();
}
- if (m_storageSettings.m_cleanIndentation && !m_tabSettings.isIndentationClean(blockText)) {
+ if (cleanIndentation && !m_tabSettings.isIndentationClean(blockText)) {
cursor.setPosition(block.position());
int firstNonSpace = m_tabSettings.firstNonSpace(blockText);
if (firstNonSpace == blockText.length()) {
diff --git a/src/plugins/texteditor/basetextdocument.h b/src/plugins/texteditor/basetextdocument.h
index 88e1c609a13..eaf37c91caf 100644
--- a/src/plugins/texteditor/basetextdocument.h
+++ b/src/plugins/texteditor/basetextdocument.h
@@ -110,7 +110,7 @@ public:
void reload(QTextCodec *codec);
- void cleanWhitespace();
+ void cleanWhitespace(const QTextCursor &cursor);
signals:
void titleChanged(QString title);
@@ -146,7 +146,7 @@ private:
bool m_hasDecodingError;
QByteArray m_decodingErrorSample;
- void cleanWhitespace(QTextCursor& cursor, bool onlyInModifiedLines);
+ void cleanWhitespace(QTextCursor& cursor, bool cleanIndentation, bool inEntireDocument);
void ensureFinalNewLine(QTextCursor& cursor);
};
diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp
index 511c4af88ef..905c911b4ab 100644
--- a/src/plugins/texteditor/basetexteditor.cpp
+++ b/src/plugins/texteditor/basetexteditor.cpp
@@ -833,7 +833,7 @@ void BaseTextEditor::moveLineUpDown(bool up)
void BaseTextEditor::cleanWhitespace()
{
- d->m_document->cleanWhitespace();
+ d->m_document->cleanWhitespace(textCursor());
}
void BaseTextEditor::keyPressEvent(QKeyEvent *e)
@@ -887,13 +887,18 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
QTextCursor cursor = textCursor();
if (d->m_inBlockSelectionMode)
cursor.clearSelection();
- if (d->m_document->tabSettings().m_autoIndent) {
+ const TabSettings &ts = d->m_document->tabSettings();
+ if (ts.m_autoIndent) {
cursor.beginEditBlock();
cursor.insertBlock();
indent(document(), cursor, QChar::Null);
cursor.endEditBlock();
} else {
+ cursor.beginEditBlock();
+ QString previousBlockText = cursor.block().text();
cursor.insertBlock();
+ cursor.insertText(ts.indentationString(previousBlockText));
+ cursor.endEditBlock();
}
e->accept();
setTextCursor(cursor);
@@ -3189,17 +3194,14 @@ void BaseTextEditor::handleBackspaceKey()
continue;
previousIndent = tabSettings.columnAt(previousNonEmptyBlockText,
tabSettings.firstNonSpace(previousNonEmptyBlockText));
- if (previousIndent < indent)
+ if (previousIndent < indent) {
+ cursor.beginEditBlock();
+ cursor.setPosition(currentBlock.position(), QTextCursor::KeepAnchor);
+ cursor.insertText(tabSettings.indentationString(previousNonEmptyBlockText));
+ cursor.endEditBlock();
break;
+ }
}
-
- if (previousIndent >= indent)
- previousIndent = 0;
-
- cursor.beginEditBlock();
- cursor.setPosition(currentBlock.position(), QTextCursor::KeepAnchor);
- cursor.insertText(tabSettings.indentationString(0, previousIndent));
- cursor.endEditBlock();
}
void BaseTextEditor::wheelEvent(QWheelEvent *e)
diff --git a/src/plugins/texteditor/completionwidget.cpp b/src/plugins/texteditor/completionwidget.cpp
index 91b05cd7a2e..c656500f072 100644
--- a/src/plugins/texteditor/completionwidget.cpp
+++ b/src/plugins/texteditor/completionwidget.cpp
@@ -156,7 +156,17 @@ bool CompletionWidget::event(QEvent *e)
closeList(currentIndex());
return true;
case Qt::Key_Up:
+ if (currentIndex().row() == 0) {
+ setCurrentIndex(model()->index(model()->rowCount()-1, 0));
+ return true;
+ }
+ forwardKeys = false;
+ break;
case Qt::Key_Down:
+ if (currentIndex().row() == model()->rowCount()-1) {
+ setCurrentIndex(model()->index(0, 0));
+ return true;
+ }
case Qt::Key_Enter:
case Qt::Key_PageDown:
case Qt::Key_PageUp:
diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp
index e0225ce8bcd..393434d9085 100644
--- a/src/plugins/texteditor/tabsettings.cpp
+++ b/src/plugins/texteditor/tabsettings.cpp
@@ -110,6 +110,18 @@ int TabSettings::firstNonSpace(const QString &text) const
return i;
}
+QString TabSettings::indentationString(const QString &text) const
+{
+ return text.left(firstNonSpace(text));
+}
+
+
+int TabSettings::indentationColumn(const QString &text) const
+{
+ return columnAt(text, firstNonSpace(text));
+}
+
+
int TabSettings::trailingWhitespaces(const QString &text) const
{
int i = 0;
@@ -225,7 +237,7 @@ void TabSettings::indentLine(QTextBlock block, int newIndent) const
const int oldBlockLength = text.size();
// Quickly check whether indenting is required.
- if (oldBlockLength == 0 && newIndent == 0)
+ if (indentationColumn(text) == newIndent)
return;
const QString indentString = indentationString(0, newIndent);
@@ -234,12 +246,6 @@ void TabSettings::indentLine(QTextBlock block, int newIndent) const
if (oldBlockLength == indentString.length() && text == indentString)
return;
- if (oldBlockLength > indentString.length() &&
- text.startsWith(indentString) &&
- !text.at(indentString.length()).isSpace()) {
- return;
- }
-
QTextCursor cursor(block);
cursor.beginEditBlock();
cursor.movePosition(QTextCursor::StartOfBlock);
diff --git a/src/plugins/texteditor/tabsettings.h b/src/plugins/texteditor/tabsettings.h
index ec2c3dfe8ea..f26e0bb5ad9 100644
--- a/src/plugins/texteditor/tabsettings.h
+++ b/src/plugins/texteditor/tabsettings.h
@@ -63,6 +63,8 @@ struct TEXTEDITOR_EXPORT TabSettings
int spacesLeftFromPosition(const QString &text, int position) const;
int indentedColumn(int column, bool doIndent = true) const;
QString indentationString(int startColumn, int targetColumn) const;
+ QString indentationString(const QString &text) const;
+ int indentationColumn(const QString &text) const;
void indentLine(QTextBlock block, int newIndent) const;
diff --git a/src/plugins/vcsbase/VCSBase.pluginspec b/src/plugins/vcsbase/VCSBase.pluginspec
index 383cd1d4be9..670df6002b9 100644
--- a/src/plugins/vcsbase/VCSBase.pluginspec
+++ b/src/plugins/vcsbase/VCSBase.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,8 +19,8 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Version Control System Base Plugin
http://qt.nokia.com
-
-
-
+
+
+
diff --git a/src/plugins/welcome/Welcome.pluginspec b/src/plugins/welcome/Welcome.pluginspec
index 32b0bffee50..396d0d57324 100644
--- a/src/plugins/welcome/Welcome.pluginspec
+++ b/src/plugins/welcome/Welcome.pluginspec
@@ -1,4 +1,4 @@
-
+
Nokia Corporation
(C) 2008-2009 Nokia Corporation
@@ -19,6 +19,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Default Welcome Screen Plugin
http://qt.nokia.com
-
+
diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp
index c4718c08495..d536a03ef0f 100644
--- a/src/shared/proparser/profileevaluator.cpp
+++ b/src/shared/proparser/profileevaluator.cpp
@@ -1139,10 +1139,11 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pr
}
if (!qmake_cache.isEmpty()) {
qmake_cache = QDir::cleanPath(qmake_cache);
- if (evaluateFileInto(qmake_cache, &m_option->cache_valuemap, 0)) {
+ QHash cache_valuemap;
+ if (evaluateFileInto(qmake_cache, &cache_valuemap, 0)) {
m_option->cachefile = qmake_cache;
if (m_option->qmakespec.isEmpty()) {
- const QStringList &vals = m_option->cache_valuemap.value(QLatin1String("QMAKESPEC"));
+ const QStringList &vals = cache_valuemap.value(QLatin1String("QMAKESPEC"));
if (!vals.isEmpty())
m_option->qmakespec = vals.first();
}
@@ -1196,8 +1197,9 @@ ProItem::ProItemReturn ProFileEvaluator::Private::visitBeginProFile(ProFile * pr
if (!evaluateFileInto(spec,
&m_option->base_valuemap, &m_option->base_functions)) {
errorMessage(format("Could not read qmake configuration file %1").arg(spec));
- } else {
- evaluateFileInto(qmake_cache, &m_option->base_valuemap, 0);
+ } else if (!m_option->cachefile.isEmpty()) {
+ evaluateFileInto(m_option->cachefile,
+ &m_option->base_valuemap, &m_option->base_functions);
}
}
diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h
index cba159c6b8f..691dd78e02b 100644
--- a/src/shared/proparser/profileevaluator.h
+++ b/src/shared/proparser/profileevaluator.h
@@ -88,8 +88,7 @@ public:
friend class ProFileEvaluator;
friend class ProFileEvaluator::Private;
static QString field_sep; // Just a cache for quick construction
- QHash cache_valuemap; // Cached results of .qmake.cache
- QHash base_valuemap; // ~ and qmake.conf and default_pre.prf
+ QHash base_valuemap; // Cached results of qmake.conf, .qmake.cache & default_pre.prf
FunctionDefs base_functions;
QStringList feature_roots;
};
diff --git a/tests/manual/trk/adapter.pro b/tests/manual/trk/adapter.pro
index 22f4aa3cddb..9ee1a95d8f7 100644
--- a/tests/manual/trk/adapter.pro
+++ b/tests/manual/trk/adapter.pro
@@ -1,14 +1,20 @@
TEMPLATE = app
+DEBUGGERHOME = ../../../src/plugins/debugger/symbian
+
+INCLUDEPATH *= $$DEBUGGERHOME
+
+UTILSDIR = ../../../src/libs
QT = core network
win32:CONFIG+=console
-HEADERS += trkutils.h \
-trkfunctor.h \
-trkdevice.h \
+HEADERS += \
+ $$DEBUGGERHOME/trkutils.h \
+ $$DEBUGGERHOME/trkfunctor.h \
+ $$PWD/trkdevice.h \
SOURCES += \
- adapter.cpp \
- trkutils.cpp \
- trkdevice.cpp
+ $$DEBUGGERHOME/trkutils.cpp \
+ $$PWD/trkdevice.cpp \
+ $$PWD/adapter.cpp \
diff --git a/tests/manual/trk/runner.cpp b/tests/manual/trk/runner.cpp
index 1ed357b5df0..059eac4f946 100755
--- a/tests/manual/trk/runner.cpp
+++ b/tests/manual/trk/runner.cpp
@@ -27,1777 +27,17 @@
**
**************************************************************************/
-#include "trkutils.h"
-#include "trkdevicex.h"
+#include "symbianadapter.h"
-#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+#include
#include
+#include
#include
#include
#include
-
-#include
-#include
-#include
-#include
-
-/*
-fetch-register p info registers
-set-register P set
-binary-download X load, set
-read-aux-vector qXfer:auxv:read info auxv
-symbol-lookup qSymbol Detecting multiple threads
-attach vAttach attach
-verbose-resume vCont Stepping or resuming multiple threads
-run vRun run
-software-breakpoint Z0 break
-hardware-breakpoint Z1 hbreak
-write-watchpoint Z2 watch
-read-watchpoint Z3 rwatch
-access-watchpoint Z4 awatch
-target-features qXfer:features:read set architecture
-library-info qXfer:libraries:read info sharedlibrary
-memory-map qXfer:memory-map:read info mem
-read-spu-object qXfer:spu:read info spu
-write-spu-object qXfer:spu:write info spu
-get-thread-local-
-storage-address qGetTLSAddr Displaying __thread variables
-supported-packets qSupported Remote communications parameters
-pass-signals QPassSignals handle signal
-hostio-close-packet vFile:close remote get, remote put
-hostio-open-packet vFile:open remote get, remote put
-hostio-pread-packet vFile:pread remote get, remote put
-hostio-pwrite-packet vFile:pwrite remote get, remote put
-hostio-unlink-packet vFile:unlink remote delete
-*/
-
-using namespace trk;
-
-enum { KnownRegisters = RegisterPSGdb + 1};
-
-static const char *registerNames[KnownRegisters] =
-{
- "A1", "A2", "A3", "A4",
- 0, 0, 0, 0,
- 0, 0, 0, "AP",
- "IP", "SP", "LR", "PC",
- "PSTrk", 0, 0, 0,
- 0, 0, 0, 0,
- 0, "PSGdb"
-};
-
-static QByteArray dumpRegister(int n, uint value)
-{
- QByteArray ba;
- ba += ' ';
- if (n < KnownRegisters && registerNames[n]) {
- ba += registerNames[n];
- } else {
- ba += '#';
- ba += QByteArray::number(n);
- }
- ba += "=0x" + hexNumber(value);
- return ba;
-}
-
-#define TrkCB(s) TrkCallback(this, &Adapter::s)
-#define GdbCB(s) GdbCallback(this, &Adapter::s)
-
-struct GdbResult
-{
- QByteArray data;
-};
-
-///////////////////////////////////////////////////////////////////////
-//
-// Adapter
-//
-///////////////////////////////////////////////////////////////////////
-
-class Adapter : public QObject
-{
- Q_OBJECT
-
-public:
- typedef TrkFunctor1 TrkCallback;
- typedef TrkFunctor1 GdbCallback;
-
- Adapter();
- ~Adapter();
- void setGdbServerName(const QString &name);
- QString gdbServerIP() const;
- uint gdbServerPort() const;
- void setTrkServerName(const QString &name) { m_trkServerName = name; }
- void setVerbose(int verbose) { m_verbose = verbose; }
- void setSerialFrame(bool b) { m_serialFrame = b; }
- void setRegisterEndianness(Endianness r) { m_registerEndianness = r; }
- void setBufferedMemoryRead(bool b) { m_bufferedMemoryRead = b; }
-
-public slots:
- void startInferior();
-
-signals:
- void output(const QString &senderName, const QString &data);
-
-private slots:
- void handleProcError(QProcess::ProcessError error);
- void handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus);
- void handleProcStarted();
- void handleProcStateChanged(QProcess::ProcessState newState);
- void run();
- void startGdb();
-
-private:
- friend class RunnerGui;
- void connectProcess(QProcess *proc);
- void sendOutput(QObject *sender, const QString &data);
- void sendOutput(const QString &data) { sendOutput(0, data); }
-
- QString m_trkServerName; //
- QString m_gdbServerName; // 127.0.0.1:(2222+uid)
-
- QProcess m_gdbProc;
- QProcess m_rfcommProc;
- bool m_running;
-
-public:
- //
- // TRK
- //
- bool openTrkPort(const QString &port, QString *errorMessage);
- void sendTrkMessage(byte code,
- TrkCallback callback = TrkCallback(),
- const QByteArray &data = QByteArray(),
- const QVariant &cookie = QVariant(),
- bool invokeOnFailure = false);
- Q_SLOT void handleTrkResult(const trk::TrkResult &data);
- Q_SLOT void handleTrkError(const QString &msg);
-
- // convenience messages
- void waitForTrkFinished();
- void sendTrkAck(byte token);
-
- // kill process and breakpoints
- void cleanUp();
-
- void handleCpuType(const TrkResult &result);
- void handleCreateProcess(const TrkResult &result);
- void handleClearBreakpoint(const TrkResult &result);
- void handleSignalContinue(const TrkResult &result);
- void handleWaitForFinished(const TrkResult &result);
- void handleStop(const TrkResult &result);
- void handleSupportMask(const TrkResult &result);
- void handleTrkVersions(const TrkResult &result);
- void handleDisconnect(const TrkResult &result);
-
- void handleAndReportCreateProcess(const TrkResult &result);
- void handleAndReportReadRegisters(const TrkResult &result);
- QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const;
- QByteArray trkContinueMessage();
- QByteArray trkBreakpointMessage(uint addr, int len, int pid,
- bool armMode = true);
- void handleAndReportSetBreakpoint(const TrkResult &result);
- void handleReadMemoryBuffered(const TrkResult &result);
- void handleReadMemoryUnbuffered(const TrkResult &result);
- void handleStepRange(const TrkResult &result);
- void handleReadRegisters(const TrkResult &result);
- void reportReadMemoryBuffered(const TrkResult &result);
- void reportToGdb(const TrkResult &result);
-
- void clearTrkBreakpoint(const Breakpoint &bp);
-
- // set breakpoints behind gdb's back
- void setTrkBreakpoint(const Breakpoint &bp);
- void handleSetTrkBreakpoint(const TrkResult &result);
- void handleSetTrkMainBreakpoint(const TrkResult &result);
-
- void readMemory(uint addr, uint len);
- void interruptInferior();
-
- TrkDevice m_trkDevice;
-
- QList m_breakpoints;
-
- //
- // Gdb
- //
- struct GdbCommand
- {
- GdbCommand() : flags(0), callback(GdbCallback()), callbackName(0) {}
-
- int flags;
- GdbCallback callback;
- const char *callbackName;
- QString command;
- QVariant cookie;
- //QTime postTime;
- };
-
- void sendGdbMessage(const QString &msg,
- GdbCallback callback = GdbCallback(),
- const QVariant &cookie = QVariant());
- Q_SLOT void handleGdbConnection();
- Q_SLOT void readGdbServerCommand();
- void readGdbResponse();
- void handleGdbServerCommand(const QByteArray &ba);
- void sendGdbServerMessage(const QByteArray &msg,
- const QByteArray &logNote = QByteArray());
- void sendGdbServerMessageAfterTrkResponse(const QByteArray &msg,
- const QByteArray &logNote = QByteArray());
- void sendGdbServerAck();
- bool sendGdbServerPacket(const QByteArray &packet, bool doFlush);
-
- Q_SLOT void handleGdbReadyReadStandardError();
- Q_SLOT void handleGdbReadyReadStandardOutput();
- void logMessage(const QString &msg, bool force = false);
- Q_SLOT void trkLogMessage(const QString &msg);
-
- void handleInfoAddress(const GdbResult &result);
- void handleInfoMainAddress(const GdbResult &result);
-
- QTcpServer m_gdbServer;
- QPointer m_gdbConnection;
- QByteArray m_gdbReadBuffer;
- bool m_gdbAckMode;
-
- QHash m_gdbCookieForToken;
-
- //
- // Rfcomm
- //
- Q_SLOT void handleRfcommReadyReadStandardError();
- Q_SLOT void handleRfcommReadyReadStandardOutput();
-
- // Debuggee state
- void executeCommand(const QString &msg);
- Session m_session; // global-ish data (process id, target information)
- Snapshot m_snapshot; // local-ish data (memory and registers)
- int m_verbose;
- Endianness m_registerEndianness;
- bool m_serialFrame;
- bool m_bufferedMemoryRead;
-};
-
-Adapter::Adapter()
-{
- m_running = false;
- m_gdbAckMode = true;
- m_verbose = 2;
- m_registerEndianness = LittleEndian;
- //m_serialFrame = true;
- m_serialFrame = false;
- m_bufferedMemoryRead = true;
- //m_bufferedMemoryRead = false;
- // m_breakpoints.append(Breakpoint(0x0040)); // E32Main
- m_breakpoints.append(Breakpoint(0x0cc8)); // E32Main
- m_breakpoints.append(Breakpoint(0x0cd0)); // E32Main
- m_trkServerName = "/dev/rfcomm0";
-
- uid_t userId = getuid();
- m_gdbServerName = QString("127.0.0.1:%1").arg(2222 + userId);
-
- m_gdbProc.setObjectName("GDB PROCESS");
- connectProcess(&m_gdbProc);
- connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
- this, SLOT(handleGdbReadyReadStandardError()));
- connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
- this, SLOT(handleGdbReadyReadStandardOutput()));
-
- m_rfcommProc.setObjectName("RFCOMM PROCESS");
- connectProcess(&m_rfcommProc);
- connect(&m_rfcommProc, SIGNAL(readyReadStandardError()),
- this, SLOT(handleRfcommReadyReadStandardError()));
- connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
- this, SLOT(handleRfcommReadyReadStandardOutput()));
-
- connect(&m_trkDevice, SIGNAL(logMessage(QString)),
- this, SLOT(trkLogMessage(QString)));
-}
-
-Adapter::~Adapter()
-{
- m_gdbServer.close();
- logMessage("Shutting down.\n", true);
-}
-
-void Adapter::trkLogMessage(const QString &msg)
-{
- logMessage("TRK " + msg);
-}
-
-void Adapter::setGdbServerName(const QString &name)
-{
- m_gdbServerName = name;
-}
-
-QString Adapter::gdbServerIP() const
-{
- int pos = m_gdbServerName.indexOf(':');
- if (pos == -1)
- return m_gdbServerName;
- return m_gdbServerName.left(pos);
-}
-
-uint Adapter::gdbServerPort() const
-{
- int pos = m_gdbServerName.indexOf(':');
- if (pos == -1)
- return 0;
- return m_gdbServerName.mid(pos + 1).toUInt();
-}
-
-void Adapter::startInferior()
-{
- QString errorMessage;
- if (!openTrkPort(m_trkServerName, &errorMessage)) {
- logMessage(errorMessage, true);
- logMessage("LOOPING");
- QTimer::singleShot(1000, this, SLOT(startInferior()));
- return;
- }
-
- m_trkDevice.sendTrkInitialPing();
- sendTrkMessage(0x01); // Connect
- sendTrkMessage(0x05, TrkCB(handleSupportMask));
- sendTrkMessage(0x06, TrkCB(handleCpuType));
- sendTrkMessage(0x04, TrkCB(handleTrkVersions)); // Versions
- //sendTrkMessage(0x09); // Unrecognized command
- //sendTrkMessage(0x4a, 0,
- // "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); // ?
-
- QByteArray file("C:\\sys\\bin\\filebrowseapp.exe");
- appendString(&ba, file, TargetByteOrder);
- sendTrkMessage(0x40, TrkCB(handleCreateProcess), ba); // Create Item
- //sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(startGdbServer));
-}
-
-void Adapter::logMessage(const QString &msg, bool force)
-{
- if (m_verbose || force)
- emit output(QString(), msg);
-}
-
-//
-// Gdb
-//
-void Adapter::handleGdbConnection()
-{
- logMessage("HANDLING GDB CONNECTION");
-
- m_gdbConnection = m_gdbServer.nextPendingConnection();
- connect(m_gdbConnection, SIGNAL(disconnected()),
- m_gdbConnection, SLOT(deleteLater()));
- connect(m_gdbConnection, SIGNAL(readyRead()),
- this, SLOT(readGdbServerCommand()));
-}
-
-static inline QString msgGdbPacket(const QString &p)
-{
- return QLatin1String("gdb: ") + p;
-}
-
-void Adapter::readGdbServerCommand()
-{
- QByteArray packet = m_gdbConnection->readAll();
- m_gdbReadBuffer.append(packet);
-
- logMessage("gdb: -> " + QString::fromAscii(packet));
- if (packet != m_gdbReadBuffer)
- logMessage("buffer: " + m_gdbReadBuffer);
-
- QByteArray &ba = m_gdbReadBuffer;
- while (ba.size()) {
- char code = ba.at(0);
- ba = ba.mid(1);
-
- if (code == '+') {
- //logMessage("ACK");
- continue;
- }
-
- if (code == '-') {
- logMessage("NAK: Retransmission requested");
- continue;
- }
-
- if (code == char(0x03)) {
- logMessage("INTERRUPT RECEIVED");
- interruptInferior();
- continue;
- }
-
- if (code != '$') {
- logMessage("Broken package (2) " + quoteUnprintableLatin1(ba)
- + hexNumber(code));
- continue;
- }
-
- int pos = ba.indexOf('#');
- if (pos == -1) {
- logMessage("Invalid checksum format in "
- + quoteUnprintableLatin1(ba));
- continue;
- }
-
- bool ok = false;
- uint checkSum = ba.mid(pos + 1, 2).toUInt(&ok, 16);
- if (!ok) {
- logMessage("Invalid checksum format 2 in "
- + quoteUnprintableLatin1(ba));
- return;
- }
-
- //logMessage(QString("Packet checksum: %1").arg(checkSum));
- byte sum = 0;
- for (int i = 0; i < pos; ++i)
- sum += ba.at(i);
-
- if (sum != checkSum) {
- logMessage(QString("ERROR: Packet checksum wrong: %1 %2 in "
- + quoteUnprintableLatin1(ba)).arg(checkSum).arg(sum));
- }
-
- QByteArray response = ba.left(pos);
- ba.remove(0, pos + 3);
- handleGdbServerCommand(response);
- }
-}
-
-bool Adapter::sendGdbServerPacket(const QByteArray &packet, bool doFlush)
-{
- if (!m_gdbConnection) {
- logMessage(QString::fromLatin1("Cannot write to gdb: No connection (%1)")
- .arg(QString::fromLatin1(packet)), true);
- return false;
- }
- if (m_gdbConnection->state() != QAbstractSocket::ConnectedState) {
- logMessage(QString::fromLatin1("Cannot write to gdb: Not connected (%1)")
- .arg(QString::fromLatin1(packet)), true);
- return false;
- }
- if (m_gdbConnection->write(packet) == -1) {
- logMessage(QString::fromLatin1("Cannot write to gdb: %1 (%2)")
- .arg(m_gdbConnection->errorString()).arg(QString::fromLatin1(packet)), true);
- return false;
- }
- if (doFlush)
- m_gdbConnection->flush();
- return true;
-}
-
-void Adapter::sendGdbServerAck()
-{
- if (!m_gdbAckMode)
- return;
- QByteArray packet = "+";
- logMessage("gdb: <- " + packet);
- sendGdbServerPacket(packet, false);
-}
-
-void Adapter::sendGdbServerMessage(const QByteArray &msg, const QByteArray &logNote)
-{
- byte sum = 0;
- for (int i = 0; i != msg.size(); ++i)
- sum += msg.at(i);
-
- char checkSum[30];
- qsnprintf(checkSum, sizeof(checkSum) - 1, "%02x ", sum);
-
- //logMessage(QString("Packet checksum: %1").arg(sum));
-
- QByteArray packet;
- packet.append("$");
- packet.append(msg);
- packet.append('#');
- packet.append(checkSum);
- int pad = qMax(0, 24 - packet.size());
- logMessage("gdb: <- " + packet + QByteArray(pad, ' ') + logNote);
- sendGdbServerPacket(packet, true);
-}
-
-void Adapter::sendGdbServerMessageAfterTrkResponse(const QByteArray &msg,
- const QByteArray &logNote)
-{
- QByteArray ba = msg + char(1) + logNote;
- sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(reportToGdb), "", ba); // Answer gdb
-}
-
-void Adapter::reportToGdb(const TrkResult &result)
-{
- QByteArray message = result.cookie.toByteArray();
- QByteArray note;
- int pos = message.lastIndexOf(char(1)); // HACK
- if (pos != -1) {
- note = message.mid(pos + 1);
- message = message.left(pos);
- }
- message.replace("@CODESEG@", hexNumber(m_session.codeseg));
- message.replace("@DATASEG@", hexNumber(m_session.dataseg));
- message.replace("@PID@", hexNumber(m_session.pid));
- message.replace("@TID@", hexNumber(m_session.tid));
- sendGdbServerMessage(message, note);
-}
-
-QByteArray Adapter::trkBreakpointMessage(uint addr, int len, int pid, bool armMode)
-{
- QByteArray ba;
- appendByte(&ba, 0x82); // unused option
- appendByte(&ba, armMode /*bp.mode == ArmMode*/ ? 0x00 : 0x01);
- appendInt(&ba, addr);
- appendInt(&ba, len);
- appendInt(&ba, 0x00000001);
- appendInt(&ba, pid);
- appendInt(&ba, 0xFFFFFFFF);
- return ba;
-}
-
-void Adapter::handleGdbServerCommand(const QByteArray &response)
-{
- // http://sourceware.org/gdb/current/onlinedocs/gdb_34.html
- if (0) {}
-
- else if (response == "!") {
- sendGdbServerAck();
- //sendGdbServerMessage("", "extended mode not enabled");
- sendGdbServerMessage("OK", "extended mode enabled");
- }
-
- else if (response.startsWith("?")) {
- logMessage(msgGdbPacket(QLatin1String("Query halted")));
- // Indicate the reason the target halted.
- // The reply is the same as for step and continue.
- sendGdbServerAck();
- // The command below will trigger fetching a stack trace while
- // the process does not seem to be fully functional. Most notably
- // the PC points to a 0x9..., which is not in "our" range
- //sendGdbServerMessage("T05library:r;", "target halted (library load)");
- //sendGdbServerMessage("S05", "target halted (trap)");
- sendGdbServerMessage("S00", "target halted (trap)");
- //sendGdbServerMessage("O" + QByteArray("Starting...").toHex());
- }
-
- else if (response == "c") {
- logMessage(msgGdbPacket(QLatin1String("Continue")));
- sendGdbServerAck();
- QByteArray ba;
- appendByte(&ba, 0); // options
- appendInt(&ba, 0); // start address
- appendInt(&ba, 0); // end address
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- sendTrkMessage(0x18, TrkCallback(), ba);
- }
-
- else if (response.startsWith("C")) {
- logMessage(msgGdbPacket(QLatin1String("Continue with signal")));
- // C sig[;addr] Continue with signal sig (hex signal number)
- //Reply: See section D.3 Stop Reply Packets, for the reply specifications.
- sendGdbServerAck();
- bool ok = false;
- uint signalNumber = response.mid(1).toInt(&ok, 16);
- QByteArray ba;
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- sendTrkMessage(0x18, TrkCB(handleSignalContinue), ba, signalNumber); // Continue
- }
-
- else if (response.startsWith("D")) {
- sendGdbServerAck();
- sendGdbServerMessage("OK", "shutting down");
- qApp->quit();
- }
-
- else if (response == "g") {
- logMessage(msgGdbPacket(QLatin1String("Read registers")));
- // Read general registers.
- //sendGdbServerMessage("00000000", "read registers");
- sendGdbServerAck();
- QByteArray ba;
- appendByte(&ba, 0); // Register set, only 0 supported
- appendShort(&ba, 0);
- appendShort(&ba, RegisterCount - 1); // last register
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- sendTrkMessage(0x12, TrkCB(handleAndReportReadRegisters), ba, QVariant(), true);
- }
-
- else if (response.startsWith("Hc")) {
- logMessage(msgGdbPacket(QLatin1String("Set thread & continue")));
- // Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
- // for step and continue operations
- //$Hc-1#09
- sendGdbServerAck();
- sendGdbServerMessage("OK", "Set current thread for step & continue");
- }
-
- else if (response.startsWith("Hg")) {
- logMessage(msgGdbPacket(QLatin1String("Set thread")));
- // Set thread for subsequent operations (`m', `M', `g', `G', et.al.).
- // for 'other operations. 0 - any thread
- //$Hg0#df
- sendGdbServerAck();
- m_session.currentThread = response.mid(2).toInt(0, 16);
- sendGdbServerMessage("OK", "Set current thread "
- + QByteArray::number(m_session.currentThread));
- }
-
- else if (response == "k") {
- logMessage(msgGdbPacket(QLatin1String("kill")));
- // kill
- sendGdbServerAck();
- QByteArray ba;
- appendByte(&ba, 0); // Sub-command: Delete Process
- appendInt(&ba, m_session.pid);
- sendTrkMessage(0x41, TrkCallback(), ba, "Delete process"); // Delete Item
- sendGdbServerMessageAfterTrkResponse("", "process killed");
- }
-
- else if (response.startsWith("m")) {
- logMessage(msgGdbPacket(QLatin1String("Read memory")));
- // m addr,length
- sendGdbServerAck();
- uint addr = 0, len = 0;
- do {
- const int pos = response.indexOf(',');
- if (pos == -1)
- break;
- bool ok;
- addr = response.mid(1, pos - 1).toUInt(&ok, 16);
- if (!ok)
- break;
- len = response.mid(pos + 1).toUInt(&ok, 16);
- if (!ok)
- break;
- } while (false);
- if (len) {
- readMemory(addr, len);
- } else {
- sendGdbServerMessage("E20", "Error " + response);
- }
- }
- else if (response.startsWith("p")) {
- logMessage(msgGdbPacket(QLatin1String("read register")));
- // 0xf == current instruction pointer?
- //sendGdbServerMessage("0000", "current IP");
- sendGdbServerAck();
- #if 0
- A1 = 0, first integer-like argument
- A4 = 3, last integer-like argument
- AP = 11,
- IP = 12,
- SP = 13, Contains address of top of stack
- LR = 14, address to return to from a function call
- PC = 15, Contains program counter
- F0 = 16, first floating point register
- F3 = 19, last floating point argument register
- F7 = 23, last floating point register
- FPS = 24, floating point status register
- PS = 25, Contains processor status
- WR0, WMMX data registers.
- WR15 = WR0 + 15,
- WC0, WMMX control registers.
- WCSSF = WC0 + 2,
- WCASF = WC0 + 3,
- WC7 = WC0 + 7,
- WCGR0, WMMX general purpose registers.
- WCGR3 = WCGR0 + 3,
- WCGR7 = WCGR0 + 7,
- NUM_REGS,
-
- // Other useful registers.
- FP = 11, Frame register in ARM code, if used.
- THUMB_FP = 7, Frame register in Thumb code, if used.
- NUM_ARG_REGS = 4,
- LAST_ARG = A4,
- NUM_FP_ARG_REGS = 4,
- LAST_FP_ARG = F3
- #endif
- bool ok = false;
- const uint registerNumber = response.mid(1).toInt(&ok, 16);
- QByteArray logMsg = "Read Register";
- if (registerNumber == RegisterPSGdb) {
- QByteArray ba;
- appendInt(&ba, m_snapshot.registers[RegisterPSTrk], m_registerEndianness);
- logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]);
- sendGdbServerMessage(ba.toHex(), logMsg);
- } else if (registerNumber < RegisterCount) {
- QByteArray ba;
- appendInt(&ba, m_snapshot.registers[registerNumber], m_registerEndianness);
- logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]);
- sendGdbServerMessage(ba.toHex(), logMsg);
- } else {
- sendGdbServerMessage("0000", "read single unknown register #" + QByteArray::number(registerNumber));
- //sendGdbServerMessage("E01", "read single unknown register");
- }
- }
-
- else if (response == "qAttached") {
- //$qAttached#8f
- // 1: attached to an existing process
- // 0: created a new process
- sendGdbServerAck();
- sendGdbServerMessage("0", "new process created");
- //sendGdbServerMessage("1", "attached to existing process");
- //sendGdbServerMessage("E01", "new process created");
- }
-
- else if (response.startsWith("qC")) {
- logMessage(msgGdbPacket(QLatin1String("query thread id")));
- // Return the current thread ID
- //$qC#b4
- sendGdbServerAck();
- sendGdbServerMessageAfterTrkResponse("QC@TID@");
- }
-
- else if (response.startsWith("qSupported")) {
- //$qSupported#37
- //$qSupported:multiprocess+#c6
- //logMessage("Handling 'qSupported'");
- sendGdbServerAck();
- if (0)
- sendGdbServerMessage(QByteArray(), "nothing supported");
- else
- sendGdbServerMessage(
- "PacketSize=7cf;"
- //"QPassSignals+;"
- "qXfer:libraries:read+;"
- //"qXfer:auxv:read+;"
- "qXfer:features:read+");
- }
-
- else if (response == "qPacketInfo") {
- // happens with gdb 6.4.50.20060226-cvs / CodeSourcery
- // deprecated by qSupported?
-
- sendGdbServerAck();
- sendGdbServerMessage("", "FIXME: nothing?");
- }
-
- else if (response == "qOffsets") {
- sendGdbServerAck();
- sendGdbServerMessageAfterTrkResponse("TextSeg=@CODESEG@;DataSeg=@DATASEG@");
- }
-
- else if (response == "qSymbol::") {
- if (m_verbose)
- logMessage(msgGdbPacket(QLatin1String("notify can handle symbol lookup")));
- // Notify the target that GDB is prepared to serve symbol lookup requests.
- sendGdbServerAck();
- if (1)
- sendGdbServerMessage("OK", "no further symbols needed");
- else
- sendGdbServerMessage("qSymbol:" + QByteArray("_Z7E32Mainv").toHex(), "ask for more");
- }
-
- else if (response.startsWith("qXfer:features:read:target.xml:")) {
- // $qXfer:features:read:target.xml:0,7ca#46...Ack
- sendGdbServerAck();
- sendGdbServerMessage("lsymbianelf ");
- }
-
- else if (response == "QStartNoAckMode") {
- //$qSupported#37
- //logMessage("Handling 'QStartNoAckMode'");
- sendGdbServerAck();
- sendGdbServerMessage("OK", "ack no-ack mode");
- m_gdbAckMode = false;
- }
-
- else if (response.startsWith("QPassSignals")) {
- // list of signals to pass directly to inferior
- // $QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;4c;#8f
- // happens only if "QPassSignals+;" is qSupported
- sendGdbServerAck();
- // FIXME: use the parameters
- sendGdbServerMessage("OK", "passing signals accepted");
- }
-
- else if (response == "s") {
- if (m_verbose)
- logMessage(msgGdbPacket(QLatin1String("Step range")));
- sendGdbServerAck();
- QByteArray ba;
- appendByte(&ba, 0); // options
- appendInt(&ba, m_snapshot.registers[RegisterPC]); // start address
- appendInt(&ba, m_snapshot.registers[RegisterPC] + 8); // end address
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- sendTrkMessage(0x19, TrkCB(handleStepRange), ba, "Step range");
- // FIXME: should be triggered by "real" stop"
- //sendGdbServerMessageAfterTrkResponse("S05", "target halted");
- }
-
- else if (response == "vCont?") {
- // actions supported by the vCont packet
- sendGdbServerAck();
- sendGdbServerMessage("OK"); // we don't support vCont.
- //sendGdbServerMessage("vCont;c");
- }
-
- else if (response == "vCont;c") {
- // vCont[;action[:thread-id]]...'
- sendGdbServerAck();
- m_running = true;
- sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
- }
-
- else if (response.startsWith("vCont;s")) {
- // vCont[;action[:thread-id]]...'
- sendGdbServerAck();
- m_running = true;
- sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
- }
-
- else if (response.startsWith("vKill")) {
- // kill
- sendGdbServerAck();
- QByteArray ba;
- appendByte(&ba, 0); // Sub-command: Delete Process
- appendInt(&ba, m_session.pid);
- sendTrkMessage(0x41, TrkCallback(), ba, "Delete process"); // Delete Item
- sendGdbServerMessageAfterTrkResponse("", "process killed");
- }
-
- else if (0 && response.startsWith("Z0,")) {
- // Tell gdb we don't support software breakpoints
- sendGdbServerMessage("");
- }
-
- else if (response.startsWith("Z0,") || response.startsWith("Z1,")) {
- // Insert breakpoint
- if (m_verbose)
- logMessage(msgGdbPacket(QLatin1String("Insert breakpoint")));
- // $z0,786a4ccc,4#99
- const int pos = response.lastIndexOf(',');
- bool ok = false;
- const uint addr = response.mid(3, pos - 3).toInt(&ok, 16);
- const uint len = response.mid(pos + 1).toInt(&ok, 16);
- qDebug() << "ADDR: " << hexNumber(addr) << " LEN: " << len;
- if (m_verbose)
- logMessage(QString::fromLatin1("Inserting breakpoint at 0x%1, %2")
- .arg(addr, 0, 16).arg(len));
-
- //---IDE------------------------------------------------------
- // Command: 0x1B Set Break
- //BreakType: 0x82
- // Options: 0x00
- // Address: 0x78674340 (2020033344) i.e + 0x00000340
- // Length: 0x00000001 (1)
- // Count: 0x00000000 (0)
- //ProcessID: 0x000001b5 (437)
- // ThreadID: 0xffffffff (-1)
- // [1B 09 82 00 78 67 43 40 00 00 00 01 00 00 00 00
- // 00 00 01 B5 FF FF FF FF]
- const QByteArray ba = trkBreakpointMessage(addr, len, m_session.pid);
- sendTrkMessage(0x1B, TrkCB(handleAndReportSetBreakpoint), ba);
- //m_session.toekn
-
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 09 00 00 00 00 0A]
- } else if (response.startsWith("qPart:") || response.startsWith("qXfer:")) {
- QByteArray data = response.mid(1 + response.indexOf(':'));
- // "qPart:auxv:read::0,147": Read OS auxiliary data (see info aux)
- bool handled = false;
- if (data.startsWith("auxv:read::")) {
- const int offsetPos = data.lastIndexOf(':') + 1;
- const int commaPos = data.lastIndexOf(',');
- if (commaPos != -1) {
- bool ok1 = false, ok2 = false;
- const int offset = data.mid(offsetPos, commaPos - offsetPos)
- .toInt(&ok1, 16);
- const int length = data.mid(commaPos + 1).toInt(&ok2, 16);
- if (ok1 && ok2) {
- const QString msg = QString::fromLatin1("Read of OS auxilary "
- "vector (%1, %2) not implemented.").arg(offset).arg(length);
- logMessage(msgGdbPacket(msg), true);
- sendGdbServerMessage("E20", msg.toLatin1());
- handled = true;
- }
- }
- } // auxv read
- if (!handled) {
- const QString msg = QLatin1String("FIXME unknown 'XFER'-request: ")
- + QString::fromAscii(response);
- logMessage(msgGdbPacket(msg), true);
- sendGdbServerMessage("E20", msg.toLatin1());
- }
- } // qPart/qXfer
- else {
- logMessage(msgGdbPacket(QLatin1String("FIXME unknown: ")
- + QString::fromAscii(response)));
- }
-}
-
-void Adapter::executeCommand(const QString &msg)
-{
- if (msg == "EI") {
- sendGdbMessage("-exec-interrupt");
- } else if (msg == "C") {
- sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
- } else if (msg == "I") {
- interruptInferior();
- } else {
- logMessage("EXECUTING GDB COMMAND " + msg);
- sendGdbMessage(msg);
- }
-}
-
-bool Adapter::openTrkPort(const QString &port, QString *errorMessage)
-{
- connect(&m_trkDevice, SIGNAL(messageReceived(trk::TrkResult)),
- this, SLOT(handleTrkResult(trk::TrkResult)));
- connect(&m_trkDevice, SIGNAL(error(QString)),
- this, SLOT(handleTrkError(QString)));
- if (m_verbose > 1)
- m_trkDevice.setVerbose(true);
- m_trkDevice.setSerialFrame(m_serialFrame);
- return m_trkDevice.open(port, errorMessage);
-}
-
-void Adapter::sendTrkMessage(byte code, TrkCallback callback,
- const QByteArray &data, const QVariant &cookie, bool invokeOnFailure)
-{
- m_trkDevice.sendTrkMessage(code, callback, data, cookie, invokeOnFailure);
-}
-
-void Adapter::waitForTrkFinished()
-{
- // initiate one last roundtrip to ensure all is flushed
- sendTrkMessage(0x0, TrkCB(handleWaitForFinished));
-}
-
-void Adapter::sendTrkAck(byte token)
-{
- logMessage(QString("SENDING ACKNOWLEDGEMENT FOR TOKEN %1").arg(int(token)));
- m_trkDevice.sendTrkAck(token);
-}
-
-void Adapter::handleTrkError(const QString &msg)
-{
- logMessage("## TRK ERROR: " + msg);
-}
-
-void Adapter::handleTrkResult(const TrkResult &result)
-{
- logMessage("HANDLING RESULT: " + result.data);
- if (result.isDebugOutput) {
- sendTrkAck(result.token);
- logMessage(QLatin1String("APPLICATION OUTPUT: ") +
- QString::fromAscii(result.data));
- sendGdbServerMessage("O" + result.data.toHex());
- return;
- }
- QByteArray prefix = "READ BUF: ";
- QByteArray str = result.toString().toUtf8();
- switch (result.code) {
- case 0x80: // ACK
- break;
- case 0xff: { // NAK. This mostly means transmission error, not command failed.
- QString logMsg;
- QTextStream(&logMsg) << prefix << "NAK: for token=" << result.token
- << " ERROR: " << errorMessage(result.data.at(0)) << ' ' << str;
- logMessage(logMsg, true);
- break;
- }
- case 0x90: { // Notified Stopped
- // 90 01 78 6a 40 40 00 00 07 23 00 00 07 24 00 00
- const char *data = result.data.data();
- const uint addr = extractInt(data);
- const uint pid = extractInt(data + 4);
- const uint tid = extractInt(data + 8);
- logMessage(prefix + QString::fromLatin1("NOTE: PID %1/TID %2 "
- "STOPPED at 0x%3").arg(pid).arg(tid).arg(addr, 0, 16));
- sendTrkAck(result.token);
- if (addr) {
- // Todo: Do not send off GdbMessages if a synced gdb
- // query is pending, queue instead
- if (m_running) {
- m_running = false;
- sendGdbServerMessage("S05", "Target stopped");
- }
- } else {
- if (m_verbose)
- logMessage(QLatin1String("Ignoring stop at 0"));
- }
- break;
- }
- case 0x91: { // Notify Exception (obsolete)
- logMessage(prefix + "NOTE: EXCEPTION " + str);
- sendTrkAck(result.token);
- break;
- }
- case 0x92: { //
- logMessage(prefix + "NOTE: INTERNAL ERROR: " + str);
- sendTrkAck(result.token);
- break;
- }
-
- // target->host OS notification
- case 0xa0: { // Notify Created
- const char *data = result.data.data();
- const byte error = result.data.at(0);
- // type: 1 byte; for dll item, this value is 2.
- const byte type = result.data.at(1);
- const uint pid = extractInt(data + 2);
- const uint tid = extractInt(data + 6);
- const uint codeseg = extractInt(data + 10);
- const uint dataseg = extractInt(data + 14);
- const uint len = extractShort(data + 18);
- const QByteArray name = result.data.mid(20, len); // library name
- m_session.modules += QString::fromAscii(name);
- QString logMsg;
- QTextStream str(&logMsg);
- str << prefix << " NOTE: LIBRARY LOAD: token=" << result.token;
- if (error)
- str << " ERROR: " << int(error);
- str << " TYPE: " << int(type) << " PID: " << pid << " TID: " << tid;
- str << " CODE: 0x" << hexNumber(codeseg);
- str << " DATA: 0x" << hexNumber(dataseg);
- str << " NAME: '" << name << '\'';
- logMessage(logMsg);
- sendGdbServerMessage("T05library:" + name);
- //sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
- break;
- }
- case 0xa1: { // NotifyDeleted
- const ushort itemType = extractByte(result.data.data() + 1);
- const ushort len = result.data.size() > 12
- ? extractShort(result.data.data() + 10) : ushort(0);
- const QString name = len
- ? QString::fromAscii(result.data.mid(12, len)) : QString();
- if (!name.isEmpty())
- m_session.modules.removeAll(name);
- logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3")
- .arg(QString::fromAscii(prefix))
- .arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS"))
- .arg(name));
- sendTrkAck(result.token);
- if (itemType == 0) {
- sendGdbServerMessage("W00", "Process exited");
- //sendTrkMessage(0x02, TrkCB(handleDisconnect));
- }
- break;
- }
- case 0xa2: { // NotifyProcessorStarted
- logMessage(prefix + "NOTE: PROCESSOR STARTED: " + str);
- sendTrkAck(result.token);
- break;
- }
- case 0xa6: { // NotifyProcessorStandby
- logMessage(prefix + "NOTE: PROCESSOR STANDBY: " + str);
- sendTrkAck(result.token);
- break;
- }
- case 0xa7: { // NotifyProcessorReset
- logMessage(prefix + "NOTE: PROCESSOR RESET: " + str);
- sendTrkAck(result.token);
- break;
- }
- default: {
- logMessage(prefix + "INVALID: " + str);
- break;
- }
- }
-}
-
-void Adapter::handleCpuType(const TrkResult &result)
-{
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 03 00 04 00 00 04 00 00 00]
- m_session.cpuMajor = result.data[1];
- m_session.cpuMinor = result.data[2];
- m_session.bigEndian = result.data[3];
- m_session.defaultTypeSize = result.data[4];
- m_session.fpTypeSize = result.data[5];
- m_session.extended1TypeSize = result.data[6];
- //m_session.extended2TypeSize = result.data[6];
- QString logMsg;
- QTextStream(&logMsg) << "HANDLE CPU TYPE: CPU=" << m_session.cpuMajor << '.'
- << m_session.cpuMinor << " bigEndian=" << m_session.bigEndian
- << " defaultTypeSize=" << m_session.defaultTypeSize
- << " fpTypeSize=" << m_session.fpTypeSize
- << " extended1TypeSize=" << m_session.extended1TypeSize;
- logMessage(logMsg);
-}
-
-void Adapter::setTrkBreakpoint(const Breakpoint &bp)
-{
- //---IDE------------------------------------------------------
- // Command: 0x1B Set Break
- //BreakType: 0x82
- // Options: 0x00
- // Address: 0x78674340 (2020033344) i.e + 0x00000340
- // Length: 0x00000001 (1)
- // Count: 0x00000000 (0)
- //ProcessID: 0x000001b5 (437)
- // ThreadID: 0xffffffff (-1)
- // [1B 09 82 00 78 67 43 40 00 00 00 01 00 00 00 00
- // 00 00 01 B5 FF FF FF FF]
- const QByteArray ba = trkBreakpointMessage(m_session.codeseg + bp.offset,
- 1, m_session.pid);
- sendTrkMessage(0x1B, TrkCB(handleSetTrkBreakpoint), ba);
-
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 09 00 00 00 00 0A]
-}
-
-void Adapter::handleSetTrkBreakpoint(const TrkResult &result)
-{
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 09 00 00 00 00 0A]
- const uint bpnr = extractInt(result.data.data());
- if (m_verbose)
- logMessage("SET BREAKPOINT 0x" + hexNumber(bpnr)
- + stringFromArray(result.data.data()));
-}
-
-void Adapter::handleCreateProcess(const TrkResult &result)
-{
- // 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]
- 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: 0x" + hexNumber(m_session.pid));
- logMessage("TID: 0x" + hexNumber(m_session.tid));
- logMessage("COD: 0x" + hexNumber(m_session.codeseg));
- logMessage("DAT: 0x" + hexNumber(m_session.dataseg));
-
- QByteArray ba;
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
-
- startGdb();
-
-
-#if 0
- //---IDE------------------------------------------------------
- // Command: 0x42 Read Info
- // [42 0C 00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F
- // 72 70 68 69 63 44 4C 4C 32 2E 64 6C 6C 00]
- sendTrkMessage(0x42, TrkCB(handleReadInfo),
- "00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F "
- "72 70 68 69 63 44 4C 4C 32 2E 64 6C 6C 00");
- //sendTrkMessage(0x42, TrkCB(handleReadInfo),
- // "00 01 00 00 00 00");
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x20 Unspecified general OS-related error
- // [80 0C 20]
-
-
- //---IDE------------------------------------------------------
- // Command: 0x42 Read Info
- // [42 0D 00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F
- // 72 70 68 69 63 44 4C 4C 31 2E 64 6C 6C 00]
- sendTrkMessage(0x42, TrkCB(handleReadInfo),
- "00 06 00 00 00 00 00 14 50 6F 6C 79 6D 6F "
- "72 70 68 69 63 44 4C 4C 31 2E 64 6C 6C 00");
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x20 Unspecified general OS-related error
- // [80 0D 20]
-#endif
-
- //sendTrkMessage(0x18, TrkCB(handleStop),
- // "01 " + formatInt(m_session.pid) + formatInt(m_session.tid));
-}
-
-void Adapter::handleReadRegisters(const TrkResult &result)
-{
- logMessage(" RESULT: " + result.toString());
- // [80 0B 00 00 00 00 00 C9 24 FF BC 00 00 00 00 00
- // 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...]
-
- const char *data = result.data.data() + 1; // Skip ok byte
- for (int i = 0; i < RegisterCount; ++i)
- m_snapshot.registers[i] = extractInt(data + 4 * i);
-}
-
-void Adapter::handleAndReportReadRegisters(const TrkResult &result)
-{
- handleReadRegisters(result);
- QByteArray ba;
- for (int i = 0; i < 16; ++i) {
- const uint reg = m_registerEndianness == LittleEndian
- ? swapEndian(m_snapshot.registers[i]) : m_snapshot.registers[i];
- ba += hexNumber(reg, 8);
- }
- QByteArray logMsg = "REGISTER CONTENTS: ";
- if (m_verbose > 1) {
- for (int i = 0; i < RegisterCount; ++i) {
- logMsg += dumpRegister(i, m_snapshot.registers[i]);
- logMsg += ' ';
- }
- }
- sendGdbServerMessage(ba, logMsg);
-}
-
-static inline QString msgMemoryReadError(int code, uint addr, uint len = 0)
-{
- const QString lenS = len ? QString::number(len) : QLatin1String("");
- return QString::fromLatin1("Memory read error %1 at: 0x%2 %3")
- .arg(code).arg(addr, 0 ,16).arg(lenS);
-}
-
-void Adapter::handleReadMemoryBuffered(const TrkResult &result)
-{
- if (extractShort(result.data.data() + 1) + 3 != result.data.size())
- logMessage("\n BAD MEMORY RESULT: " + result.data.toHex() + "\n");
- const uint blockaddr = result.cookie.toUInt();
- if (const int errorCode = result.errorCode()) {
- logMessage(msgMemoryReadError(errorCode, blockaddr));
- return;
- }
- const QByteArray ba = result.data.mid(3);
- m_snapshot.memory.insert(blockaddr, ba);
-}
-
-// Format log message for memory access with some smartness about registers
-QByteArray Adapter::memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const
-{
- QByteArray logMsg = "memory contents";
- if (m_verbose > 1) {
- logMsg += " addr: 0x";
- logMsg += QByteArray::number(addr, 16);
- // indicate dereferencing of registers
- if (len == 4) {
- if (addr == m_snapshot.registers[RegisterPC]) {
- logMsg += "[PC]";
- } else if (addr == m_snapshot.registers[RegisterPSTrk]) {
- logMsg += "[PSTrk]";
- } else if (addr == m_snapshot.registers[RegisterSP]) {
- logMsg += "[SP]";
- } else if (addr == m_snapshot.registers[RegisterLR]) {
- logMsg += "[LR]";
- } else if (addr > m_snapshot.registers[RegisterSP] &&
- (addr - m_snapshot.registers[RegisterSP]) < 10240) {
- logMsg += "[SP+"; // Stack area ...stack seems to be top-down
- logMsg += QByteArray::number(addr - m_snapshot.registers[RegisterSP]);
- logMsg += ']';
- }
- }
- logMsg += " length ";
- logMsg += QByteArray::number(len);
- logMsg += " :";
- logMsg += stringFromArray(ba, 16);
- }
- return logMsg;
-}
-
-QByteArray Adapter::trkContinueMessage()
-{
- QByteArray ba;
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- return ba;
-}
-
-void Adapter::reportReadMemoryBuffered(const TrkResult &result)
-{
- const qulonglong cookie = result.cookie.toULongLong();
- const uint addr = cookie >> 32;
- const uint len = uint(cookie);
-
- // Gdb accepts less memory according to documentation.
- // Send E on complete failure.
- QByteArray ba;
- uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
- for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
- const Snapshot::Memory::const_iterator it = m_snapshot.memory.constFind(blockaddr);
- if (it == m_snapshot.memory.constEnd())
- break;
- ba.append(it.value());
- }
- const int previousChunkOverlap = addr % MemoryChunkSize;
- if (previousChunkOverlap != 0 && ba.size() > previousChunkOverlap)
- ba.remove(0, previousChunkOverlap);
- if (ba.size() > int(len))
- ba.truncate(len);
-
- if (ba.isEmpty()) {
- ba = "E20";
- sendGdbServerMessage(ba, msgMemoryReadError(32, addr, len).toLatin1());
- } else {
- sendGdbServerMessage(ba.toHex(), memoryReadLogMessage(addr, len, ba));
- }
-}
-
-void Adapter::handleReadMemoryUnbuffered(const TrkResult &result)
-{
- //logMessage("UNBUFFERED MEMORY READ: " + stringFromArray(result.data));
- const uint blockaddr = result.cookie.toUInt();
- if (extractShort(result.data.data() + 1) + 3 != result.data.size())
- logMessage("\n BAD MEMORY RESULT: " + result.data.toHex() + "\n");
- if (const int errorCode = result.errorCode()) {
- const QByteArray ba = "E20";
- sendGdbServerMessage(ba, msgMemoryReadError(32, blockaddr).toLatin1());
- } else {
- const QByteArray ba = result.data.mid(3);
- sendGdbServerMessage(ba.toHex(), memoryReadLogMessage(blockaddr, ba.size(), ba));
- }
-}
-
-void Adapter::handleStepRange(const TrkResult &result)
-{
- // [80 0f 12]
- //uint bpnr = extractInt(result.data.data());
- logMessage("STEPPING FINISHED " + stringFromArray(result.data.data()));
- sendGdbServerMessage("S05", "Stepping finished");
-}
-
-void Adapter::handleAndReportSetBreakpoint(const TrkResult &result)
-{
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 09 00 00 00 00 0A]
- uint bpnr = extractByte(result.data.data());
- logMessage("SET BREAKPOINT 0x" + hexNumber(bpnr) + " "
- + stringFromArray(result.data.data()));
- sendGdbServerMessage("OK");
-}
-
-void Adapter::clearTrkBreakpoint(const Breakpoint &bp)
-{
- //---IDE------------------------------------------------------
- // Command: 0x1C Clear Break
- // [1C 25 00 00 00 0A 78 6A 43 40]
- QByteArray ba;
- appendByte(&ba, 0x00);
- appendShort(&ba, bp.number);
- appendInt(&ba, m_session.codeseg + bp.offset);
- sendTrkMessage(0x1C, TrkCB(handleClearBreakpoint), ba);
-}
-
-void Adapter::handleClearBreakpoint(const TrkResult &result)
-{
- Q_UNUSED(result);
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 09 00 00 00 00 0A]
- logMessage("CLEAR BREAKPOINT ");
-}
-
-void Adapter::handleSignalContinue(const TrkResult &result)
-{
- int signalNumber = result.cookie.toInt();
- logMessage(" HANDLE SIGNAL CONTINUE: " + stringFromArray(result.data));
- logMessage("NUMBER" + QString::number(signalNumber));
- sendGdbServerMessage("O" + QByteArray("Console output").toHex());
- sendGdbServerMessage("W81"); // "Process exited with result 1
-}
-
-void Adapter::handleWaitForFinished(const TrkResult &result)
-{
- logMessage(" FINISHED: " + stringFromArray(result.data));
- //qApp->exit(1);
-}
-
-void Adapter::handleSupportMask(const TrkResult &result)
-{
- const char *data = result.data.data();
- QByteArray str;
- for (int i = 0; i < 32; ++i) {
- //str.append(" [" + formatByte(data[i]) + "]: ");
- for (int j = 0; j < 8; ++j)
- if (data[i] & (1 << j))
- str.append(QByteArray::number(i * 8 + j, 16));
- }
- logMessage("SUPPORTED: " + str);
- }
-
-void Adapter::handleTrkVersions(const TrkResult &result)
-{
- QString logMsg;
- QTextStream str(&logMsg);
- str << "Versions: ";
- if (result.data.size() >= 5) {
- str << "Trk version " << int(result.data.at(1)) << '.'
- << int(result.data.at(2))
- << ", Protocol version " << int(result.data.at(3))
- << '.' << int(result.data.at(4));
- }
- logMessage(logMsg);
-}
-
-void Adapter::handleDisconnect(const TrkResult & /*result*/)
-{
- logMessage(QLatin1String("Trk disconnected"), true);
-}
-
-void Adapter::cleanUp()
-{
- //
- //---IDE------------------------------------------------------
- // Command: 0x41 Delete Item
- // Sub Cmd: Delete Process
- //ProcessID: 0x0000071F (1823)
- // [41 24 00 00 00 00 07 1F]
- logMessage(QString::fromLatin1("Cleanup PID=%1").arg(m_session.pid), true);
- if (!m_session.pid)
- return;
-
- QByteArray ba;
- appendByte(&ba, 0x00);
- appendByte(&ba, 0x00);
- appendInt(&ba, m_session.pid);
- sendTrkMessage(0x41, TrkCallback(), ba, "Delete process");
-
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 24 00]
-
- foreach (const Breakpoint &bp, m_breakpoints)
- clearTrkBreakpoint(bp);
-
- sendTrkMessage(0x02, TrkCB(handleDisconnect));
- //---IDE------------------------------------------------------
- // Command: 0x1C Clear Break
- // [1C 25 00 00 00 0A 78 6A 43 40]
-
- //---TRK------------------------------------------------------
- // Command: 0xA1 Notify Deleted
- // [A1 09 00 00 00 00 00 00 00 00 07 1F]
- //---IDE------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 09 00]
-
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 25 00]
-
- //---IDE------------------------------------------------------
- // Command: 0x1C Clear Break
- // [1C 26 00 00 00 0B 78 6A 43 70]
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
- // [80 26 00]
-
-
- //---IDE------------------------------------------------------
- // Command: 0x02 Disconnect
- // [02 27]
-// sendTrkMessage(0x02, TrkCB(handleDisconnect));
- //---TRK------------------------------------------------------
- // Command: 0x80 Acknowledge
- // Error: 0x00
-}
-
-static inline QByteArray memoryRequestTrkMessage(uint addr, uint len, int pid, int tid)
-{
- QByteArray ba;
- appendByte(&ba, 0x08); // Options, FIXME: why?
- appendShort(&ba, len);
- appendInt(&ba, addr);
- appendInt(&ba, pid);
- appendInt(&ba, tid);
- return ba;
-}
-
-void Adapter::readMemory(uint addr, uint len)
-{
- Q_ASSERT(len < (2 << 16));
-
- // We try to get medium-sized chunks of data from the device
- if (m_verbose > 2)
- logMessage(QString::fromLatin1("readMemory %1 bytes from 0x%2 blocksize=%3")
- .arg(len).arg(addr, 0, 16).arg(MemoryChunkSize));
-
- if (m_bufferedMemoryRead) {
- uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
- for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
- if (!m_snapshot.memory.contains(blockaddr)) {
- if (m_verbose)
- logMessage(QString::fromLatin1("Requesting buffered "
- "memory %1 bytes from 0x%2")
- .arg(MemoryChunkSize).arg(blockaddr, 0, 16));
- sendTrkMessage(0x10, TrkCB(handleReadMemoryBuffered),
- memoryRequestTrkMessage(blockaddr, MemoryChunkSize,
- m_session.pid, m_session.tid),
- QVariant(blockaddr), true);
- }
- }
- const qulonglong cookie = (qulonglong(addr) << 32) + len;
- sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, TrkCB(reportReadMemoryBuffered),
- QByteArray(), cookie);
- } else {
- if (m_verbose)
- logMessage(QString::fromLatin1("Requesting unbuffered memory %1 "
- "bytes from 0x%2").arg(len).arg(addr, 0, 16));
- sendTrkMessage(0x10, TrkCB(handleReadMemoryUnbuffered),
- memoryRequestTrkMessage(addr, len, m_session.pid, m_session.tid),
- QVariant(addr), true);
- }
-}
-
-void Adapter::interruptInferior()
-{
- QByteArray ba;
- // stop the thread (2) or the process (1) or the whole system (0)
- // We choose 2, as 1 does not seem to work.
- appendByte(&ba, 2);
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid); // threadID: 4 bytes Variable number of bytes.
- sendTrkMessage(0x1a, TrkCallback(), ba, "Interrupting...");
-}
-
-void Adapter::connectProcess(QProcess *proc)
-{
- connect(proc, SIGNAL(error(QProcess::ProcessError)),
- this, SLOT(handleProcError(QProcess::ProcessError)));
- connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
- this, SLOT(handleProcFinished(int, QProcess::ExitStatus)));
- connect(proc, SIGNAL(started()),
- this, SLOT(handleProcStarted()));
- connect(proc, SIGNAL(stateChanged(QProcess::ProcessState)),
- this, SLOT(handleProcStateChanged(QProcess::ProcessState)));
-}
-
-void Adapter::sendOutput(QObject *sender, const QString &data)
-{
- if (sender)
- emit output(sender->objectName() + " : ", data);
- else
- emit output(QString(), data);
-}
-
-void Adapter::handleProcError(QProcess::ProcessError error)
-{
- sendOutput(sender(), QString("Process Error %1").arg(error));
-}
-
-void Adapter::handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus)
-{
- sendOutput(sender(),
- QString("ProcessFinished %1 %2").arg(exitCode).arg(exitStatus));
-}
-
-void Adapter::handleProcStarted()
-{
- sendOutput(sender(), QString("Process Started"));
-}
-
-void Adapter::handleProcStateChanged(QProcess::ProcessState newState)
-{
- sendOutput(sender(), QString("Process State %1").arg(newState));
-}
-
-void Adapter::run()
-{
- startInferior();
- sendOutput("### Starting Adapter");
- m_rfcommProc.start("rfcomm listen /dev/rfcomm0 1");
-}
-
-void Adapter::startGdb()
-{
- if (!m_gdbServer.listen(QHostAddress(gdbServerIP()), gdbServerPort())) {
- logMessage(QString("Unable to start the gdb server at %1: %2.")
- .arg(m_gdbServerName).arg(m_gdbServer.errorString()), true);
- QCoreApplication::exit(5);
- return;
- }
-
- logMessage(QString("Gdb server running on %1.\nRegister endianness: %3.")
- .arg(m_gdbServerName).arg(m_registerEndianness), true);
-
- connect(&m_gdbServer, SIGNAL(newConnection()),
- this, SLOT(handleGdbConnection()));
-
- logMessage("STARTING GDB");
- QStringList gdbArgs;
- gdbArgs.append("--nx"); // Do not read .gdbinit file
- gdbArgs.append("-i");
- gdbArgs.append("mi");
- m_gdbProc.start(QDir::currentPath() + "/cs-gdb", gdbArgs);
- m_gdbProc.waitForStarted();
-
- sendGdbMessage("set confirm off"); // confirm potentially dangerous operations?
- sendGdbMessage("set endian little");
- sendGdbMessage("set remotebreak on");
- sendGdbMessage("set breakpoint pending on");
-
- // FIXME: "remote noack" does not seem to be supported on cs-gdb?
- //sendGdbMessage("set remote noack-packet");
-
- // FIXME: creates a lot of noise a la '&"putpkt: Junk: Ack " &'
- // even thouhg the communication seems sane
- //sendGdbMessage("set debug remote 1"); // creates l
-
- //sendGdbMessage("target remote " + m_gdbServerName);
-// sendGdbMessage("target extended-remote " + m_gdbServerName);
- //sendGdbMessage("target extended-async " + m_gdbServerName);
- //sendGdbMessage("set remotecache ...") // Set cache use for remote targets
- //sendGdbMessage("file filebrowseapp.sym");
-// sendGdbMessage("add-symbol-file filebrowseapp.sym " + m_baseAddress);
-// sendGdbMessage("symbol-file filebrowseapp.sym");
-// sendGdbMessage("print E32Main");
-// sendGdbMessage("break E32Main");
- //sendGdbMessage("continue");
- //sendGdbMessage("info files");
- //sendGdbMessage("file filebrowseapp.sym -readnow");
-
- sendGdbMessage("add-symbol-file filebrowseapp.sym 0x"
- + hexNumber(m_session.codeseg));
- sendGdbMessage("symbol-file filebrowseapp.sym");
-
- // -symbol-info-address not implemented in cs-gdb 6.4-6.8 (at least)
- sendGdbMessage("info address E32Main", GdbCB(handleInfoMainAddress));
-
-#if 1
- // FIXME: Gdb based version. That's the goal
- //sendGdbMessage("break E32Main");
- //sendGdbMessage("continue");
- QByteArray ba;
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- //sendTrkMessage(0x18, TrkCB(handleContinueAfterCreateProcess),
- // trkContinueMessage(), "CONTINUE");
-#else
- // Directly talk to TRK. Works for now...
- sendGdbMessage("break E32Main");
- sendGdbMessage("break filebrowseappui.cpp:39");
- //foreach (const Breakpoint &bp, m_breakpoints)
- // setTrkBreakpoint(bp);
- //sendTrkContinue();
- // sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE");
-#endif
-}
-
-void Adapter::sendGdbMessage(const QString &msg, GdbCallback callback,
- const QVariant &cookie)
-{
- static int token = 0;
- ++token;
- GdbCommand data;
- data.command = msg;
- data.callback = callback;
- data.cookie = cookie;
- m_gdbCookieForToken[++token] = data;
- logMessage(QString("<- GDB: %1 %2").arg(token).arg(msg));
- m_gdbProc.write(QString("%1%2\n").arg(token).arg(msg).toLatin1());
-}
-
-void Adapter::handleGdbReadyReadStandardError()
-{
- QByteArray ba = qobject_cast(sender())->readAllStandardError();
- sendOutput(sender(), QString("stderr: %1").arg(QString::fromLatin1(ba)));
-}
-
-void Adapter::handleGdbReadyReadStandardOutput()
-{
- QByteArray ba = qobject_cast(sender())->readAllStandardOutput();
- QString str = QString::fromLatin1(ba);
- // FIXME: fragile. merge with gdbengine logic
-#if 0
- QRegExp re(QString(".*([0-9]+)[^]done.*"));
- int pos = re.indexIn(str);
- if (pos == -1) {
- logMessage(QString("\n-> GDB: %1 %**% %2 %**%\n").arg(str).arg(pos));
- return;
- }
- int token = re.cap(1).toInt();
- logMessage(QString("\n-> GDB: %1 %2##\n").arg(token).arg(QString::fromLatin1(ba)));
- if (!token)
- return;
- GdbCommand cmd = m_gdbCookieForToken.take(token);
- logMessage("FOUND CALLBACK FOR " + cmd.command);
- GdbResult result;
- result.data = ba;
- if (!cmd.callback.isNull())
- cmd.callback(result);
-#else
- QRegExp re(QString("Symbol .._Z7E32Mainv.. is a function at address 0x(.*)\\."));
- if (re.indexIn(str) == -1) {
- logMessage(QString("-> GDB: %1").arg(str));
- return;
- }
- logMessage(QString("-> GDB MAIN: %1").arg(re.cap(1)));
- GdbResult result;
- result.data = re.cap(1).toLatin1();
- handleInfoMainAddress(result);
-#endif
-}
-
-void Adapter::handleInfoMainAddress(const GdbResult &result)
-{
- bool ok;
- uint addr = result.data.toInt(&ok, 16);
- const QByteArray ba = trkBreakpointMessage(addr, 1, m_session.pid);
- sendTrkMessage(0x1B, TrkCB(handleSetTrkMainBreakpoint), ba);
-}
-
-void Adapter::handleSetTrkMainBreakpoint(const TrkResult &result)
-{
- //---TRK------------------------------------------------------
- // [80 09 00 00 00 00 0A]
- const uint bpnr = extractInt(result.data.data());
- logMessage("SET MAIN BREAKPOINT 0x" + hexNumber(bpnr)
- + stringFromArray(result.data.data()));
-
- // 'continue after initial break'
- QByteArray ba;
- appendInt(&ba, m_session.pid);
- appendInt(&ba, m_session.tid);
- sendTrkMessage(0x18, TrkCallback(), ba, "CONTINUE");
-
- // this attaches
- sendGdbMessage("target remote " + m_gdbServerName);
-}
-
-void Adapter::handleInfoAddress(const GdbResult &result)
-{
- Q_UNUSED(result);
- // FIXME
-}
-
-void Adapter::handleRfcommReadyReadStandardError()
-{
- QByteArray ba = qobject_cast(sender())->readAllStandardError();
- sendOutput(sender(), QString("stderr: %1").arg(QString::fromLatin1(ba)));
-}
-
-void Adapter::handleRfcommReadyReadStandardOutput()
-{
- QByteArray ba = qobject_cast(sender())->readAllStandardOutput();
- sendOutput(sender(), QString("stdout: %1").arg(QString::fromLatin1(ba)));
-}
+#include
///////////////////////////////////////////////////////////////////////
//
@@ -1805,57 +45,171 @@ void Adapter::handleRfcommReadyReadStandardOutput()
//
///////////////////////////////////////////////////////////////////////
-class RunnerGui : public QTextEdit
+class TextEdit : public QTextEdit
+{
+ Q_OBJECT
+
+signals:
+ void executeCommand(QString);
+
+public slots:
+ void handleOutput(const QString &str0)
+ {
+ QString str = str0;
+ str.replace("\\t", QString(QChar(0x09)));
+ str.replace("\\n", QString("\n"));
+ append(str);
+
+ QTextCursor tc = textCursor();
+ tc.movePosition(QTextCursor::End);
+ setTextCursor(tc);
+ /*
+ int pos1 = str.indexOf("#");
+ int pos2 = str.indexOf(")", pos1);
+ if (pos1 != -1 && pos2 != -1)
+ str = str.left(pos1) + "" + str.mid(pos1, pos2 - pos1 + 1)
+ + " " + str.mid(pos2 + 1);
+ insertHtml(str + "\n");
+ */
+ setCurrentCharFormat(QTextCharFormat());
+ ensureCursorVisible();
+ }
+
+ void keyPressEvent(QKeyEvent *ev)
+ {
+ if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Return)
+ emit executeCommand(textCursor().block().text());
+ else
+ QTextEdit::keyPressEvent(ev);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////
+//
+// RunnerGui
+//
+///////////////////////////////////////////////////////////////////////
+
+using namespace Debugger::Internal;
+
+class RunnerGui : public QMainWindow
{
Q_OBJECT
public:
- RunnerGui(Adapter *adapter);
- void keyPressEvent(QKeyEvent *ev);
+ RunnerGui(SymbianAdapter *adapter);
private slots:
- void handleOutput(const QString &senderName, const QString &data);
+ void executeStepICommand() { executeCommand("-exec-step-instruction"); }
+ void executeStepCommand() { executeCommand("-exec-step"); }
+ void executeNextICommand() { executeCommand("-exec-next-instruction"); }
+ void executeNextCommand() { executeCommand("-exec-next"); }
+ void executeContinueCommand() { executeCommand("-exec-continue"); }
+ void executeDisassICommand() { executeCommand("disass $pc $pc+4"); }
+
+ void handleReadyReadStandardError();
+ void handleReadyReadStandardOutput();
+
+ void run();
+ void started();
private:
- Adapter *m_adapter;
+ void executeCommand(const QString &cmd) { m_adapter->executeCommand(cmd); }
+ void connectAction(QAction *&, QString name, const char *slot);
+
+ SymbianAdapter *m_adapter;
+ TextEdit m_textEdit;
+ QToolBar m_toolBar;
+ QAction *m_stepIAction;
+ QAction *m_stepAction;
+ QAction *m_nextIAction;
+ QAction *m_nextAction;
+ QAction *m_disassIAction;
+ QAction *m_continueAction;
};
-RunnerGui::RunnerGui(Adapter *adapter)
- : m_adapter(adapter)
+RunnerGui::RunnerGui(SymbianAdapter *adapter)
+ : m_adapter(adapter)
{
resize(1200, 1000);
- connect(adapter, SIGNAL(output(QString,QString)),
- this, SLOT(handleOutput(QString,QString)));
+ setCentralWidget(&m_textEdit);
+
+ addToolBar(&m_toolBar);
+
+ connectAction(m_stepIAction, "Step Inst", SLOT(executeStepICommand()));
+ connectAction(m_stepAction, "Step", SLOT(executeStepCommand()));
+ connectAction(m_nextIAction, "Next Inst", SLOT(executeNextICommand()));
+ connectAction(m_nextAction, "Next", SLOT(executeNextCommand()));
+ connectAction(m_disassIAction, "Disass Inst", SLOT(executeDisassICommand()));
+ connectAction(m_continueAction, "Continue", SLOT(executeContinueCommand()));
+
+ connect(adapter, SIGNAL(output(QString)),
+ &m_textEdit, SLOT(handleOutput(QString)));
+ connect(&m_textEdit, SIGNAL(executeCommand(QString)),
+ m_adapter, SLOT(executeCommand(QString)));
+
+ connect(adapter, SIGNAL(readyReadStandardError()),
+ this, SLOT(handleReadyReadStandardError()));
+ connect(adapter, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(handleReadyReadStandardOutput()));
+ connect(adapter, SIGNAL(started()),
+ this, SLOT(started()));
}
-void RunnerGui::handleOutput(const QString &senderName, const QString &data)
+void RunnerGui::connectAction(QAction *&action, QString name, const char *slot)
{
- append(senderName + data);
- QTextCursor tc = textCursor();
- tc.movePosition(QTextCursor::End);
- setTextCursor(tc);
-/*
- QString str = data;
- int pos1 = str.indexOf("#");
- int pos2 = str.indexOf(")", pos1);
- if (pos1 != -1 && pos2 != -1)
- str = str.left(pos1) + "" + str.mid(pos1, pos2 - pos1 + 1)
- + " " + str.mid(pos2 + 1);
- str.replace("\\t", QString(QChar(0x09)));
- str.replace("\\n", QString("\n"));
- insertHtml(str + "\n");
-*/
- setCurrentCharFormat(QTextCharFormat());
- ensureCursorVisible();
-
+ action = new QAction(this);
+ action->setText(name);
+ m_toolBar.addAction(action);
+ connect(action, SIGNAL(triggered()), this, slot);
}
-void RunnerGui::keyPressEvent(QKeyEvent *ev)
+void RunnerGui::handleReadyReadStandardError()
{
- if (ev->modifiers() == Qt::ControlModifier && ev->key() == Qt::Key_Return)
- m_adapter->executeCommand(textCursor().block().text());
- else
- QTextEdit::keyPressEvent(ev);
+ QByteArray ba = m_adapter->readAllStandardError();
+ qDebug() << ba;
+ m_textEdit.handleOutput(ba);
+}
+
+void RunnerGui::handleReadyReadStandardOutput()
+{
+ QByteArray ba = m_adapter->readAllStandardOutput();
+ qDebug() << ba;
+ m_textEdit.handleOutput("-> GDB: " + ba);
+}
+
+void RunnerGui::run()
+{
+ m_adapter->run();
+}
+
+void RunnerGui::started()
+{
+ qDebug() << "\nSTARTED\n";
+ executeCommand("set confirm off"); // confirm potentially dangerous operations?
+ executeCommand("set endian little");
+ executeCommand("set remotebreak on");
+ executeCommand("set breakpoint pending on");
+ executeCommand("set trust-readonly-sections on");
+ //executeCommand("mem 0 ~0ll rw 8 cache");
+
+ // FIXME: "remote noack" does not seem to be supported on cs-gdb?
+ //executeCommand("set remote noack-packet");
+
+ // FIXME: creates a lot of noise a la '&"putpkt: Junk: Ack " &'
+ // even though the communication seems sane
+ //executeCommand("set debug remote 1"); // creates l
+
+ executeCommand("add-symbol-file filebrowseapp.sym "
+ + trk::hexxNumber(m_adapter->session().codeseg));
+ executeCommand("symbol-file filebrowseapp.sym");
+
+ //executeCommand("info address CFileBrowseAppUi::HandleCommandL",
+ // GdbCB(handleInfoMainAddress));
+
+ executeCommand("-break-insert filebrowseappui.cpp:39");
+ executeCommand("target remote " + m_adapter->gdbServerName());
+ executeCommand("-exec-continue");
}
///////////////////////////////////////////////////////////////////////
@@ -1867,10 +221,11 @@ void RunnerGui::keyPressEvent(QKeyEvent *ev)
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- Adapter adapter;
+ SymbianAdapter adapter;
+ adapter.setVerbose(2);
RunnerGui gui(&adapter);
gui.show();
- QTimer::singleShot(0, &adapter, SLOT(run()));
+ QTimer::singleShot(0, &gui, SLOT(run()));
return app.exec();
}
diff --git a/tests/manual/trk/runner.pro b/tests/manual/trk/runner.pro
index 4ced7ccd71a..20240eb1f73 100644
--- a/tests/manual/trk/runner.pro
+++ b/tests/manual/trk/runner.pro
@@ -1,15 +1,23 @@
TEMPLATE = app
+DEBUGGERHOME = ../../../src/plugins/debugger/symbian
+INCLUDEPATH *= $$DEBUGGERHOME
+
+DEFINES += STANDALONE_RUNNER
+
QT += network
win32:CONFIG+=console
HEADERS += \
- trkutils.h \
- trkdevicex.h \
+ $$DEBUGGERHOME/../gdb/gdbprocessbase.h \
+ $$DEBUGGERHOME/trkutils.h \
+ $$DEBUGGERHOME/trkclient.h \
+ $$DEBUGGERHOME/symbianadapter.h \
SOURCES += \
- runner.cpp \
- trkutils.cpp \
- trkdevicex.cpp \
+ $$DEBUGGERHOME/trkutils.cpp \
+ $$DEBUGGERHOME/trkclient.cpp \
+ $$DEBUGGERHOME/symbianadapter.cpp \
+ $$PWD/runner.cpp \
diff --git a/tests/manual/trk/trklauncher.pri b/tests/manual/trk/trklauncher.pri
index 3593888b861..69ed7630410 100644
--- a/tests/manual/trk/trklauncher.pri
+++ b/tests/manual/trk/trklauncher.pri
@@ -1,9 +1,15 @@
DEFINES += DEBUG_TRK=0
-INCLUDEPATH *= $$PWD
-SOURCES += $$PWD/launcher.cpp \
- $$PWD/trkutils.cpp \
- $$PWD/trkdevice.cpp
-HEADERS += $$PWD/trkutils.h \
- $$PWD/trkfunctor.h \
+DEBUGGERHOME = ../../../src/plugins/debugger/symbian
+
+INCLUDEPATH *= $$PWD $$DEBUGGERHOME
+
+SOURCES += \
+ $$DEBUGGERHOME/trkutils.cpp \
+ $$PWD/trkdevice.cpp \
+ $$PWD/launcher.cpp \
+
+HEADERS += \
+ $$DEBUGGERHOME/trkutils.h \
+ $$DEBUGGERHOME/trkfunctor.h \
$$PWD/trkdevice.h \
$$PWD/launcher.h
diff --git a/tests/manual/trk/trkserver.pro b/tests/manual/trk/trkserver.pro
index a333dc2c363..6fbbc85c06c 100644
--- a/tests/manual/trk/trkserver.pro
+++ b/tests/manual/trk/trkserver.pro
@@ -1,12 +1,17 @@
TEMPLATE = app
+DEBUGGERHOME = ../../../src/plugins/debugger/symbian
+
QT = core network
win32:CONFIG+=console
+INCLUDEPATH *= $$DEBUGGERHOME
+
+
HEADERS += \
- trkutils.h
+ $$DEBUGGERHOME/trkutils.h
SOURCES += \
- trkutils.cpp \
- trkserver.cpp
+ $$DEBUGGERHOME/trkutils.cpp \
+ $$PWD/trkserver.cpp