magic/extflat/EFflat.c

1226 lines
37 KiB
C
Raw Normal View History

/*
* EFflat.c -
*
* Procedures to flatten the hierarchical description built
* by efReadDef().
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/extflat/EFflat.c,v 1.5 2010/12/16 18:59:03 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "utils/magic.h"
#include "utils/geometry.h"
#include "utils/geofast.h"
#include "utils/hash.h"
#include "utils/malloc.h"
#include "utils/utils.h"
#include "extflat/extflat.h"
#include "extflat/EFint.h"
/* C99 compat */
#include "textio/textio.h"
/* Initial size of the hash table of all flattened node names */
#define INITFLATSIZE 1024
/* Hash table containing all flattened capacitors */
HashTable efCapHashTable;
/* Hash table containing all flattened distances */
HashTable efDistHashTable;
/* Head of circular list of all flattened nodes */
EFNode efNodeList;
/* Root of the tree being flattened */
Def *efFlatRootDef;
Use efFlatRootUse;
HierContext efFlatContext;
/* Forward declarations */
int efFlatSingleCap(HierContext *hc, char *name1, char *name2, Connection *conn);
void efFlatGlob(void);
int efFlatGlobHash(HierName *);
bool efFlatGlobCmp(HierName *, HierName *);
char *efFlatGlobCopy(HierName *);
void efFlatGlobError(EFNodeName *nameGlob, EFNodeName *nameFlat);
int efAddNodes(HierContext *hc, bool stdcell);
int efAddConns(HierContext *hc, bool doWarn);
int efAddOneConn(HierContext *hc, char *name1, char *name2, Connection *conn, bool doWarn);
/* Flags passed to efFlatNode() */
#define FLATNODE_STDCELL 0x01
#define FLATNODE_DOWARN 0x02
#define FLATNODE_NOABSTRACT 0x04
/*
* ----------------------------------------------------------------------------
*
* EFFlatBuild --
*
* First pass of flattening a circuit.
* Builds up the flattened tables of nodes, capacitors, etc, depending
* on the bits contained in flags: EF_FLATNODES causes the node table
* to be built, EF_FLATCAPS the internodal capacitor table (implies
* EF_FLATNODES), and EF_FLATDISTS the distance table.
*
* Callers who want various pieces of information should call
* the relevant EFVisit procedures (e.g., EFVisitDevs(), EFVisitCaps(),
* EFVisitNodes(), etc).
*
* Results:
* None.
*
* Side effects:
* Allocates lots of memory.
* Be certain to call EFFlatDone() when this memory is
* no longer needed.
*
* ----------------------------------------------------------------------------
*/
void
EFFlatBuild(name, flags)
char *name; /* Name of root def being flattened */
int flags; /* Say what to flatten; see above */
{
efFlatRootDef = efDefLook(name);
if (efHNStats) efHNPrintSizes("before building flattened table");
/* Keyed by a full HierName */
HashInitClient(&efNodeHashTable, INITFLATSIZE, HT_CLIENTKEYS,
efHNCompare, (char *(*)()) NULL, efHNHash, (int (*)()) NULL);
/* Keyed by a pair of HierNames */
HashInitClient(&efDistHashTable, INITFLATSIZE, HT_CLIENTKEYS,
efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill);
/* Keyed by pairs of EFNode pointers (i.e., EFCoupleKeys) */
HashInit(&efCapHashTable, INITFLATSIZE, HashSize(sizeof (EFCoupleKey)));
/* Keyed by a string and a HierName */
HashInitClient(&efHNUseHashTable, INITFLATSIZE, HT_CLIENTKEYS,
efHNUseCompare, (char *(*)()) NULL, efHNUseHash, (int (*)()) NULL);
/* Circular list of all nodes contains no elements initially */
efNodeList.efnode_next = (EFNodeHdr *) &efNodeList;
efNodeList.efnode_prev = (EFNodeHdr *) &efNodeList;
efFlatContext.hc_hierName = (HierName *) NULL;
efFlatContext.hc_use = &efFlatRootUse;
efFlatContext.hc_trans = GeoIdentityTransform;
efFlatContext.hc_x = efFlatContext.hc_y = 0;
efFlatRootUse.use_def = efFlatRootDef;
if (flags & EF_FLATNODES)
{
int flatnodeflags = 0;
if (flags & EF_WARNABSTRACT)
flatnodeflags = FLATNODE_NOABSTRACT;
if (flags & EF_NOFLATSUBCKT)
{
/* The top cell must always have the DEF_SUBCIRCUIT flag cleared */
efFlatRootDef->def_flags &= ~DEF_SUBCIRCUIT;
efFlatNodesStdCell(&efFlatContext);
}
else
{
flatnodeflags |= FLATNODE_DOWARN; /* No FLATNODE_STDCELL flag */
efFlatNodes(&efFlatContext, INT2CD(flatnodeflags));
}
efFlatKills(&efFlatContext);
if (!(flags & EF_NONAMEMERGE))
efFlatGlob();
}
/* Must happen after kill processing */
if (flags & EF_FLATCAPS)
efFlatCaps(&efFlatContext);
/* Distances are independent of kill processing */
if (flags & EF_FLATDISTS)
efFlatDists(&efFlatContext);
if (efHNStats) efHNPrintSizes("after building flattened table");
return;
}
/*----------------------------------------------------------------------*/
/* EFFlatBuildOneLevel -- */
/* */
/* EFFlatBuild for a single hierarchical level. Note, however that */
/* where subcircuits have no extracted components, the hierarchy of */
/* the subcircuit will be traversed and the subcircuit merged into */
/* the root being flattened. */
/* */
/* This routine used for hierarchical extraction. */
/*----------------------------------------------------------------------*/
HierContext *
EFFlatBuildOneLevel(def, flags)
Def *def; /* root def being flattened */
int flags;
{
int usecount, savecount;
Use *use;
int efFlatNodesDeviceless(); /* Forward declaration */
int efFlatCapsDeviceless(); /* Forward declaration */
int flatnodeflags;
efFlatRootDef = def;
/* Keyed by a full HierName */
HashInitClient(&efNodeHashTable, INITFLATSIZE, HT_CLIENTKEYS,
efHNCompare, (char *(*)()) NULL, efHNHash, (int (*)()) NULL);
/* Keyed by a pair of HierNames */
HashInitClient(&efDistHashTable, INITFLATSIZE, HT_CLIENTKEYS,
efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill);
/* Keyed by pairs of EFNode pointers (i.e., EFCoupleKeys) */
HashInit(&efCapHashTable, INITFLATSIZE, HashSize(sizeof (EFCoupleKey)));
/* Keyed by a string and a HierName */
HashInitClient(&efHNUseHashTable, INITFLATSIZE, HT_CLIENTKEYS,
efHNUseCompare, (char *(*)()) NULL, efHNUseHash, (int (*)()) NULL);
/* Circular list of all nodes contains no elements initially */
efNodeList.efnode_next = (EFNodeHdr *) &efNodeList;
efNodeList.efnode_prev = (EFNodeHdr *) &efNodeList;
efFlatContext.hc_hierName = (HierName *) NULL;
efFlatContext.hc_use = &efFlatRootUse;
efFlatContext.hc_trans = GeoIdentityTransform;
efFlatContext.hc_x = efFlatContext.hc_y = 0;
efFlatRootUse.use_def = efFlatRootDef;
/* Record all nodes down the hierarchy from here */
flatnodeflags = 0; /* No FLATNODE_DOWARN */
efFlatNodes(&efFlatContext, INT2CD(flatnodeflags));
/* Expand all subcells that contain connectivity information but */
/* no active devices (including those in subcells). */
usecount = HashGetNumEntries(&efFlatRootUse.use_def->def_uses);
/* Recursively flatten uses that have no active devices */
if (usecount > 0)
efHierSrUses(&efFlatContext, efFlatNodesDeviceless, (ClientData)&usecount);
if ((usecount == 0) && (HashGetNumEntries(&efFlatRootUse.use_def->def_devs) == 0))
efFlatRootUse.use_def->def_flags |= DEF_NODEVICES;
efFlatKills(&efFlatContext);
if (!(flags & EF_NONAMEMERGE))
efFlatGlob();
if (flags & EF_FLATCAPS)
efFlatCapsDeviceless(&efFlatContext);
if (flags & EF_FLATDISTS)
efFlatDists(&efFlatContext);
return &efFlatContext;
}
/*
* ----------------------------------------------------------------------------
*
* EFFlatDone --
*
* Cleanup by removing all memory used by the flattened circuit
* representation. For use of func(), see efFreeNodeList() in EFbuild.c.
*
* Results:
* None.
*
* Side effects:
* Frees lots of memory.
*
* ----------------------------------------------------------------------------
*/
void
EFFlatDone(func)
int (*func)();
{
#ifdef MALLOCTRACE
/* Hash table statistics */
TxPrintf("\n\nStatistics for node hash table:\n");
HashStats(&efNodeHashTable);
#endif /* MALLOCTRACE */
/* Free temporary storage */
efFreeNodeTable(&efNodeHashTable);
efFreeNodeList(&efNodeList, func);
HashFreeKill(&efCapHashTable);
HashKill(&efNodeHashTable);
HashKill(&efDistHashTable);
HashKill(&efHNUseHashTable);
return;
}
/*
* ----------------------------------------------------------------------------
*
* efFlatNodes --
*
* Recursive procedure to flatten the nodes in hc->hc_use->use_def,
* using a depth-first post-order traversal of the hierarchy.
*
* Algorithm:
* We first recursivly call efFlatNodes for all of our children uses.
* This adds their node names to the global node table. Next we add
* our own nodes to the table. Some nodes will have to be merged
* by connections made in this def, or at least will require adjustments
* to their resistance or capacitance. We walk down the connection
* list hc->hc_use->use_def->def_conns to do this merging. Whenever
* two nodes merge, the EFNodeName list for the resulting node is
* rearranged to begin with the highest precedence name from the lists
* for the two nodes being combined. See efNodeMerge for a discussion
* of precedence.
*
* Results:
* Returns 0 to keep efHierSrUses going.
*
* Side effects:
* Adds node names to the table of flattened node names efNodeHashTable.
* May merge nodes from the list efNodeList as per the connection
* list hc->hc_use->use_def->def_conns.
*
* Note:
* stdcell = TRUE is only used when writing DEF files.
*
* ----------------------------------------------------------------------------
*/
int
efFlatNodes(hc, clientData)
HierContext *hc;
ClientData clientData;
{
int flags = (int)CD2INT(clientData);
bool stdcell = (flags & FLATNODE_STDCELL) ? TRUE : FALSE;
bool doWarn = (flags & FLATNODE_DOWARN) ? TRUE : FALSE;
if (flags & FLATNODE_NOABSTRACT)
{
Def *def = hc->hc_use->use_def;
if (def->def_flags & DEF_ABSTRACT)
TxError("Error: Cell %s was extracted as an abstract view.\n",
def->def_name);
}
(void) efHierSrUses(hc, efFlatNodes, clientData);
/* Add all our own nodes to the table */
efAddNodes(hc, stdcell);
/* Process our own connections and adjustments */
(void) efAddConns(hc, doWarn);
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* efFlatNodesStdCell --
*
* Recursive procedure to flatten the nodes in hc->hc_use->use_def,
* using a depth-first post-order traversal of the hierarchy. We stop
* whenever we reach a subcircuit definition, only enumerating its ports.
*
* Algorithm:
* We first recursivly call efFlatNodes for all of our children uses.
* This adds their node names to the global node table. Next we add
* our own nodes to the table. Some nodes will have to be merged
* by connections made in this def, or at least will require adjustments
* to their resistance or capacitance. We walk down the connection
* list hc->hc_use->use_def->def_conns to do this merging. Whenever
* two nodes merge, the EFNodeName list for the resulting node is
* rearranged to begin with the highest precedence name from the lists
* for the two nodes being combined. See efNodeMerge for a discussion
* of precedence.
*
* Results:
* Returns 0 to keep efHierSrUses going.
*
* Side effects:
* Adds node names to the table of flattened node names efNodeHashTable.
* May merge nodes from the list efNodeList as per the connection
* list hc->hc_use->use_def->def_conns.
*
* ----------------------------------------------------------------------------
*/
int
efFlatNodesStdCell(hc)
HierContext *hc;
{
if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT))
{
/* Recursively flatten each use, except in defined subcircuits */
(void) efHierSrUses(hc, efFlatNodesStdCell, (ClientData) NULL);
}
/* Add all our own nodes to the table */
efAddNodes(hc, TRUE);
/* Process our own connections and adjustments */
if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT))
(void) efAddConns(hc, TRUE);
return (0);
}
int
efFlatNodesDeviceless(hc, cdata)
HierContext *hc;
ClientData cdata;
{
int *usecount = (int *)cdata;
int newcount;
Use *use;
newcount = HashGetNumEntries(&hc->hc_use->use_def->def_uses);
/* Recursively flatten uses that have no active devices */
if (newcount > 0)
efHierSrUses(hc, efFlatNodesDeviceless, (ClientData)&newcount);
if ((HashGetNumEntries(&hc->hc_use->use_def->def_devs) == 0) && (newcount == 0))
{
/* Add all our own nodes to the table */
efAddNodes(hc, TRUE);
/* Process our own connections and adjustments */
efAddConns(hc, TRUE);
/* Mark this definition as having no devices, so it will not be visited */
hc->hc_use->use_def->def_flags |= DEF_NODEVICES;
/* If this definition has no devices but has ports, then it is treated */
/* as a black-box device, so don't decrement the use count of the */
/* parent. Alternately, devices flagged "abstract" or "primitive" are */
/* automatically treated as black-box devices. */
if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT))
if (!(hc->hc_use->use_def->def_flags & (DEF_ABSTRACT | DEF_PRIMITIVE)))
(*usecount)--;
}
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* efAddNodes --
*
* Add all the nodes defined by the def 'hc->hc_use->use_def' to the
* global symbol table. Each global name is prefixed by the hierarchical
* name component hc->hc_hierName. If "stdcell" is TRUE, we ONLY add nodes
* that are defined ports. Otherwise, we add all nodes.
*
* Results:
* None.
*
* Side effects:
* Adds node names to the table of flattened node names efNodeHashTable.
*
* ----------------------------------------------------------------------------
*/
int
efAddNodes(
HierContext *hc,
bool stdcell)
{
Def *def = hc->hc_use->use_def;
EFNodeName *nn, *newname, *oldname;
EFNode *node, *newnode;
EFAttr *ap, *newap;
LinkedRect *lr, *newlr;
HierName *hierName;
int size, asize;
HashEntry *he;
bool is_subcircuit = (def->def_flags & DEF_SUBCIRCUIT) ? TRUE : FALSE;
size = sizeof (EFNode) + (efNumResistClasses-1) * sizeof (EFPerimArea);
for (node = (EFNode *) def->def_firstn.efnode_next;
node != &def->def_firstn;
node = (EFNode *) node->efnode_next)
{
/* In subcircuits, only enumerate the ports */
if (stdcell && is_subcircuit && !(node->efnode_flags & EF_PORT))
continue;
newnode = (EFNode *) mallocMagic((unsigned)(size));
newnode->efnode_attrs = (EFAttr *) NULL;
for (ap = node->efnode_attrs; ap; ap = ap->efa_next)
{
asize = ATTRSIZE(strlen(ap->efa_text));
newap = (EFAttr *) mallocMagic((unsigned)(asize));
(void) strcpy(newap->efa_text, ap->efa_text);
GeoTransRect(&hc->hc_trans, &ap->efa_loc, &newap->efa_loc);
newap->efa_type = ap->efa_type;
newap->efa_next = newnode->efnode_attrs;
newnode->efnode_attrs = newap;
}
newnode->efnode_disjoint = (LinkedRect *)NULL;
for (lr = node->efnode_disjoint; lr; lr = lr->r_next)
{
newlr = (LinkedRect *)mallocMagic(sizeof(LinkedRect));
newlr->r_r = lr->r_r;
newlr->r_type = lr->r_type;
newlr->r_next = newnode->efnode_disjoint;
newnode->efnode_disjoint = newlr;
}
// If called with "hierarchy on", all local node caps and adjustments
// have been output and should be ignored.
newnode->efnode_cap = (!stdcell) ? node->efnode_cap : (EFCapValue)0.0;
newnode->efnode_client = (ClientData) NULL;
newnode->efnode_flags = node->efnode_flags;
newnode->efnode_type = node->efnode_type;
newnode->efnode_num = 1;
if (!stdcell)
bcopy((char *) node->efnode_pa, (char *) newnode->efnode_pa,
efNumResistClasses * sizeof (EFPerimArea));
else
bzero((char *) newnode->efnode_pa,
efNumResistClasses * sizeof (EFPerimArea));
GeoTransRect(&hc->hc_trans, &node->efnode_loc, &newnode->efnode_loc);
/* Add each name for this node to the hash table */
newnode->efnode_name = (EFNodeName *) NULL;
/* Prepend to global node list */
newnode->efnode_next = efNodeList.efnode_next;
newnode->efnode_prev = (EFNodeHdr *) &efNodeList;
efNodeList.efnode_next->efnhdr_prev = (EFNodeHdr *) newnode;
efNodeList.efnode_next = (EFNodeHdr *) newnode;
for (nn = node->efnode_name; nn; nn = nn->efnn_next)
{
/*
* Construct the full hierarchical name of this node.
* The path down to this point is given by hc->hc_hierName,
* to which nn->efnn_hier is "appended". Exception: nodes
* marked with EF_DEVTERM (fet substrate nodes used before
* declared, so intended to refer to default global names)
* are added as global nodes.
*/
if (node->efnode_flags & EF_DEVTERM) hierName = nn->efnn_hier;
else hierName = EFHNConcat(hc->hc_hierName, nn->efnn_hier);
he = HashFind(&efNodeHashTable, (char *) hierName);
/*
* The name should only have been in the hash table already
* if the node was marked with EF_DEVTERM as described above.
*/
38 x warning: suggest parentheses around assignment used as truth value EFdef.c:110:12: warning: suggest parentheses around assignment used as truth value EFdef.c:154:12: warning: suggest parentheses around assignment used as truth value EFdef.c:167:12: warning: suggest parentheses around assignment used as truth value EFflat.c:546:17: warning: suggest parentheses around assignment used as truth value EFflat.c:798:12: warning: suggest parentheses around assignment used as truth value EFflat.c:930:13: warning: suggest parentheses around assignment used as truth value EFflat.c:1152:12: warning: suggest parentheses around assignment used as truth value EFflat.c:1157:13: warning: suggest parentheses around assignment used as truth value EFhier.c:84:12: warning: suggest parentheses around assignment used as truth value EFhier.c:261:12: warning: suggest parentheses around assignment used as truth value EFhier.c:489:12: warning: suggest parentheses around assignment used as truth value EFhier.c:682:12: warning: suggest parentheses around assignment used as truth value EFname.c:325:12: warning: suggest parentheses around assignment used as truth value EFname.c:584:13: warning: suggest parentheses around assignment used as truth value EFname.c:632:16: warning: suggest parentheses around assignment used as truth value EFname.c:765:16: warning: suggest parentheses around assignment used as truth value EFname.c:977:12: warning: suggest parentheses around assignment used as truth value EFsym.c:113:13: warning: suggest parentheses around assignment used as truth value EFsym.c:164:9: warning: suggest parentheses around assignment used as truth value EFvisit.c:322:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:627:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:881:16: warning: suggest parentheses around assignment used as truth value EFvisit.c:917:12: warning: suggest parentheses around assignment used as truth value grTk1.c:1325:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1342:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1757:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1766:9: warning: suggest parentheses around assignment used as truth value grTk5.c:177:12: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1095:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1111:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1542:13: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1551:13: warning: suggest parentheses around assignment used as truth value grTOGL5.c:201:12: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1093:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1109:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1493:21: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1502:21: warning: suggest parentheses around assignment used as truth value grTCairo5.c:202:16: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:20:32 +02:00
if ((oldname = (EFNodeName *) HashGetValue(he)))
{
if (hierName != nn->efnn_hier)
EFHNFree(hierName, hc->hc_hierName, HN_CONCAT);
if (oldname->efnn_node != newnode)
efNodeMerge(&oldname->efnn_node, &newnode);
newnode = oldname->efnn_node;
continue;
}
/*
* We only guarantee that the first name for the node remains
* first (since the first name is the "canonical" name for the
* node). The order of the remaining names will be reversed.
*/
newname = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName)));
HashSetValue(he, (char *) newname);
newname->efnn_node = newnode;
newname->efnn_hier = hierName;
newname->efnn_port = -1;
newname->efnn_refc = 0;
if (newnode->efnode_name)
{
newname->efnn_next = newnode->efnode_name->efnn_next;
newnode->efnode_name->efnn_next = newname;
}
else
{
newname->efnn_next = (EFNodeName *) NULL;
newnode->efnode_name = newname;
}
}
}
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* efAddConns --
*
* Make all the connections for a given def. This may cause previously
* distinct nodes in the flat table to merge.
*
* Results:
* Returns 0
*
* Side effects:
* May merge nodes from the list efNodeList as per the connection
* list hc->hc_use->use_def->def_conns.
*
* ----------------------------------------------------------------------------
*/
int
efAddConns(
HierContext *hc,
bool doWarn)
{
Connection *conn;
if (efWatchNodes)
TxPrintf("Processing %s (%s)\n",
EFHNToStr(hc->hc_hierName),
hc->hc_use->use_def->def_name);
for (conn = hc->hc_use->use_def->def_conns; conn; conn = conn->conn_next)
{
/* Special case for speed when no array info is present */
if (conn->conn_1.cn_nsubs == 0)
efAddOneConn(hc, conn->conn_name1, conn->conn_name2, conn, doWarn);
else
efHierSrArray(hc, conn, efAddOneConn, INT2CD(doWarn));
}
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* efAddOneConn --
*
* Do the work of adding a single connection. The names of the nodes
* to be connected are 'name1' and 'name2' (note that these are regular
* strings, not HierNames). The resistance of the merged node is to be
* adjusted by 'deltaR' and its capacitance by 'deltaC'. If 'name2' is
* NULL, we just adjust the R and C of the node 'name1'.
*
* Results:
* Returns 0
*
* Side effects:
* May merge nodes from the list efNodeList.
*
* ----------------------------------------------------------------------------
*/
int
efAddOneConn(
HierContext *hc,
char *name1, /* These are strings, not HierNames */
char *name2,
Connection *conn,
bool doWarn)
{
HashEntry *he1, *he2;
EFNode *node, *newnode;
int n;
he1 = EFHNLook(hc->hc_hierName, name1, (doWarn) ? "connect(1)" : NULL);
if (he1 == NULL)
return 0;
/* Adjust the resistance and capacitance of its corresponding node */
node = ((EFNodeName *) HashGetValue(he1))->efnn_node;
node->efnode_cap += conn->conn_cap;
for (n = 0; n < efNumResistClasses; n++)
{
node->efnode_pa[n].pa_area += conn->conn_pa[n].pa_area;
node->efnode_pa[n].pa_perim += conn->conn_pa[n].pa_perim;
}
/* Merge this node with conn_name2 if one was specified */
if (name2)
{
he2 = EFHNLook(hc->hc_hierName, name2, (doWarn) ? "connect(2)" : NULL);
if (he2 == NULL)
return 0;
newnode = ((EFNodeName *) HashGetValue(he2))->efnn_node;
if (node != newnode)
efNodeMerge(&node, &newnode);
}
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* efFlatGlob --
*
* This procedure checks to ensure that all occurrences of the same global
* name are connected. It also adds the reduced form of the global name
* (i.e., the global name with no pathname prefix) to the hash table
* efNodeHashTable, making this the preferred name of the global node.
*
* Algorithm:
* Scan through the node table looking for globals. Add each
* global to a global name table keyed by just the first component
* of the HierName. The value of the entry in this table is set
* initially to the EFNodeName for the first occurrence of the
* global node. If another occurrence of the global name is
* found whose EFNode differs from this one's, it's an error.
* However, we still merge all the pieces of a global node
* into a single one at the end.
*
* Results:
* None.
*
* Side effects:
* See above.
*
* ----------------------------------------------------------------------------
*/
void
efFlatGlob(void)
{
EFNodeName *nameFlat, *nameGlob;
EFNode *nodeFlat, *nodeGlob;
HashEntry *heFlat, *heGlob;
HierName *hnFlat, *hnGlob;
HashTable globalTable;
HashSearch hs;
HashInitClient(&globalTable, INITFLATSIZE, HT_CLIENTKEYS,
efFlatGlobCmp, efFlatGlobCopy, efFlatGlobHash, (int (*)()) NULL);
/*
* The following loop examines each global name (the last component of
* each flat HierName that ends in the global symbol '!'), using the
* hash table globalTable to keep track of how many times each global
* name has been seen. Each global name should be seen exactly once.
* The only exceptions are fet substrate nodes (nodes marked with the
* flag EF_DEVTERM), which automatically merge with other global nodes
* with the same name, since they're only implicitly connected anyway.
*/
for (nodeFlat = (EFNode *) efNodeList.efnode_next;
nodeFlat != &efNodeList;
nodeFlat = (EFNode *) nodeFlat->efnode_next)
{
/*
* Ignore nodes whose names aren't global. NOTE: we rely on
* the fact that EFHNBest() prefers global names to all others,
* so if the first name in a node's list isn't global, none of
* the rest are either.
*/
nameFlat = nodeFlat->efnode_name;
hnFlat = nameFlat->efnn_hier;
if (!EFHNIsGlob(hnFlat))
continue;
/*
* Look for an entry corresponding to the global part of hnFlat
* (only the leaf component) in the global name table. If one
* isn't found, an entry gets created.
*/
heGlob = HashFind(&globalTable, (char *) hnFlat);
nameGlob = (EFNodeName *) HashGetValue(heGlob);
if (nameGlob == NULL)
{
/*
* Create a new EFNodeName that points to nodeFlat, but
* don't link it in to nodeFlat->efnode_name yet.
*/
nameGlob = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName)));
HashSetValue(heGlob, (ClientData) nameGlob);
nameGlob->efnn_node = nodeFlat;
nameGlob->efnn_hier = (HierName *) heGlob->h_key.h_ptr;
nameGlob->efnn_port = -1;
nameGlob->efnn_refc = 0;
}
else if (nameGlob->efnn_node != nodeFlat)
{
/*
* If either node is a fet substrate node (marked with EF_DEVTERM)
* it's OK to merge them; otherwise, it's an error, but we still
* merge the nodes. When merging, we blow away nodeGlob and
* absorb it into nodeFlat for simplicity in control of the main
* loop. Note that since nameGlob isn't on the efnode_name list
* for nodeGlob, we have to update its node backpointer explicitly.
*/
nodeGlob = nameGlob->efnn_node;
if ((nodeGlob->efnode_flags & EF_DEVTERM) == 0
&& (nodeFlat->efnode_flags & EF_DEVTERM) == 0)
{
efFlatGlobError(nameGlob, nameFlat);
}
efNodeMerge(&nodeFlat, &nodeGlob);
nameGlob->efnn_node = nodeFlat;
}
}
/*
* Now make another pass through the global name table,
* prepending the global name (the HierName consisting of
* the trailing component only that was allocated when the
* name was added to globalTable above) to its node, and
* also adding it to the global hash table efNodeHashTable.
*/
HashStartSearch(&hs);
38 x warning: suggest parentheses around assignment used as truth value EFdef.c:110:12: warning: suggest parentheses around assignment used as truth value EFdef.c:154:12: warning: suggest parentheses around assignment used as truth value EFdef.c:167:12: warning: suggest parentheses around assignment used as truth value EFflat.c:546:17: warning: suggest parentheses around assignment used as truth value EFflat.c:798:12: warning: suggest parentheses around assignment used as truth value EFflat.c:930:13: warning: suggest parentheses around assignment used as truth value EFflat.c:1152:12: warning: suggest parentheses around assignment used as truth value EFflat.c:1157:13: warning: suggest parentheses around assignment used as truth value EFhier.c:84:12: warning: suggest parentheses around assignment used as truth value EFhier.c:261:12: warning: suggest parentheses around assignment used as truth value EFhier.c:489:12: warning: suggest parentheses around assignment used as truth value EFhier.c:682:12: warning: suggest parentheses around assignment used as truth value EFname.c:325:12: warning: suggest parentheses around assignment used as truth value EFname.c:584:13: warning: suggest parentheses around assignment used as truth value EFname.c:632:16: warning: suggest parentheses around assignment used as truth value EFname.c:765:16: warning: suggest parentheses around assignment used as truth value EFname.c:977:12: warning: suggest parentheses around assignment used as truth value EFsym.c:113:13: warning: suggest parentheses around assignment used as truth value EFsym.c:164:9: warning: suggest parentheses around assignment used as truth value EFvisit.c:322:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:627:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:881:16: warning: suggest parentheses around assignment used as truth value EFvisit.c:917:12: warning: suggest parentheses around assignment used as truth value grTk1.c:1325:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1342:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1757:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1766:9: warning: suggest parentheses around assignment used as truth value grTk5.c:177:12: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1095:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1111:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1542:13: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1551:13: warning: suggest parentheses around assignment used as truth value grTOGL5.c:201:12: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1093:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1109:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1493:21: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1502:21: warning: suggest parentheses around assignment used as truth value grTCairo5.c:202:16: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:20:32 +02:00
while ((heGlob = HashNext(&globalTable, &hs)))
{
/*
* Add the name to the flat node name hash table, and
* prepend the EFNodeName to the node's list, but only
* if the node didn't already exist in efNodeHashTable.
* Otherwise, free nameGlob.
*/
nameGlob = (EFNodeName *) HashGetValue(heGlob);
hnGlob = nameGlob->efnn_hier;
heFlat = HashFind(&efNodeHashTable, (char *) hnGlob);
if (HashGetValue(heFlat) == NULL)
{
nodeFlat = nameGlob->efnn_node;
HashSetValue(heFlat, (ClientData) nameGlob);
nameGlob->efnn_next = nodeFlat->efnode_name;
nodeFlat->efnode_name = nameGlob;
}
else
{
freeMagic((char *) nameGlob);
EFHNFree(hnGlob, (HierName *) NULL, HN_GLOBAL);
}
}
HashKill(&globalTable);
return;
}
void
efFlatGlobError(
EFNodeName *nameGlob,
EFNodeName *nameFlat)
{
EFNode *nodeGlob = nameGlob->efnn_node, *nodeFlat = nameFlat->efnn_node;
EFNodeName *nn;
int count;
TxPrintf("*** Global name %s not fully connected:\n",
nameGlob->efnn_hier->hn_name);
TxPrintf("One portion contains the names:\n");
for (count = 0, nn = nodeGlob->efnode_name;
count < 10 && nn;
count++, nn = nn->efnn_next)
{
TxPrintf(" %s\n", EFHNToStr(nn->efnn_hier));
}
if (nn) TxPrintf(" .... (no more names will be printed)\n");
TxPrintf("The other portion contains the names:\n");
for (count = 0, nn = nodeFlat->efnode_name;
count < 10 && nn;
count++, nn = nn->efnn_next)
{
TxPrintf(" %s\n", EFHNToStr(nn->efnn_hier));
}
if (nn) TxPrintf(" .... (no more names will be printed)\n");
TxPrintf("I'm merging the two pieces into a single node, but you\n");
TxPrintf("should be sure eventually to connect them in the layout.\n\n");
return;
}
bool
efFlatGlobCmp(hierName1, hierName2)
HierName *hierName1, *hierName2;
{
if (hierName1 == hierName2)
return FALSE;
return ((bool)(hierName1 == NULL || hierName2 == NULL
|| hierName1->hn_hash != hierName2->hn_hash
|| strcmp(hierName1->hn_name, hierName2->hn_name) != 0
));
}
char *
efFlatGlobCopy(hierName)
HierName *hierName;
{
HierName *hNew;
int size;
size = HIERNAMESIZE(strlen(hierName->hn_name));
hNew = (HierName *) mallocMagic((unsigned)(size));
(void) strcpy(hNew->hn_name, hierName->hn_name);
hNew->hn_parent = (HierName *) NULL;
hNew->hn_hash = hierName->hn_hash;
if (efHNStats)
efHNRecord(size, HN_GLOBAL);
return (char *) hNew;
}
int
efFlatGlobHash(hierName)
HierName *hierName;
{
return hierName->hn_hash;
}
/*
* ----------------------------------------------------------------------------
*
* efFlatKills --
*
* Recursively mark all killed nodes, using a depth-first post-order
* traversal of the hierarchy. The algorithm is the same as for
* efFlatNodes above.
*
* Results:
* Returns 0 to keep efHierSrUses going.
*
* Side effects:
* May mark node entries in the global name table as killed
* by setting EF_KILLED in the efnode_flags field.
*
* ----------------------------------------------------------------------------
*/
int
efFlatKills(hc)
HierContext *hc;
{
Def *def = hc->hc_use->use_def;
HashEntry *he;
EFNodeName *nn;
Kill *k;
/* Recursively visit each use */
(void) efHierSrUses(hc, efFlatKills, (ClientData) NULL);
/* Process all of our kill information */
for (k = def->def_kills; k; k = k->kill_next)
{
38 x warning: suggest parentheses around assignment used as truth value EFdef.c:110:12: warning: suggest parentheses around assignment used as truth value EFdef.c:154:12: warning: suggest parentheses around assignment used as truth value EFdef.c:167:12: warning: suggest parentheses around assignment used as truth value EFflat.c:546:17: warning: suggest parentheses around assignment used as truth value EFflat.c:798:12: warning: suggest parentheses around assignment used as truth value EFflat.c:930:13: warning: suggest parentheses around assignment used as truth value EFflat.c:1152:12: warning: suggest parentheses around assignment used as truth value EFflat.c:1157:13: warning: suggest parentheses around assignment used as truth value EFhier.c:84:12: warning: suggest parentheses around assignment used as truth value EFhier.c:261:12: warning: suggest parentheses around assignment used as truth value EFhier.c:489:12: warning: suggest parentheses around assignment used as truth value EFhier.c:682:12: warning: suggest parentheses around assignment used as truth value EFname.c:325:12: warning: suggest parentheses around assignment used as truth value EFname.c:584:13: warning: suggest parentheses around assignment used as truth value EFname.c:632:16: warning: suggest parentheses around assignment used as truth value EFname.c:765:16: warning: suggest parentheses around assignment used as truth value EFname.c:977:12: warning: suggest parentheses around assignment used as truth value EFsym.c:113:13: warning: suggest parentheses around assignment used as truth value EFsym.c:164:9: warning: suggest parentheses around assignment used as truth value EFvisit.c:322:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:627:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:881:16: warning: suggest parentheses around assignment used as truth value EFvisit.c:917:12: warning: suggest parentheses around assignment used as truth value grTk1.c:1325:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1342:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1757:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1766:9: warning: suggest parentheses around assignment used as truth value grTk5.c:177:12: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1095:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1111:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1542:13: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1551:13: warning: suggest parentheses around assignment used as truth value grTOGL5.c:201:12: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1093:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1109:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1493:21: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1502:21: warning: suggest parentheses around assignment used as truth value grTCairo5.c:202:16: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:20:32 +02:00
if ((he = EFHNConcatLook(hc->hc_hierName, k->kill_name, "kill")))
{
nn = (EFNodeName *) HashGetValue(he);
nn->efnn_node->efnode_flags |= EF_KILLED;
}
}
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* efFlatCapsDeviceless --
*
* Recursive procedure to flatten all capacitors in the circuit.
* Works like efFlatCaps() (see below), but ignores CellDefs that
* have no devices.
*
* Results:
* Returns 0 to keep efHierSrUses going.
*
* Side effects:
* See description of efFlatCaps().
*
* ----------------------------------------------------------------------------
*/
int
efFlatCapsDeviceless(hc)
HierContext *hc;
{
Connection *conn;
int newcount;
Use *use;
newcount = HashGetNumEntries(&hc->hc_use->use_def->def_uses);
/* Recursively flatten uses that have no active devices */
if (newcount > 0)
efHierSrUses(hc, efFlatCapsDeviceless, (ClientData)NULL);
if (!(hc->hc_use->use_def->def_flags & DEF_NODEVICES))
if (hc->hc_use->use_def->def_flags & DEF_PROCESSED)
return 0;
/* Output our own capacitors */
for (conn = hc->hc_use->use_def->def_caps; conn; conn = conn->conn_next)
{
/* Special case for speed if no arraying info */
if (conn->conn_1.cn_nsubs == 0)
efFlatSingleCap(hc, conn->conn_name1, conn->conn_name2, conn);
else
efHierSrArray(hc, conn, efFlatSingleCap, (ClientData) NULL);
}
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* efFlatCaps --
*
* Recursive procedure to flatten all capacitors in the circuit.
* Produces a single, global hash table (efCapHashTable) indexed
* by pairs of EFNode pointers, where the value of each entry is the
* capacitance between the two nodes.
*
* Algorithm:
* Before this procedure is called, efFlatNodes() should have been
* called to create a global table of all node names. We do a recursive
* traversal of the design rooted at 'hc->hc_use->use_def', and construct
* full hierarchical names from the terminals of each capacitor
* encountered.
*
* These full names are used to find via a lookup in efNodeHashTable the
* canonical name of the node for which this full name is an alias. The
* canonical name is output as the node to which this terminal connects.
*
* Capacitance where one of the nodes is substrate is treated specially;
* instead of adding an entry to the global hash table, we update
* the substrate capacitance of the other node appropriately.
*
* Results:
* Returns 0 to keep efHierSrUses going.
*
* Side effects:
* See above.
*
* ----------------------------------------------------------------------------
*/
int
efFlatCaps(hc)
HierContext *hc;
{
Connection *conn;
/* Recursively flatten capacitors */
(void) efHierSrUses(hc, efFlatCaps, (ClientData) 0);
/* Output our own capacitors */
for (conn = hc->hc_use->use_def->def_caps; conn; conn = conn->conn_next)
{
/* Special case for speed if no arraying info */
if (conn->conn_1.cn_nsubs == 0)
efFlatSingleCap(hc, conn->conn_name1, conn->conn_name2, conn);
else
efHierSrArray(hc, conn, efFlatSingleCap, (ClientData) NULL);
}
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* efFlatSingleCap --
*
* Add a capacitor with value 'conn->conn_cap' between the nodes
* 'name1' and 'name2' (text names, not hierarchical names). Don't
* add the capacitor if either terminal is a killed node.
*
* Results:
* Returns 0
*
* Side effects:
* Adds an entry to efCapHashTable indexed by the nodes of 'name1'
* and 'name2' respectively. If the two nodes are the same, though,
* nothing happens. If either node is ground (GND!), the capacitance
* is added to the substrate capacitance of the other node instead of
* creating a hash table entry.
*
* ----------------------------------------------------------------------------
*/
int
efFlatSingleCap(
HierContext *hc, /* Contains hierarchical pathname to cell */
char *name1, /* Names of nodes connecting to capacitor */
char *name2,
Connection *conn) /* Contains capacitance to add */
{
EFNode *n1, *n2;
HashEntry *he;
EFCoupleKey ck;
static char msg0[] = "cap(1)";
static char msg1[] = "cap(2)";
char *msg;
/* Connections that are below threshold (ext2spice hierarchy only) */
/* will be missing. Do not generate errors for these. */
msg = (fabs((double)conn->conn_cap / 1000) < EFCapThreshold) ? NULL : msg0;
if ((he = EFHNLook(hc->hc_hierName, name1, msg)) == NULL)
return 0;
n1 = ((EFNodeName *) HashGetValue(he))->efnn_node;
if (n1->efnode_flags & EF_KILLED)
return 0;
if (msg) msg = msg1;
if ((he = EFHNLook(hc->hc_hierName, name2, msg)) == NULL)
return 0;
n2 = ((EFNodeName *) HashGetValue(he))->efnn_node;
if (n2->efnode_flags & EF_KILLED)
return 0;
/* Do nothing if the nodes aren't different */
if (n1 == n2)
return 0;
if (n1->efnode_flags & EF_GLOB_SUBS_NODE)
n2->efnode_cap += conn->conn_cap; /* node 2 to substrate */
else if (n2->efnode_flags & EF_GLOB_SUBS_NODE)
n1->efnode_cap += conn->conn_cap; /* node 1 to substrate */
else
{
/* node1 to node2 */
if (n1 < n2) ck.ck_1 = n1, ck.ck_2 = n2;
else ck.ck_1 = n2, ck.ck_2 = n1;
he = HashFind(&efCapHashTable, (char *) &ck);
CapHashSetValue(he, (double) (conn->conn_cap + CapHashGetValue(he)));
}
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* efFlatDists --
*
* Recursive procedure to flatten all distance information in the circuit.
* Produces a single, global hash table (efDistHashTable) indexed
* by Distance structures, where the value of each entry is the same
* as the key and gives the min and maximum distances between the two
* points.
*
* Results:
* Returns 0 to keep efHierSrUses going.
*
* Side effects:
* See above.
*
* ----------------------------------------------------------------------------
*/
int
efFlatDists(hc)
HierContext *hc;
{
Distance *dist, *distFlat, distKey;
HashEntry *he, *heFlat;
HashSearch hs;
/* Recursively flatten distances */
(void) efHierSrUses(hc, efFlatDists, (ClientData) 0);
/* Process our own distances */
HashStartSearch(&hs);
38 x warning: suggest parentheses around assignment used as truth value EFdef.c:110:12: warning: suggest parentheses around assignment used as truth value EFdef.c:154:12: warning: suggest parentheses around assignment used as truth value EFdef.c:167:12: warning: suggest parentheses around assignment used as truth value EFflat.c:546:17: warning: suggest parentheses around assignment used as truth value EFflat.c:798:12: warning: suggest parentheses around assignment used as truth value EFflat.c:930:13: warning: suggest parentheses around assignment used as truth value EFflat.c:1152:12: warning: suggest parentheses around assignment used as truth value EFflat.c:1157:13: warning: suggest parentheses around assignment used as truth value EFhier.c:84:12: warning: suggest parentheses around assignment used as truth value EFhier.c:261:12: warning: suggest parentheses around assignment used as truth value EFhier.c:489:12: warning: suggest parentheses around assignment used as truth value EFhier.c:682:12: warning: suggest parentheses around assignment used as truth value EFname.c:325:12: warning: suggest parentheses around assignment used as truth value EFname.c:584:13: warning: suggest parentheses around assignment used as truth value EFname.c:632:16: warning: suggest parentheses around assignment used as truth value EFname.c:765:16: warning: suggest parentheses around assignment used as truth value EFname.c:977:12: warning: suggest parentheses around assignment used as truth value EFsym.c:113:13: warning: suggest parentheses around assignment used as truth value EFsym.c:164:9: warning: suggest parentheses around assignment used as truth value EFvisit.c:322:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:627:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:881:16: warning: suggest parentheses around assignment used as truth value EFvisit.c:917:12: warning: suggest parentheses around assignment used as truth value grTk1.c:1325:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1342:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1757:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1766:9: warning: suggest parentheses around assignment used as truth value grTk5.c:177:12: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1095:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1111:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1542:13: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1551:13: warning: suggest parentheses around assignment used as truth value grTOGL5.c:201:12: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1093:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1109:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1493:21: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1502:21: warning: suggest parentheses around assignment used as truth value grTCairo5.c:202:16: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:20:32 +02:00
while ((he = HashNext(&hc->hc_use->use_def->def_dists, &hs)))
{
dist = (Distance *) HashGetValue(he);
efHNBuildDistKey(hc->hc_hierName, dist, &distKey);
heFlat = HashFind(&efDistHashTable, (char *) &distKey);
38 x warning: suggest parentheses around assignment used as truth value EFdef.c:110:12: warning: suggest parentheses around assignment used as truth value EFdef.c:154:12: warning: suggest parentheses around assignment used as truth value EFdef.c:167:12: warning: suggest parentheses around assignment used as truth value EFflat.c:546:17: warning: suggest parentheses around assignment used as truth value EFflat.c:798:12: warning: suggest parentheses around assignment used as truth value EFflat.c:930:13: warning: suggest parentheses around assignment used as truth value EFflat.c:1152:12: warning: suggest parentheses around assignment used as truth value EFflat.c:1157:13: warning: suggest parentheses around assignment used as truth value EFhier.c:84:12: warning: suggest parentheses around assignment used as truth value EFhier.c:261:12: warning: suggest parentheses around assignment used as truth value EFhier.c:489:12: warning: suggest parentheses around assignment used as truth value EFhier.c:682:12: warning: suggest parentheses around assignment used as truth value EFname.c:325:12: warning: suggest parentheses around assignment used as truth value EFname.c:584:13: warning: suggest parentheses around assignment used as truth value EFname.c:632:16: warning: suggest parentheses around assignment used as truth value EFname.c:765:16: warning: suggest parentheses around assignment used as truth value EFname.c:977:12: warning: suggest parentheses around assignment used as truth value EFsym.c:113:13: warning: suggest parentheses around assignment used as truth value EFsym.c:164:9: warning: suggest parentheses around assignment used as truth value EFvisit.c:322:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:627:12: warning: suggest parentheses around assignment used as truth value EFvisit.c:881:16: warning: suggest parentheses around assignment used as truth value EFvisit.c:917:12: warning: suggest parentheses around assignment used as truth value grTk1.c:1325:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1342:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1757:9: warning: suggest parentheses around assignment used as truth value grTk1.c:1766:9: warning: suggest parentheses around assignment used as truth value grTk5.c:177:12: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1095:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1111:9: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1542:13: warning: suggest parentheses around assignment used as truth value grTOGL1.c:1551:13: warning: suggest parentheses around assignment used as truth value grTOGL5.c:201:12: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1093:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1109:13: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1493:21: warning: suggest parentheses around assignment used as truth value grTCairo1.c:1502:21: warning: suggest parentheses around assignment used as truth value grTCairo5.c:202:16: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:20:32 +02:00
if ((distFlat = (Distance *) HashGetValue(heFlat)))
{
/*
* This code differs from that in efBuildDist(), in that
* we replace the min/max information in distFlat from
* that in dist, rather than computing a new min/max.
* The reason is that the information in dist (in the
* parent) is assumed to override that already computed
* in the child.
*/
distFlat->dist_min = dist->dist_min;
distFlat->dist_max = dist->dist_max;
EFHNFree(distKey.dist_1, hc->hc_hierName, HN_CONCAT);
EFHNFree(distKey.dist_2, hc->hc_hierName, HN_CONCAT);
}
else
{
/*
* If there was no entry in the table already with this
* key, make the HashEntry point to its key (which is
* the newly malloc'd Distance structure).
*/
HashSetValue(heFlat, (ClientData) he->h_key.h_ptr);
}
}
return 0;
}
/*
* CapHashGetValue()
* do a HashGetValue, and if the pointer is null, return (EFCapValue)0.0
*/
EFCapValue CapHashGetValue(he)
HashEntry *he;
{
EFCapValue *capp = (EFCapValue *)HashGetValue(he);
if(capp == NULL)
return (EFCapValue)0;
else
return *capp;
}
/*
* CapHashSetValue()
* if the pointer is null, allocate a EFCapValue and point to it.
* Then copy in the new value.
*
* need to pass doubles regardless of what CapValue is because of
* argument promotion in ANSI C
*
*/
void
CapHashSetValue(he, c)
HashEntry *he;
double c;
{
EFCapValue *capp = (EFCapValue *)HashGetValue(he);
if(capp == NULL) {
capp = (EFCapValue *) mallocMagic((unsigned)(sizeof(EFCapValue)));
HashSetValue(he, capp);
}
*capp = (EFCapValue) c;
return;
}