Correction from a recent commit; complicated sets of "equiv"
statement in a .ext file require that all aliases of a node name be rehashed after a node merge, or else node loops can occur. Also prevented statements of the form "equiv A A" from being output in the .ext file, as they are useless.
This commit is contained in:
parent
fd4569081e
commit
2532a696e4
|
|
@ -454,6 +454,8 @@ efBuildEquiv(def, nodeName1, nodeName2)
|
||||||
nn1 = (EFNodeName *) HashGetValue(he1);
|
nn1 = (EFNodeName *) HashGetValue(he1);
|
||||||
nn2 = (EFNodeName *) HashGetValue(he2);
|
nn2 = (EFNodeName *) HashGetValue(he2);
|
||||||
|
|
||||||
|
if (nn1 == nn2) return; /* These nodes already merged */
|
||||||
|
|
||||||
if (nn2 == (EFNodeName *) NULL)
|
if (nn2 == (EFNodeName *) NULL)
|
||||||
{
|
{
|
||||||
/* Create nodeName1 if it doesn't exist */
|
/* Create nodeName1 if it doesn't exist */
|
||||||
|
|
@ -482,6 +484,10 @@ efBuildEquiv(def, nodeName1, nodeName2)
|
||||||
return; /* Repeated "equiv" statement */
|
return; /* Repeated "equiv" statement */
|
||||||
if (nn1->efnn_node != nn2->efnn_node)
|
if (nn1->efnn_node != nn2->efnn_node)
|
||||||
{
|
{
|
||||||
|
struct efnode *node1 = nn1->efnn_node;
|
||||||
|
struct efnode *node2 = nn2->efnn_node;
|
||||||
|
HashSearch hs;
|
||||||
|
|
||||||
if (efWarn)
|
if (efWarn)
|
||||||
efReadError("Merged nodes %s and %s\n", nodeName1, nodeName2);
|
efReadError("Merged nodes %s and %s\n", nodeName1, nodeName2);
|
||||||
efNodeMerge(&nn1->efnn_node, &nn2->efnn_node);
|
efNodeMerge(&nn1->efnn_node, &nn2->efnn_node);
|
||||||
|
|
@ -489,17 +495,23 @@ efBuildEquiv(def, nodeName1, nodeName2)
|
||||||
else if (nn2->efnn_port > 0) nn1->efnn_port = nn2->efnn_port;
|
else if (nn2->efnn_port > 0) nn1->efnn_port = nn2->efnn_port;
|
||||||
|
|
||||||
/* If a node has been merged away, make sure that its name */
|
/* If a node has been merged away, make sure that its name */
|
||||||
/* points to the merged name's hash. */
|
/* and all aliases point to the merged name's hash. */
|
||||||
|
|
||||||
if (nn1->efnn_node == NULL)
|
if (nn1->efnn_node == NULL)
|
||||||
{
|
{
|
||||||
HashSetValue(he1, (char *)nn2);
|
|
||||||
nn2->efnn_refc += nn1->efnn_refc + 1;
|
nn2->efnn_refc += nn1->efnn_refc + 1;
|
||||||
|
HashStartSearch(&hs);
|
||||||
|
while (he1 = HashNext(&def->def_nodes, &hs))
|
||||||
|
if ((EFNodeName *)HashGetValue(he1) == nn1)
|
||||||
|
HashSetValue(he1, (char *)nn2);
|
||||||
}
|
}
|
||||||
else if (nn2->efnn_node == NULL)
|
else if (nn2->efnn_node == NULL)
|
||||||
{
|
{
|
||||||
HashSetValue(he2, (char *)nn1);
|
|
||||||
nn1->efnn_refc += nn2->efnn_refc + 1;
|
nn1->efnn_refc += nn2->efnn_refc + 1;
|
||||||
|
HashStartSearch(&hs);
|
||||||
|
while (he2 = HashNext(&def->def_nodes, &hs))
|
||||||
|
if ((EFNodeName *)HashGetValue(he2) == nn2)
|
||||||
|
HashSetValue(he2, (char *)nn1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -727,12 +727,16 @@ extOutputNodes(nodeList, outFile)
|
||||||
fprintf(outFile, "\"\n");
|
fprintf(outFile, "\"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output the alternate names for the node */
|
/* Output the alternate names for the node. Avoid generating */
|
||||||
|
/* unnecessary "equiv A A" entries for labels on disconnected */
|
||||||
|
/* nets. */
|
||||||
|
|
||||||
for (ll = reg->nreg_labels; ll; ll = ll->ll_next)
|
for (ll = reg->nreg_labels; ll; ll = ll->ll_next)
|
||||||
if (ll->ll_label->lab_text == text)
|
if (ll->ll_label->lab_text == text)
|
||||||
{
|
{
|
||||||
for (ll = ll->ll_next; ll; ll = ll->ll_next)
|
for (ll = ll->ll_next; ll; ll = ll->ll_next)
|
||||||
if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME))
|
if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME))
|
||||||
|
if (strcmp(text, ll->ll_label->lab_text))
|
||||||
fprintf(outFile, "equiv \"%s\" \"%s\"\n",
|
fprintf(outFile, "equiv \"%s\" \"%s\"\n",
|
||||||
text, ll->ll_label->lab_text);
|
text, ll->ll_label->lab_text);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue