Migrate static helper functions in `StaTclTypes.i` to non-static functions in `TclTypeHelpers.cc`/`.hh` (#182)
* Migrate static helper functions in StaTclTypes.i to non-static functions in StaTclTypeHelpers.cc/.hh * Rename and reorder as requested
This commit is contained in:
parent
aaa9d2d377
commit
cc3b911b6d
|
|
@ -126,6 +126,11 @@ set(STA_SOURCE
|
|||
parasitics/SpefReader.cc
|
||||
parasitics/SpefReaderPvt.hh
|
||||
|
||||
power/Power.cc
|
||||
power/VcdReader.cc
|
||||
power/SaifReader.cc
|
||||
power/VcdParse.cc
|
||||
|
||||
sdc/Clock.cc
|
||||
sdc/ClockGatingCheck.cc
|
||||
sdc/ClockGroups.cc
|
||||
|
|
@ -198,10 +203,7 @@ set(STA_SOURCE
|
|||
spice/WriteSpice.cc
|
||||
spice/Xyce.cc
|
||||
|
||||
power/Power.cc
|
||||
power/VcdReader.cc
|
||||
power/SaifReader.cc
|
||||
power/VcdParse.cc
|
||||
tcl/TclTypeHelpers.cc
|
||||
|
||||
util/Debug.cc
|
||||
util/DispatchQueue.cc
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2024, Parallax Software, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "StringSet.hh"
|
||||
#include "StringSeq.hh"
|
||||
|
||||
#include <tcl.h>
|
||||
|
||||
namespace sta {
|
||||
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
typedef int Tcl_Size;
|
||||
#endif
|
||||
|
||||
StringSet *
|
||||
tclListSetConstChar(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp);
|
||||
|
||||
StringSeq *
|
||||
tclListSeqConstChar(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp);
|
||||
|
||||
StdStringSet *
|
||||
tclListSetStdString(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp);
|
||||
|
||||
void
|
||||
tclArgError(Tcl_Interp *interp,
|
||||
const char *msg,
|
||||
const char *arg);
|
||||
|
||||
void
|
||||
objectListNext(const char *list,
|
||||
const char *type,
|
||||
// Return values.
|
||||
bool &type_match,
|
||||
const char *&next);
|
||||
|
||||
Tcl_Obj *
|
||||
tclArcDcalcArg(ArcDcalcArg &gate,
|
||||
Tcl_Interp *interp);
|
||||
|
||||
ArcDcalcArg
|
||||
arcDcalcArgTcl(Tcl_Obj *obj,
|
||||
Tcl_Interp *interp);
|
||||
|
||||
} // namespace
|
||||
|
|
@ -39,9 +39,9 @@
|
|||
#include "PathEnd.hh"
|
||||
#include "SearchClass.hh"
|
||||
#include "CircuitSim.hh"
|
||||
#include "ArcDelayCalc.hh"
|
||||
#include "Property.hh"
|
||||
#include "Sta.hh"
|
||||
#include "TclTypeHelpers.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
|
|
@ -190,66 +190,6 @@ tclListNetworkSet1(Tcl_Obj *const source,
|
|||
return set;
|
||||
}
|
||||
|
||||
static StringSet *
|
||||
tclListSetConstChar(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Tcl_Size argc;
|
||||
Tcl_Obj **argv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||
StringSet *set = new StringSet;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||
set->insert(str);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static StringSeq *
|
||||
tclListSeqConstChar(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Tcl_Size argc;
|
||||
Tcl_Obj **argv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||
StringSeq *seq = new StringSeq;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||
seq->push_back(str);
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static StdStringSet *
|
||||
tclListSetStdString(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Tcl_Size argc;
|
||||
Tcl_Obj **argv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||
StdStringSet *set = new StdStringSet;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||
set->insert(str);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Sequence out to tcl list.
|
||||
|
|
@ -315,121 +255,6 @@ setPtrTclList(SET_TYPE *set,
|
|||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static void
|
||||
tclArgError(Tcl_Interp *interp,
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
objectListNext(const char *list,
|
||||
const char *type,
|
||||
// Return values.
|
||||
bool &type_match,
|
||||
const char *&next)
|
||||
{
|
||||
// Default return values (failure).
|
||||
type_match = false;
|
||||
next = nullptr;
|
||||
// _hexaddress_p_type
|
||||
const char *s = list;
|
||||
char ch = *s++;
|
||||
if (ch == '_') {
|
||||
while (*s && isxdigit(*s))
|
||||
s++;
|
||||
if ((s - list - 1) == sizeof(void*) * 2
|
||||
&& *s && *s++ == '_'
|
||||
&& *s && *s++ == 'p'
|
||||
&& *s && *s++ == '_') {
|
||||
const char *t = type;
|
||||
while (*s && *s != ' ') {
|
||||
if (*s != *t)
|
||||
return;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
type_match = true;
|
||||
if (*s)
|
||||
next = s + 1;
|
||||
else
|
||||
next = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Tcl_Obj *
|
||||
tclArcDcalcArg(ArcDcalcArg &gate,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
const Network *network = sta->network();
|
||||
const Instance *drvr = network->instance(gate.drvrPin());
|
||||
const TimingArc *arc = gate.arc();
|
||||
|
||||
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
||||
Tcl_Obj *obj;
|
||||
|
||||
const char *inst_name = network->pathName(drvr);
|
||||
obj = Tcl_NewStringObj(inst_name, strlen(inst_name));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *from_name = arc->from()->name();
|
||||
obj = Tcl_NewStringObj(from_name, strlen(from_name));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *from_edge = arc->fromEdge()->asString();
|
||||
obj = Tcl_NewStringObj(from_edge, strlen(from_edge));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *to_name = arc->to()->name();
|
||||
obj = Tcl_NewStringObj(to_name, strlen(to_name));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *to_edge = arc->toEdge()->asString();
|
||||
obj = Tcl_NewStringObj(to_edge, strlen(to_edge));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *input_delay = delayAsString(gate.inputDelay(), sta, 3);
|
||||
obj = Tcl_NewStringObj(input_delay, strlen(input_delay));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static ArcDcalcArg
|
||||
arcDcalcArgTcl(Tcl_Obj *obj,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
sta->ensureGraph();
|
||||
int list_argc;
|
||||
Tcl_Obj **list_argv;
|
||||
if (Tcl_ListObjGetElements(interp, obj, &list_argc, &list_argv) == TCL_OK) {
|
||||
const char *input_delay = "0.0";
|
||||
int length;
|
||||
if (list_argc == 6)
|
||||
input_delay = Tcl_GetStringFromObj(list_argv[5], &length);
|
||||
if (list_argc == 5 || list_argc == 6) {
|
||||
return makeArcDcalcArg(Tcl_GetStringFromObj(list_argv[0], &length),
|
||||
Tcl_GetStringFromObj(list_argv[1], &length),
|
||||
Tcl_GetStringFromObj(list_argv[2], &length),
|
||||
Tcl_GetStringFromObj(list_argv[3], &length),
|
||||
Tcl_GetStringFromObj(list_argv[4], &length),
|
||||
input_delay, sta);
|
||||
}
|
||||
else
|
||||
sta->report()->warn(2140, "Delay calc arg requires 5 or 6 args.");
|
||||
}
|
||||
return ArcDcalcArg();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
using namespace sta;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,201 @@
|
|||
// OpenSTA, Static Timing Analyzer
|
||||
// Copyright (c) 2024, Parallax Software, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "TclTypeHelpers.hh"
|
||||
|
||||
#include "Liberty.hh"
|
||||
#include "Network.hh"
|
||||
#include "Sta.hh"
|
||||
|
||||
namespace sta {
|
||||
|
||||
StringSet *
|
||||
tclListSetConstChar(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Tcl_Size argc;
|
||||
Tcl_Obj **argv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||
StringSet *set = new StringSet;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||
set->insert(str);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringSeq *
|
||||
tclListSeqConstChar(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Tcl_Size argc;
|
||||
Tcl_Obj **argv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||
StringSeq *seq = new StringSeq;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||
seq->push_back(str);
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StdStringSet *
|
||||
tclListSetStdString(Tcl_Obj *const source,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Tcl_Size argc;
|
||||
Tcl_Obj **argv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, source, &argc, &argv) == TCL_OK) {
|
||||
StdStringSet *set = new StdStringSet;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
int length;
|
||||
const char *str = Tcl_GetStringFromObj(argv[i], &length);
|
||||
set->insert(str);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
tclArgError(Tcl_Interp *interp,
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
objectListNext(const char *list,
|
||||
const char *type,
|
||||
// Return values.
|
||||
bool &type_match,
|
||||
const char *&next)
|
||||
{
|
||||
// Default return values (failure).
|
||||
type_match = false;
|
||||
next = nullptr;
|
||||
// _hexaddress_p_type
|
||||
const char *s = list;
|
||||
char ch = *s++;
|
||||
if (ch == '_') {
|
||||
while (*s && isxdigit(*s))
|
||||
s++;
|
||||
if ((s - list - 1) == sizeof(void*) * 2
|
||||
&& *s && *s++ == '_'
|
||||
&& *s && *s++ == 'p'
|
||||
&& *s && *s++ == '_') {
|
||||
const char *t = type;
|
||||
while (*s && *s != ' ') {
|
||||
if (*s != *t)
|
||||
return;
|
||||
s++;
|
||||
t++;
|
||||
}
|
||||
type_match = true;
|
||||
if (*s)
|
||||
next = s + 1;
|
||||
else
|
||||
next = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_Obj *
|
||||
tclArcDcalcArg(ArcDcalcArg &gate,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
const Network *network = sta->network();
|
||||
const Instance *drvr = network->instance(gate.drvrPin());
|
||||
const TimingArc *arc = gate.arc();
|
||||
|
||||
Tcl_Obj *list = Tcl_NewListObj(0, nullptr);
|
||||
Tcl_Obj *obj;
|
||||
|
||||
const char *inst_name = network->pathName(drvr);
|
||||
obj = Tcl_NewStringObj(inst_name, strlen(inst_name));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *from_name = arc->from()->name();
|
||||
obj = Tcl_NewStringObj(from_name, strlen(from_name));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *from_edge = arc->fromEdge()->asString();
|
||||
obj = Tcl_NewStringObj(from_edge, strlen(from_edge));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *to_name = arc->to()->name();
|
||||
obj = Tcl_NewStringObj(to_name, strlen(to_name));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *to_edge = arc->toEdge()->asString();
|
||||
obj = Tcl_NewStringObj(to_edge, strlen(to_edge));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
const char *input_delay = delayAsString(gate.inputDelay(), sta, 3);
|
||||
obj = Tcl_NewStringObj(input_delay, strlen(input_delay));
|
||||
Tcl_ListObjAppendElement(interp, list, obj);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
ArcDcalcArg
|
||||
arcDcalcArgTcl(Tcl_Obj *obj,
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Sta *sta = Sta::sta();
|
||||
sta->ensureGraph();
|
||||
int list_argc;
|
||||
Tcl_Obj **list_argv;
|
||||
if (Tcl_ListObjGetElements(interp, obj, &list_argc, &list_argv) == TCL_OK) {
|
||||
const char *input_delay = "0.0";
|
||||
int length;
|
||||
if (list_argc == 6)
|
||||
input_delay = Tcl_GetStringFromObj(list_argv[5], &length);
|
||||
if (list_argc == 5 || list_argc == 6) {
|
||||
return makeArcDcalcArg(Tcl_GetStringFromObj(list_argv[0], &length),
|
||||
Tcl_GetStringFromObj(list_argv[1], &length),
|
||||
Tcl_GetStringFromObj(list_argv[2], &length),
|
||||
Tcl_GetStringFromObj(list_argv[3], &length),
|
||||
Tcl_GetStringFromObj(list_argv[4], &length),
|
||||
input_delay, sta);
|
||||
}
|
||||
else
|
||||
sta->report()->warn(2140, "Delay calc arg requires 5 or 6 args.");
|
||||
}
|
||||
return ArcDcalcArg();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Loading…
Reference in New Issue