From e8d2aee2ddabd2fac06620956c0a3a932f6f8bca Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Mon, 22 Sep 2025 16:55:18 -0500 Subject: [PATCH 1/3] First pass at adding print support for Objective-C objects. --- src/SeerGdbWidget.cpp | 16 +++++++- src/SeerVariableTrackerBrowserWidget.cpp | 3 ++ src/resource.qrc | 1 + src/resources/mi-python/MIObjectiveC.py | 37 +++++++++++++++++++ tests/helloobjectivec/.gitignore | 1 + tests/helloobjectivec/Makefile | 9 +++-- tests/helloobjectivec/README | 8 ++++ tests/helloobjectivec/hellodays.m | 20 ++++++++++ tests/helloobjectivec/hellodays.seer | 24 ++++++++++++ .../hellodays_breakpoints.seer | 1 + tests/helloobjectivec/hellotictactoe.m | 2 +- 11 files changed, 116 insertions(+), 6 deletions(-) create mode 100644 src/resources/mi-python/MIObjectiveC.py create mode 100644 tests/helloobjectivec/README create mode 100644 tests/helloobjectivec/hellodays.m create mode 100644 tests/helloobjectivec/hellodays.seer create mode 100644 tests/helloobjectivec/hellodays_breakpoints.seer diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp index 417cade..51a28d4 100644 --- a/src/SeerGdbWidget.cpp +++ b/src/SeerGdbWidget.cpp @@ -2640,7 +2640,14 @@ void SeerGdbWidget::handleGdbDataEvaluateExpression (int expressionid, QString e return; } - handleGdbCommand(QString::number(expressionid) + "-data-evaluate-expression \"" + expression + "\""); + // Check if there's a ObjectiveC pretext. + if (expression.startsWith("oc#")) { + handleGdbCommand(QString::number(expressionid) + "-objc-evaluate-expression \"" + expression.mid(3) + "\""); + + // Otherwise handle normally. + }else{ + handleGdbCommand(QString::number(expressionid) + "-data-evaluate-expression \"" + expression + "\""); + } } void SeerGdbWidget::handleGdbVarObjCreate (int expressionid, QString expression) { @@ -2716,7 +2723,7 @@ void SeerGdbWidget::handleGdbDataListValues () { } for (int i=0; i<_dataExpressionId.size(); i++) { - handleGdbCommand(QString::number(_dataExpressionId[i]) + "-data-evaluate-expression \"" + _dataExpressionName[i] + "\""); + handleGdbDataEvaluateExpression(_dataExpressionId[i], _dataExpressionName[i]); } } @@ -2777,6 +2784,11 @@ void SeerGdbWidget::handleGdbDataAddExpression (QString expression) { void SeerGdbWidget::handleGdbDataDeleteExpressions (QString expressionids) { if (executableLaunchMode() == "") { + + // Clear expression list. + _dataExpressionId.clear(); + _dataExpressionName.clear(); + return; } diff --git a/src/SeerVariableTrackerBrowserWidget.cpp b/src/SeerVariableTrackerBrowserWidget.cpp index 80e5530..5cf087e 100644 --- a/src/SeerVariableTrackerBrowserWidget.cpp +++ b/src/SeerVariableTrackerBrowserWidget.cpp @@ -224,6 +224,9 @@ void SeerVariableTrackerBrowserWidget::handleSessionTerminated () { // Delete previous contents. variablesTreeWidget->clear(); + + // Tell the GdbWidget to forget all tracked expressions. + emit deleteVariableExpressions("*"); } void SeerVariableTrackerBrowserWidget::refresh () { diff --git a/src/resource.qrc b/src/resource.qrc index 88b0762..87b7368 100644 --- a/src/resource.qrc +++ b/src/resource.qrc @@ -86,6 +86,7 @@ resources/mi-python/MIKill.py resources/mi-python/MICheckpoint.py resources/mi-python/MICatchpoint.py + resources/mi-python/MIObjectiveC.py diff --git a/src/resources/mi-python/MIObjectiveC.py b/src/resources/mi-python/MIObjectiveC.py new file mode 100644 index 0000000..ff2be9d --- /dev/null +++ b/src/resources/mi-python/MIObjectiveC.py @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2025 Ernie Pasveer +# +# SPDX-License-Identifier: MIT + +import re + +# +# Python MI command to manage gdb's Objective-C commands. +# +# https://sourceware.org/gdb/current/onlinedocs/gdb.html/Objective_002dC.html#Objective_002dC +# + +class MIObjectiveC(gdb.MICommand): + """ + Run the ObjectiveC command. + + -objc-evaluate-expression Evaluate an Objective-C object via 'print-object' and '_NSPrintForDebugger'. + + See: https://sourceware.org/gdb/current/onlinedocs/gdb.html/Objective_002dC.html#Objective_002dC + """ + + def __init__(self, name, mode): + self._mode = mode + super(MIObjectiveC, self).__init__(name) + + def invoke(self, argv): + if self._mode == "evaluate-expression": + + result = gdb.execute ("print-object " + " ".join(argv), to_string=True) + + return { "value": result.rstrip('\n')} + + else: + raise gdb.GdbError("objectivec: Invalid parameter: %s" % self._mode) + +MIObjectiveC("-objc-evaluate-expression", "evaluate-expression") + diff --git a/tests/helloobjectivec/.gitignore b/tests/helloobjectivec/.gitignore index 8761415..c0ba299 100644 --- a/tests/helloobjectivec/.gitignore +++ b/tests/helloobjectivec/.gitignore @@ -1,2 +1,3 @@ hellotictactoe +hellodays *.d diff --git a/tests/helloobjectivec/Makefile b/tests/helloobjectivec/Makefile index 4b73f13..715860d 100644 --- a/tests/helloobjectivec/Makefile +++ b/tests/helloobjectivec/Makefile @@ -1,10 +1,13 @@ .PHONY: all -all: hellotictactoe +all: hellotictactoe hellodays hellotictactoe: hellotictactoe.m - clang hellotictactoe.m -g `gnustep-config --objc-flags` -std=c99 -lobjc -lgnustep-base -o hellotictactoe + clang hellotictactoe.m `gnustep-config --objc-flags` -O0 -std=c99 -lobjc -lgnustep-base -o hellotictactoe + +hellodays: hellodays.m + clang hellodays.m `gnustep-config --objc-flags` -O0 -std=c99 -lobjc -lgnustep-base -o hellodays .PHONY: clean clean: - rm -f hellotictactoe *.d + rm -f hellotictactoe hellodays *.d diff --git a/tests/helloobjectivec/README b/tests/helloobjectivec/README new file mode 100644 index 0000000..948dc43 --- /dev/null +++ b/tests/helloobjectivec/README @@ -0,0 +1,8 @@ + +Setup the GNUStep environment. + + $ source /usr/share/GNUstep/Makefiles/GNUstep.sh + + $ export CC=/usr/bin/clang + $ export CXX=/usr/bin/clang++ + diff --git a/tests/helloobjectivec/hellodays.m b/tests/helloobjectivec/hellodays.m new file mode 100644 index 0000000..6ac2b77 --- /dev/null +++ b/tests/helloobjectivec/hellodays.m @@ -0,0 +1,20 @@ +#import + +int main(void) { + + @autoreleasepool { + + NSString* name = @"test string!!!"; + float myval = 3.75; + NSArray* weekArray; + + weekArray = [NSArray arrayWithObjects: @"Sun", @"Mon" @"Tue", @"Wed", @"Thr", @"Fri", @"Sat", nil]; + + NSLog(@"name = %@", name); + NSLog(@"myval = %f", myval); + NSLog(@"weekArray = %@", weekArray); + } + + return 0; +} + diff --git a/tests/helloobjectivec/hellodays.seer b/tests/helloobjectivec/hellodays.seer new file mode 100644 index 0000000..82cd4d6 --- /dev/null +++ b/tests/helloobjectivec/hellodays.seer @@ -0,0 +1,24 @@ +{ + "seerproject": { + "executable": "/nas/erniep/Development/seer/tests/helloobjectivec/hellodays", + "postgdbcommands": [ + "" + ], + "pregdbcommands": [ + "" + ], + "startmode": { + "arguments": "", + "breakinfunction": false, + "breakinfunctionname": "", + "breakinmain": true, + "breakpointsfile": "/nas/erniep/Development/seer/tests/helloobjectivec/hellodays_breakpoints.seer", + "nobreak": false, + "nonstopmode": false, + "randomizestartaddress": false, + "showassemblytab": false + }, + "symbolfile": "", + "workingdirectory": "" + } +} diff --git a/tests/helloobjectivec/hellodays_breakpoints.seer b/tests/helloobjectivec/hellodays_breakpoints.seer new file mode 100644 index 0000000..2806259 --- /dev/null +++ b/tests/helloobjectivec/hellodays_breakpoints.seer @@ -0,0 +1 @@ +break -source /nas/erniep/Development/seer/tests/helloobjectivec/hellodays.m -line 15 diff --git a/tests/helloobjectivec/hellotictactoe.m b/tests/helloobjectivec/hellotictactoe.m index 8145f92..4437949 100644 --- a/tests/helloobjectivec/hellotictactoe.m +++ b/tests/helloobjectivec/hellotictactoe.m @@ -130,7 +130,7 @@ - (int)getPlayerInput { int input; printf("Player %c, enter your move (1-9): ", currentPlayer); - scanf("%d", &input); + (void)scanf("%d", &input); // Clear input buffer int c; From f6f49bc167733c4705e8bd612d49d29f36be1296 Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 27 Sep 2025 10:47:39 -0500 Subject: [PATCH 2/3] Change ObjectiveC pretext from 'oc#' to '(objc)' Makes it look like a cast. --- src/SeerEditorWidgetSourceAreas.cpp | 31 +++++++++++++++++++++++++ src/SeerGdbWidget.cpp | 6 +++-- src/SeerStackArgumentsBrowserWidget.cpp | 29 +++++++++++++++++++++++ src/SeerStackLocalsBrowserWidget.cpp | 29 +++++++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/SeerEditorWidgetSourceAreas.cpp b/src/SeerEditorWidgetSourceAreas.cpp index 29d1fe0..e7deed3 100644 --- a/src/SeerEditorWidgetSourceAreas.cpp +++ b/src/SeerEditorWidgetSourceAreas.cpp @@ -928,10 +928,12 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin QAction* addVariableLoggerAsteriskExpressionAction; QAction* addVariableLoggerAmpersandExpressionAction; QAction* addVariableLoggerAsteriskAmpersandExpressionAction; + QAction* addVariableLoggerObjcExpressionAction; QAction* addVariableTrackerExpressionAction; QAction* addVariableTrackerAsteriskExpressionAction; QAction* addVariableTrackerAmpersandExpressionAction; QAction* addVariableTrackerAsteriskAmpersandExpressionAction; + QAction* addVariableTrackerObjcExpressionAction; QAction* addMemoryVisualizerAction; QAction* addMemoryAsteriskVisualizerAction; QAction* addMemoryAmpersandVisualizerAction; @@ -988,10 +990,12 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin addVariableLoggerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); addVariableLoggerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(textCursor().selectedText())); + addVariableLoggerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(textCursor().selectedText())); addVariableTrackerExpressionAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); addVariableTrackerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); addVariableTrackerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(textCursor().selectedText())); + addVariableTrackerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(textCursor().selectedText())); addMemoryVisualizerAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); addMemoryAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); addMemoryAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); @@ -1020,6 +1024,7 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin loggerMenu.addAction(addVariableLoggerAsteriskExpressionAction); loggerMenu.addAction(addVariableLoggerAmpersandExpressionAction); loggerMenu.addAction(addVariableLoggerAsteriskAmpersandExpressionAction); + loggerMenu.addAction(addVariableLoggerObjcExpressionAction); menu.addMenu(&loggerMenu); QMenu trackerMenu("Add variable to Tracker"); @@ -1027,6 +1032,7 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin trackerMenu.addAction(addVariableTrackerAsteriskExpressionAction); trackerMenu.addAction(addVariableTrackerAmpersandExpressionAction); trackerMenu.addAction(addVariableTrackerAsteriskAmpersandExpressionAction); + trackerMenu.addAction(addVariableTrackerObjcExpressionAction); menu.addMenu(&trackerMenu); QMenu memoryVisualizerMenu("Add variable to a Memory Visualizer"); @@ -1059,6 +1065,7 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin addVariableLoggerAsteriskExpressionAction->setEnabled(false); addVariableLoggerAmpersandExpressionAction->setEnabled(false); addVariableLoggerAsteriskAmpersandExpressionAction->setEnabled(false); + addVariableLoggerObjcExpressionAction->setEnabled(false); addVariableTrackerExpressionAction->setEnabled(false); addVariableTrackerAsteriskExpressionAction->setEnabled(false); addVariableTrackerAmpersandExpressionAction->setEnabled(false); @@ -1080,6 +1087,7 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin addVariableLoggerAsteriskExpressionAction->setEnabled(true); addVariableLoggerAmpersandExpressionAction->setEnabled(true); addVariableLoggerAsteriskAmpersandExpressionAction->setEnabled(true); + addVariableLoggerObjcExpressionAction->setEnabled(true); addVariableTrackerExpressionAction->setEnabled(true); addVariableTrackerAsteriskExpressionAction->setEnabled(true); addVariableTrackerAmpersandExpressionAction->setEnabled(true); @@ -1274,6 +1282,17 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin return; } + // Handle adding a variable to log. + if (action == addVariableLoggerObjcExpressionAction) { + + // Emit the signals. + if (textCursor().selectedText() != "") { + emit addVariableLoggerExpression(QString("(objc)") + textCursor().selectedText()); + } + + return; + } + // Handle adding a variable to track. if (action == addVariableTrackerExpressionAction) { @@ -1322,6 +1341,18 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin return; } + // Handle adding a variable to track. + if (action == addVariableTrackerObjcExpressionAction) { + + // Emit the signals. + if (textCursor().selectedText() != "") { + emit addVariableTrackerExpression(QString("(objc)") + textCursor().selectedText()); + emit refreshVariableTrackerValues(); + } + + return; + } + // Handle adding memory to visualize. if (action == addMemoryVisualizerAction) { diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp index 51a28d4..bb17ff3 100644 --- a/src/SeerGdbWidget.cpp +++ b/src/SeerGdbWidget.cpp @@ -2641,8 +2641,10 @@ void SeerGdbWidget::handleGdbDataEvaluateExpression (int expressionid, QString e } // Check if there's a ObjectiveC pretext. - if (expression.startsWith("oc#")) { - handleGdbCommand(QString::number(expressionid) + "-objc-evaluate-expression \"" + expression.mid(3) + "\""); + QString token("(objc)"); + + if (expression.startsWith(token)) { + handleGdbCommand(QString::number(expressionid) + "-objc-evaluate-expression \"" + expression.mid(token.length()) + "\""); // Otherwise handle normally. }else{ diff --git a/src/SeerStackArgumentsBrowserWidget.cpp b/src/SeerStackArgumentsBrowserWidget.cpp index 7666d66..4a7255c 100644 --- a/src/SeerStackArgumentsBrowserWidget.cpp +++ b/src/SeerStackArgumentsBrowserWidget.cpp @@ -187,10 +187,12 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { QAction* addVariableLoggerAsteriskExpressionAction; QAction* addVariableLoggerAmpersandExpressionAction; QAction* addVariableLoggerAsteriskAmpersandExpressionAction; + QAction* addVariableLoggerObjcExpressionAction; QAction* addVariableTrackerExpressionAction; QAction* addVariableTrackerAsteriskExpressionAction; QAction* addVariableTrackerAmpersandExpressionAction; QAction* addVariableTrackerAsteriskAmpersandExpressionAction; + QAction* addVariableTrackerObjcExpressionAction; QAction* addMemoryVisualizerAction; QAction* addMemoryAsteriskVisualizerAction; QAction* addMemoryAmpersandVisualizerAction; @@ -208,10 +210,12 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { addVariableLoggerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(1))); addVariableLoggerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(1))); + addVariableLoggerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); addVariableTrackerExpressionAction = new QAction(QString("\"%1\"").arg(item->text(1))); addVariableTrackerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(1))); addVariableTrackerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(1))); + addVariableTrackerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); addMemoryVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(1))); addMemoryAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(1))); addMemoryAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); @@ -233,6 +237,7 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { loggerMenu.addAction(addVariableLoggerAsteriskExpressionAction); loggerMenu.addAction(addVariableLoggerAmpersandExpressionAction); loggerMenu.addAction(addVariableLoggerAsteriskAmpersandExpressionAction); + loggerMenu.addAction(addVariableLoggerObjcExpressionAction); menu.addMenu(&loggerMenu); QMenu trackerMenu("Add variable to Tracker"); @@ -240,6 +245,7 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { trackerMenu.addAction(addVariableTrackerAsteriskExpressionAction); trackerMenu.addAction(addVariableTrackerAmpersandExpressionAction); trackerMenu.addAction(addVariableTrackerAsteriskAmpersandExpressionAction); + trackerMenu.addAction(addVariableTrackerObjcExpressionAction); menu.addMenu(&trackerMenu); QMenu memoryVisualizerMenu("Add variable to a Memory Visualizer"); @@ -318,6 +324,17 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { return; } + // Handle adding a variable to log. + if (action == addVariableLoggerObjcExpressionAction) { + + // Emit the signals. + if (item->text(1) != "") { + emit addVariableLoggerExpression(QString("(objc)") + item->text(1)); + } + + return; + } + // Handle adding a variable to track. if (action == addVariableTrackerExpressionAction) { @@ -366,6 +383,18 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { return; } + // Handle adding a variable to track. + if (action == addVariableTrackerObjcExpressionAction) { + + // Emit the signals. + if (item->text(1) != "") { + emit addVariableTrackerExpression(QString("(objc)") + item->text(1)); + emit refreshVariableTrackerValues(); + } + + return; + } + // Handle adding memory to visualize. if (action == addMemoryVisualizerAction) { diff --git a/src/SeerStackLocalsBrowserWidget.cpp b/src/SeerStackLocalsBrowserWidget.cpp index c4afb63..2ad5548 100644 --- a/src/SeerStackLocalsBrowserWidget.cpp +++ b/src/SeerStackLocalsBrowserWidget.cpp @@ -155,10 +155,12 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { QAction* addVariableLoggerAsteriskExpressionAction; QAction* addVariableLoggerAmpersandExpressionAction; QAction* addVariableLoggerAsteriskAmpersandExpressionAction; + QAction* addVariableLoggerObjcExpressionAction; QAction* addVariableTrackerExpressionAction; QAction* addVariableTrackerAsteriskExpressionAction; QAction* addVariableTrackerAmpersandExpressionAction; QAction* addVariableTrackerAsteriskAmpersandExpressionAction; + QAction* addVariableTrackerObjcExpressionAction; QAction* addMemoryVisualizerAction; QAction* addMemoryAsteriskVisualizerAction; QAction* addMemoryAmpersandVisualizerAction; @@ -176,10 +178,12 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { addVariableLoggerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(0))); addVariableLoggerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(0))); + addVariableLoggerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); addVariableTrackerExpressionAction = new QAction(QString("\"%1\"").arg(item->text(0))); addVariableTrackerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(0))); addVariableTrackerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(0))); + addVariableTrackerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); addMemoryVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(0))); addMemoryAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(0))); addMemoryAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); @@ -201,6 +205,7 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { loggerMenu.addAction(addVariableLoggerAsteriskExpressionAction); loggerMenu.addAction(addVariableLoggerAmpersandExpressionAction); loggerMenu.addAction(addVariableLoggerAsteriskAmpersandExpressionAction); + loggerMenu.addAction(addVariableLoggerObjcExpressionAction); menu.addMenu(&loggerMenu); QMenu trackerMenu("Add variable to Tracker"); @@ -208,6 +213,7 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { trackerMenu.addAction(addVariableTrackerAsteriskExpressionAction); trackerMenu.addAction(addVariableTrackerAmpersandExpressionAction); trackerMenu.addAction(addVariableTrackerAsteriskAmpersandExpressionAction); + trackerMenu.addAction(addVariableTrackerObjcExpressionAction); menu.addMenu(&trackerMenu); QMenu memoryVisualizerMenu("Add variable to a Memory Visualizer"); @@ -294,6 +300,17 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { return; } + // Handle adding a variable to log. + if (action == addVariableLoggerObjcExpressionAction) { + + // Emit the signals. + if (variable != "") { + emit addVariableLoggerExpression(QString("(objc)") + variable); + } + + return; + } + // Handle adding a variable to track. if (action == addVariableTrackerExpressionAction) { @@ -342,6 +359,18 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { return; } + // Handle adding a variable to track. + if (action == addVariableTrackerObjcExpressionAction) { + + // Emit the signals. + if (variable != "") { + emit addVariableTrackerExpression(QString("(objc)") + variable); + emit refreshVariableTrackerValues(); + } + + return; + } + // Handle adding memory to visualize. if (action == addMemoryVisualizerAction) { From 30a8e8a7a6d7d51ef2e340a1ee0a335fbcfdba1e Mon Sep 17 00:00:00 2001 From: Ernie Pasveer Date: Sat, 27 Sep 2025 11:11:36 -0500 Subject: [PATCH 3/3] Remove surrounding quotes for RMB contexts. Update CHANGELOG. --- CHANGELOG.md | 1 + src/SeerEditorWidgetSourceAreas.cpp | 44 ++++++++++++------------- src/SeerStackArgumentsBrowserWidget.cpp | 44 ++++++++++++------------- src/SeerStackLocalsBrowserWidget.cpp | 44 ++++++++++++------------- 4 files changed, 67 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d50dc5b..efde751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ the next time the Debug dialog is used. Kind of a default project. * RR: When using the Debug dialog, check a couple standard locations for the RR trace directory. +* ObjectiveC: Add support for printing ObjectiveC object via a '(objc)' pretext. ## [2.5] - 2024-12-24 * Console now supports a subset of ANSI color codes. diff --git a/src/SeerEditorWidgetSourceAreas.cpp b/src/SeerEditorWidgetSourceAreas.cpp index e7deed3..53b94d6 100644 --- a/src/SeerEditorWidgetSourceAreas.cpp +++ b/src/SeerEditorWidgetSourceAreas.cpp @@ -986,28 +986,28 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin openExternalEditor->setEnabled(true); } - addVariableLoggerExpressionAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); - addVariableLoggerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); - addVariableLoggerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); - addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(textCursor().selectedText())); - addVariableLoggerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(textCursor().selectedText())); - addVariableTrackerExpressionAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); - addVariableTrackerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); - addVariableTrackerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); - addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(textCursor().selectedText())); - addVariableTrackerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(textCursor().selectedText())); - addMemoryVisualizerAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); - addMemoryAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); - addMemoryAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); - addArrayVisualizerAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); - addArrayAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); - addArrayAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); - addMatrixVisualizerAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); - addMatrixAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); - addMatrixAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); - addStructVisualizerAction = new QAction(QString("\"%1\"").arg(textCursor().selectedText())); - addStructAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(textCursor().selectedText())); - addStructAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(textCursor().selectedText())); + addVariableLoggerExpressionAction = new QAction(QString("%1").arg(textCursor().selectedText())); + addVariableLoggerAsteriskExpressionAction = new QAction(QString("*%1").arg(textCursor().selectedText())); + addVariableLoggerAmpersandExpressionAction = new QAction(QString("&&%1").arg(textCursor().selectedText())); + addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("*&&%1").arg(textCursor().selectedText())); + addVariableLoggerObjcExpressionAction = new QAction(QString("(objc)%1").arg(textCursor().selectedText())); + addVariableTrackerExpressionAction = new QAction(QString("%1").arg(textCursor().selectedText())); + addVariableTrackerAsteriskExpressionAction = new QAction(QString("*%1").arg(textCursor().selectedText())); + addVariableTrackerAmpersandExpressionAction = new QAction(QString("&&%1").arg(textCursor().selectedText())); + addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("*&&%1").arg(textCursor().selectedText())); + addVariableTrackerObjcExpressionAction = new QAction(QString("(objc)%1").arg(textCursor().selectedText())); + addMemoryVisualizerAction = new QAction(QString("%1").arg(textCursor().selectedText())); + addMemoryAsteriskVisualizerAction = new QAction(QString("*%1").arg(textCursor().selectedText())); + addMemoryAmpersandVisualizerAction = new QAction(QString("&&%1").arg(textCursor().selectedText())); + addArrayVisualizerAction = new QAction(QString("%1").arg(textCursor().selectedText())); + addArrayAsteriskVisualizerAction = new QAction(QString("*%1").arg(textCursor().selectedText())); + addArrayAmpersandVisualizerAction = new QAction(QString("&&%1").arg(textCursor().selectedText())); + addMatrixVisualizerAction = new QAction(QString("%1").arg(textCursor().selectedText())); + addMatrixAsteriskVisualizerAction = new QAction(QString("*%1").arg(textCursor().selectedText())); + addMatrixAmpersandVisualizerAction = new QAction(QString("&&%1").arg(textCursor().selectedText())); + addStructVisualizerAction = new QAction(QString("%1").arg(textCursor().selectedText())); + addStructAsteriskVisualizerAction = new QAction(QString("*%1").arg(textCursor().selectedText())); + addStructAmpersandVisualizerAction = new QAction(QString("&&%1").arg(textCursor().selectedText())); QMenu menu("Breakpoints", this); menu.setTitle("Breakpoints"); diff --git a/src/SeerStackArgumentsBrowserWidget.cpp b/src/SeerStackArgumentsBrowserWidget.cpp index 4a7255c..f04bee6 100644 --- a/src/SeerStackArgumentsBrowserWidget.cpp +++ b/src/SeerStackArgumentsBrowserWidget.cpp @@ -206,28 +206,28 @@ void SeerStackArgumentsBrowserWidget::handleContextMenu (const QPoint& pos) { QAction* addStructAsteriskVisualizerAction; QAction* addStructAmpersandVisualizerAction; - addVariableLoggerExpressionAction = new QAction(QString("\"%1\"").arg(item->text(1))); - addVariableLoggerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(1))); - addVariableLoggerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); - addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(1))); - addVariableLoggerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); - addVariableTrackerExpressionAction = new QAction(QString("\"%1\"").arg(item->text(1))); - addVariableTrackerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(1))); - addVariableTrackerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); - addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(1))); - addVariableTrackerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); - addMemoryVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(1))); - addMemoryAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(1))); - addMemoryAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); - addArrayVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(1))); - addArrayAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(1))); - addArrayAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); - addMatrixVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(1))); - addMatrixAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(1))); - addMatrixAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); - addStructVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(1))); - addStructAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(1))); - addStructAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(1))); + addVariableLoggerExpressionAction = new QAction(QString("%1").arg(item->text(1))); + addVariableLoggerAsteriskExpressionAction = new QAction(QString("*%1").arg(item->text(1))); + addVariableLoggerAmpersandExpressionAction = new QAction(QString("&&%1").arg(item->text(1))); + addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("*&&%1").arg(item->text(1))); + addVariableLoggerObjcExpressionAction = new QAction(QString("(objc)%1").arg(item->text(0))); + addVariableTrackerExpressionAction = new QAction(QString("%1").arg(item->text(1))); + addVariableTrackerAsteriskExpressionAction = new QAction(QString("*%1").arg(item->text(1))); + addVariableTrackerAmpersandExpressionAction = new QAction(QString("&&%1").arg(item->text(1))); + addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("*&&%1").arg(item->text(1))); + addVariableTrackerObjcExpressionAction = new QAction(QString("(objc)%1").arg(item->text(0))); + addMemoryVisualizerAction = new QAction(QString("%1").arg(item->text(1))); + addMemoryAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(1))); + addMemoryAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(1))); + addArrayVisualizerAction = new QAction(QString("%1").arg(item->text(1))); + addArrayAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(1))); + addArrayAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(1))); + addMatrixVisualizerAction = new QAction(QString("%1").arg(item->text(1))); + addMatrixAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(1))); + addMatrixAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(1))); + addStructVisualizerAction = new QAction(QString("%1").arg(item->text(1))); + addStructAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(1))); + addStructAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(1))); QMenu menu("Visualizers", this); menu.setTitle("Visualizers"); diff --git a/src/SeerStackLocalsBrowserWidget.cpp b/src/SeerStackLocalsBrowserWidget.cpp index 2ad5548..9573b67 100644 --- a/src/SeerStackLocalsBrowserWidget.cpp +++ b/src/SeerStackLocalsBrowserWidget.cpp @@ -174,28 +174,28 @@ void SeerStackLocalsBrowserWidget::handleContextMenu (const QPoint& pos) { QAction* addStructAsteriskVisualizerAction; QAction* addStructAmpersandVisualizerAction; - addVariableLoggerExpressionAction = new QAction(QString("\"%1\"").arg(item->text(0))); - addVariableLoggerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(0))); - addVariableLoggerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); - addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(0))); - addVariableLoggerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); - addVariableTrackerExpressionAction = new QAction(QString("\"%1\"").arg(item->text(0))); - addVariableTrackerAsteriskExpressionAction = new QAction(QString("\"*%1\"").arg(item->text(0))); - addVariableTrackerAmpersandExpressionAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); - addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("\"*&&%1\"").arg(item->text(0))); - addVariableTrackerObjcExpressionAction = new QAction(QString("\"(objc)%1\"").arg(item->text(0))); - addMemoryVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(0))); - addMemoryAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(0))); - addMemoryAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); - addArrayVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(0))); - addArrayAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(0))); - addArrayAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); - addMatrixVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(0))); - addMatrixAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(0))); - addMatrixAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); - addStructVisualizerAction = new QAction(QString("\"%1\"").arg(item->text(0))); - addStructAsteriskVisualizerAction = new QAction(QString("\"*%1\"").arg(item->text(0))); - addStructAmpersandVisualizerAction = new QAction(QString("\"&&%1\"").arg(item->text(0))); + addVariableLoggerExpressionAction = new QAction(QString("%1").arg(item->text(0))); + addVariableLoggerAsteriskExpressionAction = new QAction(QString("*%1").arg(item->text(0))); + addVariableLoggerAmpersandExpressionAction = new QAction(QString("&&%1").arg(item->text(0))); + addVariableLoggerAsteriskAmpersandExpressionAction = new QAction(QString("*&&%1").arg(item->text(0))); + addVariableLoggerObjcExpressionAction = new QAction(QString("(objc)%1").arg(item->text(0))); + addVariableTrackerExpressionAction = new QAction(QString("%1").arg(item->text(0))); + addVariableTrackerAsteriskExpressionAction = new QAction(QString("*%1").arg(item->text(0))); + addVariableTrackerAmpersandExpressionAction = new QAction(QString("&&%1").arg(item->text(0))); + addVariableTrackerAsteriskAmpersandExpressionAction = new QAction(QString("*&&%1").arg(item->text(0))); + addVariableTrackerObjcExpressionAction = new QAction(QString("(objc)%1").arg(item->text(0))); + addMemoryVisualizerAction = new QAction(QString("%1").arg(item->text(0))); + addMemoryAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(0))); + addMemoryAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(0))); + addArrayVisualizerAction = new QAction(QString("%1").arg(item->text(0))); + addArrayAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(0))); + addArrayAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(0))); + addMatrixVisualizerAction = new QAction(QString("%1").arg(item->text(0))); + addMatrixAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(0))); + addMatrixAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(0))); + addStructVisualizerAction = new QAction(QString("%1").arg(item->text(0))); + addStructAsteriskVisualizerAction = new QAction(QString("*%1").arg(item->text(0))); + addStructAmpersandVisualizerAction = new QAction(QString("&&%1").arg(item->text(0))); QMenu menu("Visualizers", this); menu.setTitle("Visualizers");