Skip to content

Commit 862863d

Browse files
authored
Merge pull request #8085 from The-OpenROAD-Project-staging/gui-tcl-stack
gui: add the TCL stacktrace to the output on error
2 parents e561a14 + 363833b commit 862863d

File tree

4 files changed

+31
-6
lines changed

4 files changed

+31
-6
lines changed

src/gui/src/cmdInputWidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class CmdInputWidget : public QPlainTextEdit
3434
void commandFinishedExecuting(bool is_ok);
3535

3636
void addResultToOutput(const QString& result, bool is_ok);
37+
void addTextToOutput(const QString& text, const QColor& color);
3738
void addCommandToOutput(const QString& cmd);
3839

3940
public slots:

src/gui/src/scriptWidget.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ ScriptWidget::ScriptWidget(QWidget* parent)
7575
&TclCmdInputWidget::addResultToOutput,
7676
this,
7777
&ScriptWidget::addResultToOutput);
78+
connect(input_,
79+
&TclCmdInputWidget::addTextToOutput,
80+
this,
81+
&ScriptWidget::addTextToOutput,
82+
Qt::QueuedConnection);
7883
connect(input_,
7984
&TclCmdInputWidget::commandFinishedExecuting,
8085
this,

src/gui/src/tclCmdInputWidget.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ void TclCmdInputWidget::setTclInterp(Tcl_Interp* interp,
8080
// OpenRoad is not initialized
8181
emit commandAboutToExecute();
8282
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
83-
const bool setup_tcl_result = ord::tclInit(interp_) == TCL_OK;
83+
const int setup_tcl_result = ord::tclInit(interp_);
8484
post_or_init();
8585
processTclResult(setup_tcl_result);
86-
emit commandFinishedExecuting(setup_tcl_result);
86+
emit commandFinishedExecuting(setup_tcl_result == TCL_OK);
8787
} else {
8888
post_or_init();
8989
}
@@ -675,7 +675,7 @@ void TclCmdInputWidget::executeCommand(const QString& cmd,
675675

676676
if (!silent) {
677677
// Show its output
678-
processTclResult(is_ok);
678+
processTclResult(return_code);
679679

680680
if (is_ok) {
681681
// record the successful command to tcl history command
@@ -685,16 +685,35 @@ void TclCmdInputWidget::executeCommand(const QString& cmd,
685685
} else {
686686
if (!is_ok) {
687687
// Show output on error despite silent
688-
processTclResult(is_ok);
688+
processTclResult(return_code);
689689
}
690690
}
691691

692692
emit commandFinishedExecuting(is_ok);
693693
}
694694

695-
void TclCmdInputWidget::processTclResult(bool is_ok)
695+
void TclCmdInputWidget::processTclResult(const int tcl_result)
696696
{
697+
const bool is_ok = (tcl_result == TCL_OK);
697698
emit addResultToOutput(Tcl_GetString(Tcl_GetObjResult(interp_)), is_ok);
699+
700+
if (!is_ok) {
701+
// Tcl_GetReturnOptions returns an object with a ref count of 0.
702+
// We DO NOT own it and MUST NOT decrement its ref count.
703+
Tcl_Obj* options = Tcl_GetReturnOptions(interp_, tcl_result);
704+
705+
// Create a key to look up the stack trace in the options dictionary.
706+
Tcl_Obj* key = Tcl_NewStringObj("-errorinfo", -1); // refCount is now 1
707+
708+
// Look up the stack trace.
709+
Tcl_Obj* stackTrace = nullptr;
710+
if (Tcl_DictObjGet(nullptr, options, key, &stackTrace) == TCL_OK
711+
&& stackTrace) {
712+
emit addTextToOutput(Tcl_GetString(stackTrace), Qt::red);
713+
}
714+
715+
Tcl_DecrRefCount(key);
716+
}
698717
}
699718

700719
} // namespace gui

src/gui/src/tclCmdInputWidget.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class TclCmdInputWidget : public CmdInputWidget
6767

6868
private:
6969
void init();
70-
void processTclResult(bool is_ok);
70+
void processTclResult(int tcl_result);
7171

7272
static int tclExitHandler(ClientData instance_data,
7373
Tcl_Interp* interp,

0 commit comments

Comments
 (0)