Last set of changes to get non-Manhattan area and perimeter

device extraction working, and also resolved an unrelated error
in "getnode" and another unrelated error reading "resist" values
from the tech file "extract" section.
This commit is contained in:
R. Timothy Edwards 2026-01-19 17:18:10 -05:00
parent 3de9ed9cbf
commit c0c5e1b5bf
10 changed files with 267 additions and 1979 deletions

1896
README

File diff suppressed because it is too large Load Diff

View File

@ -1221,7 +1221,7 @@ extComputeEffectiveLW(rlengthptr, rwidthptr, numregions, chop)
int i, j, p, jmax;
LinkedBoundary *lb, *lb2;
int oppdir, length, loclength, testlen, width;
int locwidth, testwid, cornerw;
int locwidth, testwid, cornerw, nmlen;
int segp, segn, segc, sege;
bool isComplex = FALSE;
@ -1268,8 +1268,7 @@ extComputeEffectiveLW(rlengthptr, rwidthptr, numregions, chop)
case BD_RIGHT: oppdir = BD_LEFT; break;
case BD_TOP: oppdir = BD_BOTTOM; break;
case BD_BOTTOM: oppdir = BD_TOP; break;
default: ASSERT(FALSE, "oppdir"); /* should never happen */
oppdir = 0; break;
default: continue; break;
}
/* First pass: Find the distance of the closest segment within */
@ -1470,6 +1469,32 @@ extComputeEffectiveLW(rlengthptr, rwidthptr, numregions, chop)
}
width += locwidth;
}
/* Add in the width of the sum of all non-Manhattan segments. */
/* This is an approximation that works for beveled corners on */
/* annular devices and may not work so well elsewhere. May need */
/* revisiting. */
nmlen = 0;
for (i = 0; i < numregions; i++)
{
for (lb = extSpecialBounds[i]; lb != NULL; lb = lb->b_next)
{
if (lb->dir & (BD_NW | BD_NE | BD_SW | BD_SE))
{
double asq, bsq;
/* Do not process non-Manhattan segments other than to sum
* their total length.
*/
asq = (double)(lb->r.r_xtop - lb->r.r_xbot);
bsq = (double)(lb->r.r_ytop - lb->r.r_ybot);
nmlen += (int)(0.5 + sqrt(asq * asq + bsq * bsq));
}
}
}
width += nmlen;
if ((length > 0) && (width > 0))
{
*rlengthptr = length;
@ -3627,9 +3652,12 @@ extTermAPFunc(tile, dinfo, eapd)
TileType type, tpdi;
Tile *tp;
Rect r;
int area, sides;
ExtRegion *nreg;
TiToRect(tile, &r);
eapd->eapd_area += (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot);
area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot);
sides = 0;
/* Diagonal */
if (IsSplit(tile))
@ -3640,7 +3668,28 @@ extTermAPFunc(tile, dinfo, eapd)
h = TOP(tile) - BOTTOM(tile);
l = w * w + h * h;
eapd->eapd_perim += (int)sqrt((double)l);
eapd->eapd_area += area / 2;
/* Mark which sides do not add to the perimeter */
if (dinfo & TT_SIDE)
{
sides |= BD_LEFT;
if (SplitDirection(tile))
sides |= BD_BOTTOM;
else
sides |= BD_TOP;
}
else
{
sides |= BD_RIGHT;
if (SplitDirection(tile))
sides |= BD_TOP;
else
sides |= BD_BOTTOM;
}
}
else
eapd->eapd_area += area;
/* Top */
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
@ -3649,11 +3698,17 @@ extTermAPFunc(tile, dinfo, eapd)
tpdi = SplitDirection(tp) ? (TileType)0 : (TileType)TT_SIDE;
if (TTMaskHasType(&eapd->eapd_mask, type))
{
eapd->eapd_perim += MIN(RIGHT(tile), RIGHT(tp)) -
if (!(sides & BD_TOP))
eapd->eapd_perim += MIN(RIGHT(tile), RIGHT(tp)) -
MAX(LEFT(tile), LEFT(tp));
if (TTMaskHasType(eapd->eapd_gatemask, type))
if ((NodeRegion *)ExtGetRegion(tp, tpdi) != eapd->eapd_gatenode)
{
nreg = ExtGetRegion(tp, tpdi);
if (((ClientData)nreg != CLIENTDEFAULT) &&
((ClientData)nreg != VISITPENDING) &&
((NodeRegion *)nreg != eapd->eapd_gatenode))
extAddSharedDevice(eapd, (NodeRegion *)ExtGetRegion(tp,tpdi));
}
}
}
@ -3664,11 +3719,17 @@ extTermAPFunc(tile, dinfo, eapd)
tpdi = SplitDirection(tp) ? (TileType)TT_SIDE : (TileType)0;
if (TTMaskHasType(&eapd->eapd_mask, type))
{
eapd->eapd_perim += MIN(RIGHT(tile), RIGHT(tp)) -
if (!(sides & BD_BOTTOM))
eapd->eapd_perim += MIN(RIGHT(tile), RIGHT(tp)) -
MAX(LEFT(tile), LEFT(tp));
if (TTMaskHasType(eapd->eapd_gatemask, type))
if ((NodeRegion *)ExtGetRegion(tp, tpdi) != eapd->eapd_gatenode)
{
nreg = ExtGetRegion(tp, tpdi);
if (((ClientData)nreg != CLIENTDEFAULT) &&
((ClientData)nreg != VISITPENDING) &&
((NodeRegion *)nreg != eapd->eapd_gatenode))
extAddSharedDevice(eapd, (NodeRegion *)ExtGetRegion(tp,tpdi));
}
}
}
@ -3679,11 +3740,17 @@ extTermAPFunc(tile, dinfo, eapd)
tpdi = (TileType)TT_SIDE;
if (TTMaskHasType(&eapd->eapd_mask, type))
{
eapd->eapd_perim += MIN(TOP(tile), TOP(tp)) -
if (!(sides & BD_LEFT))
eapd->eapd_perim += MIN(TOP(tile), TOP(tp)) -
MAX(BOTTOM(tile), BOTTOM(tp));
if (TTMaskHasType(eapd->eapd_gatemask, type))
if ((NodeRegion *)ExtGetRegion(tp, tpdi) != eapd->eapd_gatenode)
{
nreg = ExtGetRegion(tp, tpdi);
if (((ClientData)nreg != CLIENTDEFAULT) &&
((ClientData)nreg != VISITPENDING) &&
((NodeRegion *)nreg != eapd->eapd_gatenode))
extAddSharedDevice(eapd, (NodeRegion *)ExtGetRegion(tp,tpdi));
}
}
}
@ -3694,11 +3761,17 @@ extTermAPFunc(tile, dinfo, eapd)
tpdi = (TileType)0;
if (TTMaskHasType(&eapd->eapd_mask, type))
{
eapd->eapd_perim += MIN(TOP(tile), TOP(tp)) -
if (!(sides & BD_RIGHT))
eapd->eapd_perim += MIN(TOP(tile), TOP(tp)) -
MAX(BOTTOM(tile), BOTTOM(tp));
if (TTMaskHasType(eapd->eapd_gatemask, type))
if ((NodeRegion *)ExtGetRegion(tp, tpdi) != eapd->eapd_gatenode)
{
nreg = ExtGetRegion(tp, tpdi);
if (((ClientData)nreg != CLIENTDEFAULT) &&
((ClientData)nreg != VISITPENDING) &&
((NodeRegion *)nreg != eapd->eapd_gatenode))
extAddSharedDevice(eapd, (NodeRegion *)ExtGetRegion(tp,tpdi));
}
}
}
}
@ -3749,6 +3822,11 @@ extTransPerimFunc(bp)
case BD_BOTTOM:
tinside = TiGetBottomType(tile);
break;
default:
/* Non-Manhattan boundaries not handled.
* Future work to be done.
*/
return 0;
}
}
else
@ -4126,8 +4204,8 @@ extSpecialPerimFunc(bp, sense)
Boundary *bp;
bool sense;
{
TileType tinside, toutside;
NodeRegion *termNode = (NodeRegion *) ExtGetRegion(bp->b_outside, (TileType)0);
TileType tinside, toutside, termdinfo;
NodeRegion *termNode;
int thisterm, extended, i;
LinkedBoundary *newBound, *lb, *lastlb;
ExtDevice *devptr;
@ -4139,15 +4217,20 @@ extSpecialPerimFunc(bp, sense)
/* most cases this will be only a slight deviation from the true */
/* result. */
termdinfo = TiGetTypeExact(bp->b_outside);
switch (bp->b_direction)
{
case BD_TOP:
tinside = TiGetTopType(bp->b_inside);
toutside = TiGetBottomType(bp->b_outside);
if (IsSplit(bp->b_outside) && !SplitDirection(bp->b_outside))
termdinfo |= TT_SIDE;
break;
case BD_BOTTOM:
tinside = TiGetBottomType(bp->b_inside);
toutside = TiGetTopType(bp->b_outside);
if (SplitDirection(bp->b_outside)) termdinfo |= TT_SIDE;
break;
case BD_RIGHT:
tinside = TiGetRightType(bp->b_inside);
@ -4156,8 +4239,28 @@ extSpecialPerimFunc(bp, sense)
case BD_LEFT:
tinside = TiGetLeftType(bp->b_inside);
toutside = TiGetRightType(bp->b_outside);
termdinfo |= TT_SIDE;
break;
case BD_NW:
tinside = TiGetLeftType(bp->b_inside);
toutside = TiGetRightType(bp->b_outside);
termdinfo |= TT_SIDE;
break;
case BD_SW:
tinside = TiGetLeftType(bp->b_inside);
toutside = TiGetRightType(bp->b_outside);
termdinfo |= TT_SIDE;
break;
case BD_NE:
tinside = TiGetRightType(bp->b_inside);
toutside = TiGetLeftType(bp->b_outside);
break;
case BD_SE:
tinside = TiGetRightType(bp->b_inside);
toutside = TiGetLeftType(bp->b_outside);
break;
}
termNode = (NodeRegion *) ExtGetRegion(bp->b_outside, termdinfo);
/* Required to use the same device record that was used to find */
/* the terminals. */
@ -4225,7 +4328,11 @@ extSpecialPerimFunc(bp, sense)
/*
* Check the existing segment list to see if this segment
* extends an existing segment.
* extends an existing segment. If so, then increase the
* length of the existing segment to cover the new one.
* Then check if the segment joins two other segments.
* If so, then all three segments get merged into one.
* Otherwise, add the new segment to the segment list.
*/
extended = 0;
@ -4283,6 +4390,10 @@ extSpecialPerimFunc(bp, sense)
}
}
break;
/* To do: Handle joining of non-Manhattan
* segments in the same direction.
*/
}
}
if (extended == 2)

View File

@ -1082,6 +1082,18 @@ extAddCouple(bp, ecs)
extSidewallStruct esws;
int distFringe;
/* Non-Manhattan boundaries are not handled. This is
* future work to be done.
*/
switch (bp->b_direction)
{
case BD_NW:
case BD_NE:
case BD_SW:
case BD_SE:
return 0;
}
/* Get the types on the inside and outside of the boundary */
extGetBoundaryTypes(bp, &tin, &tout);
@ -1174,7 +1186,7 @@ extAddCouple(bp, ecs)
extSideBottom, bp, &esws);
break;
}
return (0);
return 0;
}
/*

View File

@ -1008,6 +1008,8 @@ extExtractStack(stack, doExtract, rootDef)
newsl->sl_next = sl;
sl = newsl;
}
else
def->cd_flags &= ~CDNOEXTRACT;
errorcnt += extNumErrors;
warnings += extNumWarnings;
@ -1019,6 +1021,8 @@ extExtractStack(stack, doExtract, rootDef)
TxFlush();
first = FALSE;
}
else
def->cd_flags &= ~CDNOEXTRACT;
}
}

View File

@ -97,15 +97,18 @@ extEnumTilePerim(
b.b_plane = pNum;
perimCorrect = 0;
/* Diagonal */
if (IsSplit(tpIn))
{
/* Determine which two sides need to be searched and set the corresponding
* boundary direction bit in "sides". "dinfo" determines which side of the
* split tile is considered "inside" the boundary and which is "outside".
/* Handle a diagonal boundary across a split tile.
* "dinfo" determines which side of the split tile is considered "inside" the
* boundary and which is "outside". Invoke the callback function for the
* diagonal, then determine which two sides don't need to be searched and
* set the corresponding boundary direction bit in "sides".
*/
TileType otype = (dinfo & TT_SIDE) ? SplitLeftType(tpIn): SplitRightType(tpIn);
TileType itype = (dinfo & TT_SIDE) ? SplitRightType(tpIn): SplitLeftType(tpIn);
if (TTMaskHasType(&mask, otype))
{
int width = RIGHT(tpIn) - LEFT(tpIn);
@ -113,6 +116,30 @@ extEnumTilePerim(
perimCorrect = width * width + height * height;
perimCorrect = (int)sqrt((double)perimCorrect);
}
/* Invoke the callback function on diagonal boundaries */
b.b_outside = tpIn; /* Same tile on both sides of the boundary */
TiToRect(tpIn, &b.b_segment);
if (SplitDirection(tpIn))
{
if (dinfo & TT_SIDE)
b.b_direction = BD_NE;
else
b.b_direction = BD_SW;
}
else
{
if (dinfo & TT_SIDE)
b.b_direction = BD_SE;
else
b.b_direction = BD_NW;
}
if (func) (*func)(&b, cdata);
/* Flag which two sides of the tile don't need searching */
sides = (dinfo & TT_SIDE) ? BD_LEFT : BD_RIGHT;
sides |= (((dinfo & TT_SIDE) ? 1 : 0) == SplitDirection(tpIn)) ?
BD_BOTTOM : BD_TOP;

View File

@ -3350,7 +3350,22 @@ ExtTechLine(sectionName, argc, argv)
}
else
{
TxError("Resist argument must be integer or \"None\".\n");
char *decimal;
if ((decimal = strchr(argv[2], '.')) != NULL)
{
*decimal = '\0';
if (StrIsInt(argv[2]))
{
resVal = aToRes(argv[2]);
if (strcmp(decimal + 1, "0"))
TxError("Resist argument truncated to integer value.\n");
}
else
TxError("Unparseable resist argument \"%s\"\n", argv[2]);
}
else
TxError("Resist argument must be integer or \"None\".\n");
break;
}
}

View File

@ -296,16 +296,27 @@ typedef struct
int b_plane; /* extract argument for extSideOverlap */
} Boundary;
/* Define Manhattan boundary length */
#define BoundaryLength(bp) \
((bp)->b_segment.r_xtop - (bp)->b_segment.r_xbot \
+ (bp)->b_segment.r_ytop - (bp)->b_segment.r_ybot)
/* Directions in which we can be following the boundary of a perimeter */
#define BD_LEFT 1 /* Inside is to right */
#define BD_TOP 2 /* Inside is below */
#define BD_RIGHT 4 /* Inside is to left */
#define BD_BOTTOM 8 /* Inside is above */
#define BD_LEFT 0x01 /* Inside is to right */
#define BD_TOP 0x02 /* Inside is below */
#define BD_RIGHT 0x04 /* Inside is to left */
#define BD_BOTTOM 0x08 /* Inside is above */
/* Non-manhattan boundary directions. Inside is in the
* direction indicated (e.g., BD_NW, inside is top left)
*/
#define BD_NW 0x10 /* TT_SIDE = 0 TT_DIR = 0 */
#define BD_SW 0x20 /* TT_SIDE = 0 TT_DIR = 1 */
#define BD_SE 0x40 /* TT_SIDE = 1 TT_DIR = 0 */
#define BD_NE 0x80 /* TT_SIDE = 1 TT_DIR = 1 */
/* -------- Yank buffers for hierarchical and array extraction -------- */

View File

@ -46,9 +46,9 @@
#include "utils/styles.h"
#include "graphics/graphics.h"
static char bestName[256];
/* NOTE: This should not be a global variable. . . */
#define MAXPATHNAME 1024
static char bestName[MAXPATHNAME];
/*
* ----------------------------------------------------------------------------
@ -310,8 +310,6 @@ SimConnectFunc(
* ----------------------------------------------------------------------------
*/
#define MAXPATHNAME 256
void
SimTreeCopyConnect(
SearchContext *scx, /* Describes starting area. The
@ -341,11 +339,7 @@ SimTreeCopyConnect(
* anything connected to material of
* type mask in area of rootUse.
*/
char *Node_Name) /* Name of node returned.
* NOTE: Don't call this "NodeName",
* because that conflicts with reserved
* words in some compilers.
*/
char *Node_Name) /* Name of node returned. */
{
TerminalPath tpath;
char pathName[MAXPATHNAME];
@ -775,8 +769,8 @@ SimCellTileSrFunc(
tp = fp->tf_tpath;
tnext = tp->tp_next;
tp->tp_next = DBPrintUseId(scx, tp->tp_next, tp->tp_last -
tp->tp_next, FALSE);
if (tp->tp_next < tp->tp_last)
tp->tp_next - 1, FALSE);
if (tp->tp_next < tp->tp_last - 1)
{
*(tp->tp_next++) = '/';
*(tp->tp_next) = '\0';

View File

@ -135,10 +135,10 @@ SimAddDefList(
return;
}
else {
d = (DefListElt *) mallocMagic((unsigned) (sizeof(DefListElt)));
d = (DefListElt *)mallocMagic((unsigned) (sizeof(DefListElt)));
d->dl_next = DefList;
d->dl_def = newdef;
DefList= d;
DefList = d;
}
}
@ -250,12 +250,15 @@ SimInitConnTables(void)
TTMaskZero(&SimSDMask);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
devptr = ExtCurStyle->exts_device[t];
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
for (devptr = ExtCurStyle->exts_device[t]; devptr;
devptr = devptr->exts_next)
{
TTMaskSetMask(&SimSDMask, &devptr->exts_deviceSDTypes[i]);
TTMaskZero(&SimFetMask[t]);
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
{
TTMaskSetMask(&SimSDMask, &devptr->exts_deviceSDTypes[i]);
TTMaskZero(&SimFetMask[t]);
}
}
}
@ -264,16 +267,19 @@ SimInitConnTables(void)
{
if (TTMaskHasType(&SimTransMask, t))
{
devptr = ExtCurStyle->exts_device[t];
for (sd = TT_TECHDEPBASE; sd < DBNumTypes; sd++)
for (devptr = ExtCurStyle->exts_device[t]; devptr;
devptr = devptr->exts_next)
{
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
for (sd = TT_TECHDEPBASE; sd < DBNumTypes; sd++)
{
if (TTMaskHasType(&devptr->exts_deviceSDTypes[i], sd))
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
{
TTMaskSetType(&SimFetMask[sd], t);
SimFetPlanes |= PlaneNumToMaskBit(DBPlane(t));
if (TTMaskHasType(&devptr->exts_deviceSDTypes[i], sd))
{
TTMaskSetType(&SimFetMask[sd], t);
SimFetPlanes |= PlaneNumToMaskBit(DBPlane(t));
}
}
}
}
@ -354,7 +360,7 @@ SimTxtorLabel(
r1.r_ll = trans->t_ll;
r1.r_xtop = r1.r_xbot + 1;
r1.r_ytop = r1.r_ybot + 1;
GeoTransRect( tm, &r1, &r2 );
GeoTransRect(tm, &r1, &r2);
if (nterm > 1)
nterm = 1;
sprintf(name, "@=%c%d,%d", "gsd"[nterm+1], r2.r_xbot, r2.r_ybot);
@ -382,7 +388,7 @@ SimTransTerms(
TransTerm *term;
Tile *tile = bp->b_outside;
TileType type;
NodeRegion *reg = (NodeRegion *) TiGetClientPTR(tile);
NodeRegion *reg = (NodeRegion *)TiGetClientPTR(tile);
int pNum;
int i;
@ -400,6 +406,10 @@ SimTransTerms(
case BD_BOTTOM:
type = TiGetTopType(tile);
break;
default:
/* Don't handle diagonal tiles */
/* (future work?) */
return 0;
}
}
else
@ -407,33 +417,33 @@ SimTransTerms(
pNum = DBPlane(type);
for( i = 0; i < trans->t_nterm; i++ )
for (i = 0; i < trans->t_nterm; i++)
{
term = &trans->t_term[i];
if( term->region == reg )
if (term->region == reg)
{
if( pNum < term->pnum )
if (pNum < term->pnum)
{
term->pnum = pNum;
term->pos = tile->ti_ll;
}
else if( pNum == term->pnum )
else if (pNum == term->pnum)
{
if( LEFT(tile) < term->pos.p_x )
if (LEFT(tile) < term->pos.p_x)
term->pos = tile->ti_ll;
else if( LEFT(tile) == term->pos.p_x &&
BOTTOM(tile) < term->pos.p_y )
else if (LEFT(tile) == term->pos.p_x &&
BOTTOM(tile) < term->pos.p_y)
term->pos.p_y = BOTTOM(tile);
}
return( 0 );
return 0;
}
}
term = &trans->t_term[ trans->t_nterm++ ];
term = &trans->t_term[trans->t_nterm++];
term->region = reg;
term->pnum = pNum;
term->pos = tile->ti_ll;
return( 0 );
return 0;
}
@ -448,18 +458,18 @@ SimTermNum(
do
{
changed = 0;
for( i = 0; i < trans->t_nterm-1; i++ )
for (i = 0; i < trans->t_nterm-1; i++)
{
p1 = &(trans->t_term[i]);
p2 = &(trans->t_term[i+1]);
if( p2->pnum > p1->pnum )
if (p2->pnum > p1->pnum)
continue;
else if( p2->pnum == p1->pnum )
else if (p2->pnum == p1->pnum)
{
if( p2->pos.p_x > p1->pos.p_x )
if (p2->pos.p_x > p1->pos.p_x)
continue;
else if( p2->pos.p_x == p1->pos.p_x &&
p2->pos.p_y > p1->pos.p_y )
else if (p2->pos.p_x == p1->pos.p_x &&
p2->pos.p_y > p1->pos.p_y)
continue;
}
changed = 1;
@ -468,18 +478,16 @@ SimTermNum(
*p2 = tmp;
}
}
while( changed );
while (changed);
for( i = 0; i < trans->t_nterm; i++ )
for (i = 0; i < trans->t_nterm; i++)
{
if( trans->t_term[i].region == reg )
return( i );
if (trans->t_term[i].region == reg)
return i;
}
/* should never get here */
return( -1 );
return -1; /* not reached */
}
int
SimTransistorTile(
Tile *tile,
@ -499,10 +507,9 @@ SimTransistorTile(
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
extEnumTilePerim(tile, dinfo, &devptr->exts_deviceSDTypes[i],
pNum, SimTransTerms, (ClientData) &transistor );
pNum, SimTransTerms, (ClientData)&transistor);
}
return (0);
return 0;
}
@ -526,7 +533,7 @@ SimFindTxtor(
{
gateTile = tile; /* found a transistor gate, stop searching */
gateDinfo = dinfo;
return( 1 );
return 1;
}
else if (IsTransTerm(type) && (sdTile == (Tile *)NULL))
{
@ -630,7 +637,7 @@ SimFindOneNode(
arg.fra_each = (int (*)()) NULL;
(void) ExtFindNeighbors(tile, dinfo, arg.fra_pNum, &arg);
freeMagic( reg );
freeMagic(reg);
ret.nd_name = SimTxtorLabel(-1, &sx->scx_trans, &transistor);
ret.nd_what = ND_NAME;

View File

@ -80,6 +80,7 @@ static SimDefListElt *SimCellLabList = (SimDefListElt *) NULL;
typedef struct TLE {
const char *tl_nodeName;
Tile *tl_nodeTile;
TileType tl_dinfo;
const char *tl_simLabel;
struct TLE *tl_next;
} TileListElt;
@ -396,21 +397,23 @@ SimSelectFunc(
if (TTMaskHasType(&mask, type)) break;
}
nameBuff[0] = '\0';
nodeName = SimSelectNode(&scx, type, CU_DESCEND_ALL, nameBuff);
/* add the node name to the list only if it has not been seen yet */
coord = (nodeName[0] == '@' && nodeName[1] == '=') ? TRUE : FALSE;
if(coord || HashLookOnly(&SimNodeNameTbl, nodeName) == (HashEntry *) NULL)
if (coord || HashLookOnly(&SimNodeNameTbl, nodeName) == (HashEntry *) NULL)
{
if( ! coord )
if (! coord)
HashFind(&SimNodeNameTbl, nodeName);
newNodeTile = (TileListElt *) mallocMagic((unsigned) (sizeof (TileListElt)));
char *tmp = (char *) mallocMagic((unsigned) (strlen(nodeName) + 1));
strcpy(tmp, nodeName);
newNodeTile->tl_nodeName = tmp; /* assign to const */
newNodeTile->tl_nodeTile = tile;
newNodeTile->tl_dinfo = dinfo;
newNodeTile->tl_next = *pHead;
*pHead = newNodeTile;
}