Skip to content

Commit

Permalink
Better reporting for TCL errors
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jan 18, 2025
1 parent 1febb2c commit 7d70130
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 16 deletions.
3 changes: 2 additions & 1 deletion src/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,8 @@ static void diag_emit_hints(diag_t *d, FILE *f)
color_fprintf(f, "%*s", first_col, "");

int ncarets = 1;
if (hint->loc.line_delta == 0)
if (hint->loc.line_delta == 0
&& hint->loc.column_delta != DELTA_INVALID)
ncarets = hint->loc.column_delta + 1;

const int hintcol = fwidth + hint->loc.first_column + ncarets + 4;
Expand Down
31 changes: 17 additions & 14 deletions src/rt/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -1325,16 +1325,22 @@ void shell_free(tcl_shell_t *sh)
bool shell_eval(tcl_shell_t *sh, const char *script, const char **result)
{
const int code = Tcl_Eval(sh->interp, script);
const char *str = Tcl_GetStringResult(sh->interp);

switch (code) {
case TCL_OK:
if (result != NULL)
*result = str;
*result = Tcl_GetStringResult(sh->interp);
return true;
case TCL_ERROR:
if (str != NULL && *str != '\0')
errorf("%s", str);
{
const char *info = Tcl_GetVar(sh->interp, "::errorInfo", 0);
if (info != NULL && *info != '\n')
errorf("%s", info);

*result = Tcl_GetStringResult(sh->interp);
if (info == NULL && *result != NULL && **result != '\0')
errorf("%s", *result);
}
return false;
default:
warnf("Tcl_Eval returned unknown code %d", code);
Expand Down Expand Up @@ -1462,16 +1468,13 @@ bool shell_do(tcl_shell_t *sh, const char *file)
return true;
case TCL_ERROR:
{
const char *str = Tcl_GetStringResult(sh->interp);
if (str != NULL && *str != '\0') {
diag_t *d = diag_new(DIAG_ERROR, NULL);
diag_printf(d, "%s", str);

const char *info = Tcl_GetVar(sh->interp, "::errorInfo", 0);
if (info != NULL)
diag_hint(d, NULL, "%s", info);

diag_emit(d);
const char *info = Tcl_GetVar(sh->interp, "::errorInfo", 0);
if (info != NULL && *info != '\n')
errorf("%s", info);
else {
const char *str = Tcl_GetStringResult(sh->interp);
if (str != NULL && *str != '\0')
errorf("%s", str);
}

return false;
Expand Down
10 changes: 10 additions & 0 deletions test/regress/gold/tcl3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
boo
while executing
"error "boo""
(procedure "proc2" line 2)
invoked from within
"proc2"
(procedure "proc1" line 2)
invoked from within
"proc1"
(file "
9 changes: 9 additions & 0 deletions test/regress/tcl3.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
proc proc2 args {
error "boo"
}

proc proc1 args {
proc2
}

proc1
1 change: 1 addition & 0 deletions test/regress/testlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1093,3 +1093,4 @@ cmdline13 shell
issue1117 normal,psl,2008
issue1125 normal,2008
issue1137 normal
tcl3 tcl,fail,gold
1 change: 0 additions & 1 deletion test/test_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ START_TEST(test_analyse)

const char *result = NULL;
fail_if(shell_eval(sh, "analyse " TESTDIR "/parse/entity.vhd", &result));
ck_assert_ptr_eq(result, NULL);

tree_t one = lib_get(lib_work(), ident_new("WORK.ONE"));
fail_if(one == NULL);
Expand Down

0 comments on commit 7d70130

Please sign in to comment.