diff --git a/VERSION b/VERSION index caf43a00..d29f3647 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.450 +8.3.451 diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 85bd1cb4..684f2895 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -162,7 +162,50 @@ efBuildNode(def, isSubsnode, isDevSubsnode, isExtNode, nodeName, nodeCap, int tnew = 0; he = HashFind(&def->def_nodes, nodeName); - if (newname = (EFNodeName *) HashGetValue(he)) + newname = (EFNodeName *)HashGetValue(he); + + if (newname && (def->def_kills != NULL)) + { + HashEntry *hek; + EFNodeName *nn, *knn, *nodeAlias, *lastAlias; + + /* Watch for nodes that are aliases of the node that was most + * recently killed. This can occur in .res.ext files where an + * equivalent node name (alias) is used as one of the node + * points. It must be regenerated as its own node and removed + * from the name list of the killed node. + */ + hek = HashLookOnly(&def->def_nodes, EFHNToStr(def->def_kills->kill_name)); + if (hek != NULL) + { + knn = (EFNodeName *) HashGetValue(hek); + if ((knn != NULL) && (knn->efnn_node == newname->efnn_node)) + { + /* Remove alias from killed node's name list */ + lastAlias = NULL; + for (nodeAlias = knn->efnn_node->efnode_name; nodeAlias != NULL; + nodeAlias = nodeAlias->efnn_next) + { + if (!strcmp(EFHNToStr(nodeAlias->efnn_hier), nodeName)) + { + if (lastAlias == NULL) + knn->efnn_node->efnode_name = nodeAlias->efnn_next; + else + lastAlias->efnn_next = nodeAlias->efnn_next; + EFHNFree(nodeAlias->efnn_hier, (HierName *)NULL, HN_ALLOC); + freeMagic(nodeAlias); + break; + } + lastAlias = nodeAlias; + } + + /* Force name to be made into a new node */ + newname = (EFNodeName *)NULL; + } + } + } + + if (newname) { if (efWarn) efReadError("Warning: duplicate node name %s\n", nodeName); diff --git a/resis/ResRex.c b/resis/ResRex.c index b0804f45..81726178 100644 --- a/resis/ResRex.c +++ b/resis/ResRex.c @@ -1449,8 +1449,6 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) } layoutDev->rd_fet_drain = (resNode *)NULL; if (source->rn_name != NULL) resNodeNum--; - ResFixDevName(newname, SOURCE, simDev, source); - source->rn_name = simDev->source->name; } else { @@ -1459,9 +1457,9 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) resNodeNum--; notdecremented = FALSE; } - ResFixDevName(newname, SOURCE, simDev, source); - source->rn_name = simDev->source->name; } + ResFixDevName(newname, SOURCE, simDev, source); + source->rn_name = simDev->source->name; } else @@ -1472,26 +1470,36 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) } else if (simDev->drain == simNode) { - if ((source = layoutDev->rd_fet_source) != NULL) + /* Check for devices with only one terminal. If it was cast as source, */ + /* then swap it with the drain so that the code below handles it */ + /* correctly. */ + + if (layoutDev->rd_fet_drain == NULL && layoutDev->rd_fet_source != NULL) { - if ((drain = layoutDev->rd_fet_drain) != NULL) + layoutDev->rd_fet_drain = layoutDev->rd_fet_source; + layoutDev->rd_fet_source = (struct resnode *)NULL; + } + + if ((drain = layoutDev->rd_fet_drain) != NULL) + { + if ((source = layoutDev->rd_fet_source) != NULL) { if (drain != source) { - if (drain->rn_why & ORIGIN) + if (source->rn_why & ORIGIN) { - ResMergeNodes(drain, source, &ResNodeQueue, - &ResNodeList); - ResDoneWithNode(drain); - source = drain; - } - else - { - ResMergeNodes(source, drain, &ResNodeQueue, + ResMergeNodes(source, drain, &ResNodeQueue, &ResNodeList); ResDoneWithNode(source); drain = source; } + else + { + ResMergeNodes(drain, source, &ResNodeQueue, + &ResNodeList); + ResDoneWithNode(drain); + source = drain; + } } layoutDev->rd_fet_source = (resNode *) NULL; if (drain->rn_name != NULL) @@ -1499,19 +1507,17 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename) resNodeNum--; notdecremented = FALSE; } - ResFixDevName(newname, DRAIN, simDev, drain); - drain->rn_name = simDev->drain->name; } else { - if (source->rn_name != NULL && notdecremented) + if (drain->rn_name != NULL && notdecremented) { resNodeNum--; notdecremented = FALSE; } - ResFixDevName(newname, DRAIN, simDev, source); - source->rn_name = simDev->drain->name; } + ResFixDevName(newname, DRAIN, simDev, drain); + drain->rn_name = simDev->drain->name; } else TxError("Missing terminal connection of device at (%d %d) on net %s\n",