Fixed a bug in the combine routine that causes a segfault; added
preliminary support for a Tcl list output format.
This commit is contained in:
parent
4f24915661
commit
8deccaad9c
|
|
@ -170,7 +170,7 @@ char *ReadExt(char *fname, int doflat, int *fnum)
|
|||
|
||||
SetExtension(name, fname, EXT_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
Printf("No file: %s\n",name);
|
||||
Printf("Error in ext file read: No file %s\n",name);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -643,7 +643,7 @@ char *ReadSim(char *fname, int *fnum)
|
|||
|
||||
SetExtension(name, fname, SIM_EXTENSION);
|
||||
if (OpenParseFile(name, *fnum) < 0) {
|
||||
Printf("No file: %s\n",name);
|
||||
Printf("Error in ext file read: No file %s\n",name);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
779
base/netcmp.c
779
base/netcmp.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -9,6 +9,7 @@ extern struct nlist *Circuit2;
|
|||
extern int ExhaustiveSubdivision;
|
||||
|
||||
#ifdef TCL_NETGEN
|
||||
#include <tcl.h>
|
||||
extern int InterruptPending;
|
||||
#endif
|
||||
|
||||
|
|
@ -17,10 +18,11 @@ extern int InterruptPending;
|
|||
extern void PrintElementClasses(struct ElementClass *EC, int type, int dolist);
|
||||
extern void PrintNodeClasses(struct NodeClass *NC, int type, int dolist);
|
||||
extern void SummarizeNodeClasses(struct NodeClass *NC);
|
||||
extern void PrintPropertyResults(void);
|
||||
extern void PrintPropertyResults(int do_list);
|
||||
extern void PrintCoreStats(void);
|
||||
extern void ResetState(void);
|
||||
extern void CreateTwoLists(char *name1, int file1, char *name2, int file2);
|
||||
extern void CreateTwoLists(char *name1, int file1, char *name2, int file2,
|
||||
int dolist);
|
||||
extern int Iterate(void);
|
||||
extern int VerifyMatching(void);
|
||||
extern void PrintAutomorphisms(void);
|
||||
|
|
@ -33,7 +35,7 @@ extern int EquivalenceElements(char *name1, int file1, char *name2, int file2);
|
|||
extern int EquivalenceNodes(char *name1, int file1, char *name2, int file2);
|
||||
extern int EquivalenceClasses(char *name1, int file1, char *name2, int file2);
|
||||
extern int IgnoreClass(char *name, int file, unsigned char type);
|
||||
extern int MatchPins(struct nlist *tp1, struct nlist *tp2);
|
||||
extern int MatchPins(struct nlist *tp1, struct nlist *tp2, int dolist);
|
||||
extern int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int serial);
|
||||
|
||||
extern int CreateCompareQueue(char *, int, char *, int);
|
||||
|
|
@ -51,5 +53,8 @@ extern int EquivalentElement();
|
|||
|
||||
extern void enable_interrupt();
|
||||
extern void disable_interrupt();
|
||||
|
||||
extern Tcl_Obj *ListNodeClasses(int legal);
|
||||
extern Tcl_Obj *ListElementClasses(int legal);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -77,8 +77,9 @@ extern char *SetExtension(char *buffer, char *path, char *extension)
|
|||
strcat(tmpbuf, extension);
|
||||
|
||||
/* step 4: lower-case the entire name */
|
||||
for (pt = tmpbuf; *pt != '\0'; pt++)
|
||||
if (isupper(*pt)) *pt = tolower(*pt);
|
||||
/* (Commented out because this is really stupid.) */
|
||||
// for (pt = tmpbuf; *pt != '\0'; pt++)
|
||||
// if (isupper(*pt)) *pt = tolower(*pt);
|
||||
|
||||
if (buffer != NULL) {
|
||||
strcpy(buffer, tmpbuf);
|
||||
|
|
@ -567,7 +568,7 @@ char *ReadNetgenFile (char *fname, int *fnum)
|
|||
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
|
||||
SetExtension(name, fname, NETGEN_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
Printf("No file: %s\n",name);
|
||||
Printf("Error in netgen read: No file %s\n",name);
|
||||
*fnum = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -803,7 +804,7 @@ char *ReadNetgenFile (char *fname, int *fnum)
|
|||
if ((File = open(fname, O_RDONLY, FILE_ACCESS_BITS)) == -1) {
|
||||
SetExtension(name, fname, NETGEN_EXTENSION);
|
||||
if ((File = open(name, O_RDONLY, FILE_ACCESS_BITS)) == -1) {
|
||||
Printf("No file: %s\n",name);
|
||||
Printf("Error in netgen read: No file %s\n",name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3072,7 +3072,7 @@ int CombineParallel(char *model, int file)
|
|||
pob = ob2;
|
||||
pcnt += 10;
|
||||
}
|
||||
if (ob2->type == PROPERTY) propfirst = ob2;
|
||||
if (ob2 && (ob2->type == PROPERTY)) propfirst = ob2;
|
||||
|
||||
/* Find last record in device and first record in next object */
|
||||
while (ob2 && ob2->type == PROPERTY) {
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ char *ReadNtk (char *fname, int *fnum)
|
|||
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
|
||||
SetExtension(name, fname, NTK_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
Printf("No file: %s\n",name);
|
||||
Printf("Error in ntk file read: No file %s\n",name);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1808,7 +1808,7 @@ char *ReadSpiceTop(char *fname, int *fnum, int blackbox)
|
|||
|
||||
SetExtension(name, fname, SPICE_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
Fprintf(stderr,"No file: %s\n",name);
|
||||
Fprintf(stderr,"Error in SPICE file read: No file %s\n",name);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1903,7 +1903,7 @@ void IncludeSpice(char *fname, int parent, struct cellstack **CellStackPtr,
|
|||
|
||||
SetExtension(name, fname, SPICE_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, parent)) < 0) {
|
||||
Fprintf(stderr,"No file: %s\n",name);
|
||||
Fprintf(stderr,"Error in SPICE file read: No file %s\n",name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ void initialize_netcmp_datastructures(Widget w, Widget textwidget,
|
|||
{
|
||||
X_START();
|
||||
Printf("Comparing cells '%s' and '%s'\n", get_cell(), get_other());
|
||||
CreateTwoLists(get_cell(), get_other());
|
||||
CreateTwoLists(get_cell(), get_other(), 0);
|
||||
Permute();
|
||||
#ifdef DEBUG_ALLOC
|
||||
PrintCoreStats();
|
||||
|
|
|
|||
|
|
@ -34,9 +34,22 @@ if {${tcl_version} >= 8.6} {
|
|||
# Use the "canonical" command to parse the file and cell names,
|
||||
# although if the cells have not been read in yet, then the
|
||||
# original syntax of filename or {filename cellname} is required.
|
||||
#
|
||||
# "args" is passed to verify and may therefore contain only the
|
||||
# value "-list" or nothing. If "-list", then output is returned
|
||||
# as a nested list.
|
||||
#----------------------------------------------------------------
|
||||
|
||||
proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
|
||||
proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
|
||||
set dolist 0
|
||||
puts stdout "Diagnostic version"
|
||||
foreach arg $args {
|
||||
if {$arg == "-list"} {
|
||||
puts stdout "Generating list result"
|
||||
set dolist 1
|
||||
set lvs_final {}
|
||||
}
|
||||
}
|
||||
|
||||
# Allow name1 or name2 to be a list of {filename cellname},
|
||||
# A single <filename>, or any valid_cellname form if the
|
||||
|
|
@ -137,24 +150,40 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
|
|||
netgen::log file $logfile
|
||||
netgen::log start
|
||||
netgen::log echo off
|
||||
set endval [netgen::compare hierarchical "$fnum1 $cell1" "$fnum2 $cell2"]
|
||||
if {$dolist == 1} {
|
||||
set endval [netgen::compare -list hierarchical "$fnum1 $cell1" "$fnum2 $cell2"]
|
||||
} else {
|
||||
set endval [netgen::compare hierarchical "$fnum1 $cell1" "$fnum2 $cell2"]
|
||||
}
|
||||
if {$endval == {}} {
|
||||
netgen::log put "No cells in queue!\n"
|
||||
return
|
||||
}
|
||||
set properr {}
|
||||
while {$endval != {}} {
|
||||
netgen::run converge
|
||||
if {$dolist == 1} {
|
||||
netgen::run -list converge
|
||||
} else {
|
||||
netgen::run converge
|
||||
}
|
||||
netgen::log echo on
|
||||
if {[verify equivalent]} {
|
||||
# Resolve automorphisms by pin and property
|
||||
netgen::run resolve
|
||||
if {$dolist == 1} {
|
||||
netgen::run -list resolve
|
||||
} else {
|
||||
netgen::run resolve
|
||||
}
|
||||
set uresult [verify unique]
|
||||
if {$uresult == 0} {
|
||||
netgen::log put " Networks match locally but not globally.\n"
|
||||
netgen::log put " Probably connections are swapped.\n"
|
||||
netgen::log put " Check the end of logfile ${logfile} for implicated nodes.\n"
|
||||
netgen::verify nodes
|
||||
if {$dolist == 1} {
|
||||
verify -list nodes
|
||||
} else {
|
||||
verify nodes
|
||||
}
|
||||
|
||||
# Flatten the non-matching subcircuit (but not the top-level cells)
|
||||
if {[netgen::print queue] != {}} {
|
||||
|
|
@ -183,17 +212,26 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out}} {
|
|||
}
|
||||
}
|
||||
netgen::log echo off
|
||||
set endval [netgen::compare hierarchical]
|
||||
if {$dolist == 1} {
|
||||
catch {lappend lvs_final $lvs_out}
|
||||
set lvs_out {}
|
||||
set endval [netgen::compare -list hierarchical]
|
||||
} else {
|
||||
set endval [netgen::compare hierarchical]
|
||||
}
|
||||
}
|
||||
netgen::log echo off
|
||||
puts stdout "Result: " nonewline
|
||||
netgen::log echo on
|
||||
netgen::verify only
|
||||
verify only
|
||||
if {$properr != {}} {
|
||||
netgen::log put "The following cells had property errors: $properr\n"
|
||||
}
|
||||
netgen::log end
|
||||
puts stdout "LVS Done."
|
||||
if {$dolist == 1} {
|
||||
return $lvs_final
|
||||
}
|
||||
}
|
||||
|
||||
# It is important to make sure no netgen commands overlap with Tcl built-in
|
||||
|
|
|
|||
|
|
@ -1939,13 +1939,24 @@ int
|
|||
_netcmp_compare(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
||||
{
|
||||
char *name1, *name2, *file1, *file2;
|
||||
int fnum1, fnum2;
|
||||
char *name1, *name2, *file1, *file2, *optstart;
|
||||
int fnum1, fnum2, dolist = 0;
|
||||
int dohierarchy = FALSE;
|
||||
int assignonly = FALSE;
|
||||
int argstart = 1, qresult, llen, result;
|
||||
struct Correspond *nextcomp;
|
||||
struct nlist *tp;
|
||||
Tcl_Obj *flist = NULL;
|
||||
|
||||
if (objc > 1) {
|
||||
optstart = Tcl_GetString(objv[1]);
|
||||
if (*optstart == '-') optstart++;
|
||||
if (!strcmp(optstart, "list")) {
|
||||
dolist = 1;
|
||||
objv++;
|
||||
objc--;
|
||||
}
|
||||
}
|
||||
|
||||
if (objc > 1) {
|
||||
if (!strncmp(Tcl_GetString(objv[argstart]), "assign", 6)) {
|
||||
|
|
@ -2033,18 +2044,15 @@ _netcmp_compare(ClientData clientData,
|
|||
ConvertGlobals(name2, fnum2);
|
||||
}
|
||||
|
||||
// Run cleanup a 2nd time; this corrects for cells that have no ports
|
||||
// but define global nodes that are brought out as ports by
|
||||
// ConvertGlobals().
|
||||
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2);
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
|
||||
while (PrematchLists(name1, fnum1, name2, fnum2) > 0) {
|
||||
Fprintf(stdout, "Making another compare attempt.\n");
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2);
|
||||
CreateTwoLists(name1, fnum1, name2, fnum2, dolist);
|
||||
}
|
||||
|
||||
// Return the names of the two cells being compared, if doing "compare
|
||||
// hierarchical"
|
||||
// hierarchical". If "-list" was specified, then append the output
|
||||
// to the end of the list.
|
||||
|
||||
if (dohierarchy) {
|
||||
Tcl_Obj *lobj;
|
||||
|
|
@ -2242,6 +2250,19 @@ _netcmp_run(ClientData clientData,
|
|||
};
|
||||
int result, index;
|
||||
int automorphisms;
|
||||
char *optstart;
|
||||
int dolist;
|
||||
|
||||
dolist = 0;
|
||||
if (objc > 1) {
|
||||
optstart = Tcl_GetString(objv[1]);
|
||||
if (*optstart == '-') optstart++;
|
||||
if (!strcmp(optstart, "list")) {
|
||||
dolist = 1;
|
||||
objv++;
|
||||
objc--;
|
||||
}
|
||||
}
|
||||
|
||||
if (objc == 1)
|
||||
index = RESOLVE_IDX;
|
||||
|
|
@ -2260,8 +2281,13 @@ _netcmp_run(ClientData clientData,
|
|||
else {
|
||||
enable_interrupt();
|
||||
while (!Iterate() && !InterruptPending);
|
||||
_netcmp_verify(clientData, interp, 1, NULL);
|
||||
if (dolist) {
|
||||
result = _netcmp_verify(clientData, interp, 2, objv - 1);
|
||||
}
|
||||
else
|
||||
result = _netcmp_verify(clientData, interp, 1, NULL);
|
||||
disable_interrupt();
|
||||
if (result != TCL_OK) return result;
|
||||
}
|
||||
break;
|
||||
case RESOLVE_IDX:
|
||||
|
|
@ -2304,7 +2330,7 @@ _netcmp_run(ClientData clientData,
|
|||
}
|
||||
if (PropertyErrorDetected) {
|
||||
Fprintf(stdout, "There were property errors.\n");
|
||||
PrintPropertyResults();
|
||||
PrintPropertyResults(dolist);
|
||||
}
|
||||
disable_interrupt();
|
||||
}
|
||||
|
|
@ -2318,9 +2344,17 @@ _netcmp_run(ClientData clientData,
|
|||
/* Syntax: netgen::verify [option] */
|
||||
/* options: nodes, elements, only, all, */
|
||||
/* equivalent, or unique. */
|
||||
/* option "-list" may be used with nodes, elements */
|
||||
/* all, or no option. */
|
||||
/* Formerly: v */
|
||||
/* Results: */
|
||||
/* For only, equivalent, unique: Return 1 if */
|
||||
/* verified, zero if not. */
|
||||
/* Side Effects: */
|
||||
/* For options elements, nodes, and all without */
|
||||
/* option -list: Write output to log file. */
|
||||
/* For -list options, append list to global */
|
||||
/* variable "lvs_out", if it exists. */
|
||||
/*------------------------------------------------------*/
|
||||
|
||||
int
|
||||
|
|
@ -2333,8 +2367,23 @@ _netcmp_verify(ClientData clientData,
|
|||
enum OptionIdx {
|
||||
NODE_IDX, ELEM_IDX, PROP_IDX, ONLY_IDX, ALL_IDX, EQUIV_IDX, UNIQUE_IDX
|
||||
};
|
||||
char *optstart;
|
||||
int result, index = -1;
|
||||
int automorphisms;
|
||||
int dolist = 0;
|
||||
Tcl_Obj *egood, *ebad, *ngood, *nbad;
|
||||
|
||||
if (objc > 1) {
|
||||
optstart = Tcl_GetString(objv[1]);
|
||||
if (*optstart == '-') optstart++;
|
||||
if (!strcmp(optstart, "list")) {
|
||||
dolist = 1;
|
||||
egood = ngood = NULL;
|
||||
ebad = nbad = NULL;
|
||||
objv++;
|
||||
objc--;
|
||||
}
|
||||
}
|
||||
|
||||
if (objc != 1 && objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
|
|
@ -2365,14 +2414,28 @@ _netcmp_verify(ClientData clientData,
|
|||
if (objc == 1 || index == NODE_IDX || index == ALL_IDX) {
|
||||
if (Debug == TRUE)
|
||||
PrintIllegalNodeClasses(); // Old style
|
||||
else
|
||||
FormatIllegalNodeClasses(); // Side-by-side
|
||||
else {
|
||||
FormatIllegalNodeClasses(); // Side-by-side, to log file
|
||||
if (dolist) {
|
||||
nbad = ListNodeClasses(FALSE); // As Tcl nested list
|
||||
#if 0
|
||||
ngood = ListNodeClasses(TRUE); // As Tcl nested list
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objc == 1 || index == ELEM_IDX || index == ALL_IDX) {
|
||||
if (Debug == TRUE)
|
||||
PrintIllegalElementClasses(); // Old style
|
||||
else
|
||||
FormatIllegalElementClasses(); // Side-by-side
|
||||
else {
|
||||
FormatIllegalElementClasses(); // Side-by-side, to log file
|
||||
if (dolist) {
|
||||
ebad = ListElementClasses(FALSE); // As Tcl nested list
|
||||
#if 0
|
||||
egood = ListElementClasses(TRUE); // As Tcl nested list
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
disable_interrupt();
|
||||
if (index == EQUIV_IDX || index == UNIQUE_IDX)
|
||||
|
|
@ -2403,9 +2466,73 @@ _netcmp_verify(ClientData clientData,
|
|||
Fprintf(stdout, "Property errors were found.\n");
|
||||
}
|
||||
}
|
||||
if ((index == PROP_IDX) && (PropertyErrorDetected != 0)) {
|
||||
PrintPropertyResults();
|
||||
#if 0
|
||||
if (dolist) {
|
||||
ngood = ListNodeClasses(TRUE); // As Tcl nested list
|
||||
egood = ListElementClasses(TRUE); // As Tcl nested list
|
||||
}
|
||||
#endif
|
||||
if ((index == PROP_IDX) && (PropertyErrorDetected != 0)) {
|
||||
PrintPropertyResults(dolist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If "dolist" has been specified, then return the */
|
||||
/* list-formatted output. For "verify nodes" or */
|
||||
/* "verify elements", return the associated list. */
|
||||
/* For "verify" or "verify all", return a nested */
|
||||
/* list of {node list, element list}. */
|
||||
|
||||
if (dolist)
|
||||
{
|
||||
if (objc == 1 || index == NODE_IDX || index == ALL_IDX) {
|
||||
if (nbad == NULL) {
|
||||
Tcl_Obj *n0, *n1;
|
||||
nbad = Tcl_NewListObj(0, NULL);
|
||||
n0 = Tcl_NewStringObj("badnets", -1);
|
||||
n1 = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(netgeninterp, nbad, n0);
|
||||
Tcl_ListObjAppendElement(netgeninterp, nbad, n1);
|
||||
}
|
||||
Tcl_SetVar2Ex(interp, "lvs_out", NULL, nbad,
|
||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||
#if 0
|
||||
if (ngood == NULL) {
|
||||
Tcl_Obj *n0, *n1;
|
||||
ngood = Tcl_NewListObj(0, NULL);
|
||||
n0 = Tcl_NewStringObj("goodnets", -1);
|
||||
n1 = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(netgeninterp, ngood, n0);
|
||||
Tcl_ListObjAppendElement(netgeninterp, ngood, n1);
|
||||
}
|
||||
Tcl_SetVar2Ex(interp, "lvs_out", NULL, ngood,
|
||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||
#endif
|
||||
}
|
||||
if (objc == 1 || index == ELEM_IDX || index == ALL_IDX) {
|
||||
if (ebad == NULL) {
|
||||
Tcl_Obj *e0, *e1;
|
||||
ebad = Tcl_NewListObj(0, NULL);
|
||||
e0 = Tcl_NewStringObj("badelements", -1);
|
||||
e1 = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(netgeninterp, ebad, e0);
|
||||
Tcl_ListObjAppendElement(netgeninterp, ebad, e1);
|
||||
}
|
||||
Tcl_SetVar2Ex(interp, "lvs_out", NULL, ebad,
|
||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||
#if 0
|
||||
if (egood == NULL) {
|
||||
Tcl_Obj *e0, *e1;
|
||||
ebad = Tcl_NewListObj(0, NULL);
|
||||
e0 = Tcl_NewStringObj("goodelements", -1);
|
||||
e1 = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(netgeninterp, egood, e0);
|
||||
Tcl_ListObjAppendElement(netgeninterp, egood, e1);
|
||||
}
|
||||
Tcl_SetVar2Ex(interp, "lvs_out", NULL, egood,
|
||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
|
|
@ -2566,13 +2693,23 @@ _netcmp_equate(ClientData clientData,
|
|||
NODE_IDX, ELEM_IDX, CLASS_IDX, PINS_IDX
|
||||
};
|
||||
int result, index;
|
||||
char *name1 = NULL, *name2 = NULL;
|
||||
char *name1 = NULL, *name2 = NULL, *optstart;
|
||||
struct nlist *tp1, *tp2;
|
||||
struct objlist *ob1, *ob2;
|
||||
int file1, file2;
|
||||
int i, l1, l2, ltest, lent;
|
||||
int i, l1, l2, ltest, lent, dolist;
|
||||
Tcl_Obj *tobj1, *tobj2, *tobj3;
|
||||
|
||||
if (objc > 1) {
|
||||
optstart = Tcl_GetString(objv[1]);
|
||||
if (*optstart == '-') optstart++;
|
||||
if (!strcmp(optstart, "list")) {
|
||||
dolist = 1;
|
||||
objv++;
|
||||
objc--;
|
||||
}
|
||||
}
|
||||
|
||||
if ((objc != 2) && (objc != 4) && (objc != 6)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?nodes|elements|classes|pins? name1 name2");
|
||||
return TCL_ERROR;
|
||||
|
|
@ -2737,7 +2874,8 @@ _netcmp_equate(ClientData clientData,
|
|||
return TCL_OK;
|
||||
}
|
||||
if (tp1 == Circuit1 && tp2 == Circuit2) {
|
||||
if (MatchPins(tp1, tp2)) {
|
||||
int result;
|
||||
if (MatchPins(tp1, tp2, dolist)) {
|
||||
Fprintf(stdout, "Cell pin lists are equivalent.\n");
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
|
||||
}
|
||||
|
|
@ -2748,7 +2886,7 @@ _netcmp_equate(ClientData clientData,
|
|||
}
|
||||
}
|
||||
else {
|
||||
Fprintf(stderr, "Function not yet defined outside of LVS scope.\n");
|
||||
Fprintf(stderr, "Function not defined outside of LVS scope.\n");
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue