diff --git a/VERSION b/VERSION index 6cf21ce..4595a7f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.245 +1.5.246 diff --git a/base/netcmp.c b/base/netcmp.c index 76aedcc..888382c 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -162,6 +162,10 @@ int right_col_end = 87; /* if TRUE, always partition ALL classes */ int ExhaustiveSubdivision = 0; +/* if TRUE, enforce that networks (e.g., resistor) must match */ +/* topologically, as opposed to just matching numerically. */ +int ExactTopology = 0; + #ifdef TEST static void PrintElement_List(struct Element *E) { @@ -4932,13 +4936,17 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series, } } if (kl == NULL) { - /* Prevent setting both M > 1 and S > 1 in any one */ - /* device, as it is ambiguous. */ + /* Setting both M > 1 and S > 1 is topologically */ + /* ambiguous. If global option ExactTopology is */ + /* enabled, then this will cause a failure. */ + /* Otherwise, it is allowed. */ - if ((*matchfunc)(vl->key, other)) { - if (vl->type == PROP_INTEGER) - if (vl->value.ival > 1) - fail = 1; + if (ExactTopology) { + if ((*matchfunc)(vl->key, other)) { + if (vl->type == PROP_INTEGER) + if (vl->value.ival > 1) + fail = 1; + } } } else if (kl != NULL) { diff --git a/base/netcmp.h b/base/netcmp.h index 35ff986..72dd03c 100644 --- a/base/netcmp.h +++ b/base/netcmp.h @@ -7,6 +7,7 @@ extern struct nlist *Circuit1; extern struct nlist *Circuit2; extern int ExhaustiveSubdivision; +extern int ExactTopology; extern int left_col_end; extern int right_col_end; diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index cb81d17..90b415a 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -3378,6 +3378,7 @@ _netcmp_equate(ClientData clientData, /* remove --- delete existing property */ /* tolerance --- set property tolerance */ /* associate --- associate property with a pin */ +/* topology --- set exact/relaxed matching */ /* merge --- (deprecated) */ /* or */ /* netgen::property default */ @@ -3416,11 +3417,11 @@ _netcmp_property(ClientData clientData, char *options[] = { "add", "create", "remove", "delete", "tolerance", "merge", "serial", - "series", "parallel", "associate", NULL + "series", "parallel", "associate", "topology", NULL }; enum OptionIdx { ADD_IDX, CREATE_IDX, REMOVE_IDX, DELETE_IDX, TOLERANCE_IDX, MERGE_IDX, - SERIAL_IDX, SERIES_IDX, PARALLEL_IDX, ASSOCIATE_IDX + SERIAL_IDX, SERIES_IDX, PARALLEL_IDX, ASSOCIATE_IDX, TOPOLOGY_IDX }; int result, index, idx2; @@ -3465,6 +3466,10 @@ _netcmp_property(ClientData clientData, return TCL_ERROR; } + char *topo[] = { + "strict", "relaxed", NULL + }; + /* Check for special command "property default" */ if ((objc == 2) && (!strcmp(Tcl_GetString(objv[1]), "default"))) { @@ -3550,6 +3555,36 @@ _netcmp_property(ClientData clientData, } return TCL_OK; } + else if ((objc > 1) && (!strcmp(Tcl_GetString(objv[1]), "topology"))) { + if (objc == 2) { + if (ExactTopology) + Tcl_SetResult(interp, "Strict topology property matching.", + NULL); + else + Tcl_SetResult(interp, "Relaxed topology property matching.", + NULL); + } + else if (objc == 3) { + if (Tcl_GetIndexFromObj(interp, objv[2], + (CONST84 char **)topo, + "topology", 0, &idx2) == TCL_OK) { + if (idx2 == 0) + ExactTopology = TRUE; + else if (idx2 == 1) + ExactTopology = FALSE; + else { + Tcl_SetResult(interp, "Topology matching type must be " + "'strict' or 'relaxed'.", NULL); + return TCL_ERROR; + } + } + } + else { + Tcl_WrongNumArgs(interp, 1, objv, "strict|relaxed"); + return TCL_ERROR; + } + return TCL_OK; + } result = CommonParseCell(interp, objv[1], &tp, &fnum); if (result != TCL_OK) return result; @@ -3965,6 +4000,7 @@ _netcmp_property(ClientData clientData, } } break; + } } return TCL_OK;