From 591eb9b351f70b82700284dcb1d001e5b17f253f Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Sat, 15 Feb 2025 00:33:16 +0100 Subject: [PATCH] msg: Make tclArgError use report logger, accept msg id and be parsed by FindMessages. (#216) Signed-off-by: Christian Costa --- etc/FindMessages.tcl | 6 ++-- include/sta/TclTypeHelpers.hh | 1 + tcl/StaTclTypes.i | 64 +++++++++++++++-------------------- tcl/TclTypeHelpers.cc | 11 +++--- 4 files changed, 38 insertions(+), 44 deletions(-) diff --git a/etc/FindMessages.tcl b/etc/FindMessages.tcl index ad8fbdc2..24dcc3ad 100755 --- a/etc/FindMessages.tcl +++ b/etc/FindMessages.tcl @@ -41,7 +41,7 @@ proc scan_file { file warn_regexp } { set file_line 1 while { ![eof $in_stream] } { - if { [regexp -- $warn_regexp $line ignore1 ignore2 msg_id msg] } { + if { [regexp -- $warn_regexp $line ignore msg_id msg] } { lappend msgs "$msg_id $file $file_line $msg" } gets $in_stream line @@ -61,13 +61,13 @@ foreach subdir $subdirs { set files [glob -nocomplain [file join $subdir "*.{cc,hh,yy,ll,i}"]] set files_c [concat $files_c $files] } -set warn_regexp_c {(criticalError|->warn|->fileWarn|->error|->fileError|libWarn|libError| warn)\(([0-9]+),.*(".+")} +set warn_regexp_c {(?:(?:criticalError|->warn|->fileWarn|->error|->fileError|libWarn|libError| warn)\(|tclArgError\(interp,\s*)([0-9]+),.*(".+")} set files_tcl {} foreach subdir $subdirs { set files_tcl [concat $files_tcl [glob -nocomplain [file join $subdir "*.tcl"]]] } -set warn_regexp_tcl {(sta_warn|sta_error|sta_warn_error) ([0-9]+) (".+")} +set warn_regexp_tcl {(?:sta_warn|sta_error|sta_warn_error) ([0-9]+) (".+")} proc scan_files {files warn_regexp } { foreach file $files { diff --git a/include/sta/TclTypeHelpers.hh b/include/sta/TclTypeHelpers.hh index 506d3a0c..a70f8400 100644 --- a/include/sta/TclTypeHelpers.hh +++ b/include/sta/TclTypeHelpers.hh @@ -48,6 +48,7 @@ tclListSetStdString(Tcl_Obj *const source, void tclArgError(Tcl_Interp *interp, + int id, const char *msg, const char *arg); diff --git a/tcl/StaTclTypes.i b/tcl/StaTclTypes.i index b5f6b5e5..dd3f1c63 100644 --- a/tcl/StaTclTypes.i +++ b/tcl/StaTclTypes.i @@ -441,8 +441,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); Transition *tr = Transition::find(arg); if (tr == nullptr) { - Tcl_SetResult(interp,const_cast("Error: transition not found."), - TCL_STATIC); + tclArgError(interp, 2150, "Unknown transition '%s'.", arg); return TCL_ERROR; } else @@ -462,8 +461,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); RiseFall *rf = RiseFall::find(arg); if (rf == nullptr) { - Tcl_SetResult(interp,const_cast("Error: unknown rise/fall edge."), - TCL_STATIC); + tclArgError(interp, 2151, "Unknown rise/fall edge '%s'.", arg); return TCL_ERROR; } $1 = rf; @@ -482,8 +480,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); RiseFallBoth *tr = RiseFallBoth::find(arg); if (tr == nullptr) { - Tcl_SetResult(interp,const_cast("Error: unknown transition name."), - TCL_STATIC); + tclArgError(interp, 2152, "Unknown transition name '%s'.", arg); return TCL_ERROR; } $1 = tr; @@ -502,8 +499,7 @@ using namespace sta; const char *arg = Tcl_GetStringFromObj($input, &length); PortDirection *dir = PortDirection::find(arg); if (dir == nullptr) { - Tcl_SetResult(interp,const_cast("Error: port direction not found."), - TCL_STATIC); + tclArgError(interp, 2153, "Unknown port direction '%s'.", arg); return TCL_ERROR; } else @@ -517,8 +513,7 @@ using namespace sta; if (role) $1 = TimingRole::find(arg); else { - Tcl_SetResult(interp,const_cast("Error: unknown timing role."), - TCL_STATIC); + tclArgError(interp, 2154, "Unknown timing role '%s'.", arg); return TCL_ERROR; } } @@ -541,8 +536,7 @@ using namespace sta; else if (stringEq(arg, "fall") || stringEq(arg, "falling")) $1 = LogicValue::fall; else { - Tcl_SetResult(interp,const_cast("Error: unknown logic value."), - TCL_STATIC); + tclArgError(interp, 2155, "Unknown logic value '%s'.", arg); return TCL_ERROR; } } @@ -557,9 +551,7 @@ using namespace sta; else if (stringEq(arg, "on_chip_variation")) $1 = AnalysisType::ocv; else { - Tcl_SetResult(interp,const_cast("Error: unknown analysis type."), - TCL_STATIC); - + tclArgError(interp, 2156, "Unknown analysis type '%s'.", arg); return TCL_ERROR; } } @@ -757,11 +749,11 @@ using namespace sta; char *arg = Tcl_GetString(argv[i]); double value; if (Tcl_GetDouble(interp, arg, &value) == TCL_OK) - floats->push_back(static_cast(value)); + floats->push_back(static_cast(value)); else { - delete floats; - tclArgError(interp, "%s is not a floating point number.", arg); - return TCL_ERROR; + delete floats; + tclArgError(interp, 2157, "%s is not a floating point number.", arg); + return TCL_ERROR; } } } @@ -802,11 +794,11 @@ using namespace sta; char *arg = Tcl_GetString(argv[i]); int value; if (Tcl_GetInt(interp, arg, &value) == TCL_OK) - ints->push_back(value); + ints->push_back(value); else { - delete ints; - tclArgError(interp, "%s is not an integer.", arg); - return TCL_ERROR; + delete ints; + tclArgError(interp, 2158, "%s is not an integer.", arg); + return TCL_ERROR; } } } @@ -860,7 +852,7 @@ using namespace sta; if (min_max) $1 = min_max; else { - tclArgError(interp, "%s not min or max.", arg); + tclArgError(interp, 2159, "%s not min or max.", arg); return TCL_ERROR; } } @@ -880,7 +872,7 @@ using namespace sta; if (min_max) $1 = min_max; else { - tclArgError(interp, "%s not min, max or min_max.", arg); + tclArgError(interp, 2160, "%s not min, max or min_max.", arg); return TCL_ERROR; } } @@ -895,7 +887,7 @@ using namespace sta; if (min_max) $1 = min_max; else { - tclArgError(interp, "%s not min, max or min_max.", arg); + tclArgError(interp, 2161, "%s not min, max or min_max.", arg); return TCL_ERROR; } } @@ -916,7 +908,7 @@ using namespace sta; || stringEqual(arg, "max")) $1 = MinMax::max(); else { - tclArgError(interp, "%s not setup, hold, min or max.", arg); + tclArgError(interp, 2162, "%s not setup, hold, min or max.", arg); return TCL_ERROR; } } @@ -935,7 +927,7 @@ using namespace sta; || stringEqual(arg, "min_max")) $1 = SetupHoldAll::all(); else { - tclArgError(interp, "%s not setup, hold, setup_hold, min, max or min_max.", arg); + tclArgError(interp, 2163, "%s not setup, hold, setup_hold, min, max or min_max.", arg); return TCL_ERROR; } } @@ -948,7 +940,7 @@ using namespace sta; if (early_late) $1 = early_late; else { - tclArgError(interp, "%s not early/min, late/max or early_late/min_max.", arg); + tclArgError(interp, 2164, "%s not early/min, late/max or early_late/min_max.", arg); return TCL_ERROR; } } @@ -961,7 +953,7 @@ using namespace sta; if (early_late) $1 = early_late; else { - tclArgError(interp, "%s not early/min, late/max or early_late/min_max.", arg); + tclArgError(interp, 2165, "%s not early/min, late/max or early_late/min_max.", arg); return TCL_ERROR; } } @@ -976,7 +968,7 @@ using namespace sta; else if (stringEq(arg, "cell_check")) $1 = TimingDerateType::cell_check; else { - tclArgError(interp, "%s not net_delay, cell_delay or cell_check.", arg); + tclArgError(interp, 2166, "%s not net_delay, cell_delay or cell_check.", arg); return TCL_ERROR; } } @@ -989,7 +981,7 @@ using namespace sta; else if (stringEq(arg, "cell_check")) $1 = TimingDerateCellType::cell_check; else { - tclArgError(interp, "%s not cell_delay or cell_check.", arg); + tclArgError(interp, 2167, "%s not cell_delay or cell_check.", arg); return TCL_ERROR; } } @@ -1002,7 +994,7 @@ using namespace sta; else if (stringEq(arg, "data")) $1 = PathClkOrData::data; else { - tclArgError(interp, "%s not clk or data.", arg); + tclArgError(interp, 2168, "%s not clk or data.", arg); return TCL_ERROR; } } @@ -1015,7 +1007,7 @@ using namespace sta; else if (stringEq(arg, "slack")) $1 = sort_by_slack; else { - tclArgError(interp, "%s not group or slack.", arg); + tclArgError(interp, 2169, "%s not group or slack.", arg); return TCL_ERROR; } } @@ -1040,7 +1032,7 @@ using namespace sta; else if (stringEq(arg, "json")) $1 = ReportPathFormat::json; else { - tclArgError(interp, "unknown path type %s.", arg); + tclArgError(interp, 2170, "unknown path type %s.", arg); return TCL_ERROR; } } @@ -1406,7 +1398,7 @@ using namespace sta; else if (stringEq(arg, "xyce")) $1 = CircuitSim::xyce; else { - tclArgError(interp, "unknown circuit simulator %s.", arg); + tclArgError(interp, 2171, "unknown circuit simulator %s.", arg); return TCL_ERROR; } } diff --git a/tcl/TclTypeHelpers.cc b/tcl/TclTypeHelpers.cc index d8da8e44..228ab083 100644 --- a/tcl/TclTypeHelpers.cc +++ b/tcl/TclTypeHelpers.cc @@ -93,15 +93,16 @@ tclListSetStdString(Tcl_Obj *const source, void tclArgError(Tcl_Interp *interp, + int id, const char *msg, const char *arg) { // Swig does not add try/catch around arg parsing so this cannot use Report::error. - string error_msg = "Error: "; - error_msg += msg; - char *error = stringPrint(error_msg.c_str(), arg); - Tcl_SetResult(interp, error, TCL_VOLATILE); - stringDelete(error); + try { + Sta::sta()->report()->error(id, msg, arg); + } catch (const std::exception &e) { + Tcl_SetResult(interp, const_cast(e.what()), TCL_STATIC); + } } void