Merge branch 'master' into bplane

Conflicts:
	VERSION
	database/DBcellsrch.c
	database/DBconnect.c
	extract/ExtInter.c
	lef/Depend
	utils/Depend

Updated bplane branch with all changes to master since the bplane branch
was last modified.
This commit is contained in:
Tim Edwards
2020-03-12 08:29:33 -04:00
144 changed files with 10590 additions and 8165 deletions
+41 -10
View File
@@ -234,7 +234,10 @@ dbCellPlaneSrFunc(scx, fp)
if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask))
return 0;
if ((def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(def, (char *) NULL, TRUE, NULL)) return 0;
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
}
context.tc_scx = scx;
context.tc_filter = fp;
@@ -353,7 +356,10 @@ dbCellUniqueTileSrFunc(scx, fp)
if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask))
return 0;
if ((def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(def, (char *) NULL, TRUE, NULL)) return 0;
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
}
context.tc_scx = scx;
context.tc_filter = fp;
@@ -462,7 +468,10 @@ DBNoTreeSrTiles(scx, mask, xMask, func, cdarg)
return 0;
if ((def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(def, (char *) NULL, TRUE, NULL)) return 0;
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
}
filter.tf_func = func;
filter.tf_arg = cdarg;
@@ -570,7 +579,10 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
ASSERT(def != (CellDef *) NULL, "DBTreeSrLabels");
if (!DBDescendSubcell(cellUse, xMask)) return 0;
if ((def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(def, (char *) NULL, TRUE, NULL)) return 0;
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
}
for (lab = def->cd_labels; lab; lab = lab->lab_next)
{
@@ -613,8 +625,11 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
else
is_touching = GEO_TOUCH(&lab->lab_rect, r);
}
if (!is_touching && (flags & TF_LABEL_DISPLAY) && (lab->lab_font >= 0))
if (!is_touching && (flags & TF_LABEL_DISPLAY) && lab->lab_font >= 0)
{
/* Check against bounds of the rendered label text */
is_touching = GEO_TOUCH(&lab->lab_bbox, r);
}
if (is_touching && TTMaskHasType(mask, lab->lab_type))
if ((*func)(scx, lab, tpath, cdarg))
@@ -671,7 +686,10 @@ dbCellLabelSrFunc(scx, fp)
ASSERT(def != (CellDef *) NULL, "dbCellLabelSrFunc");
if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0;
if ((def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(def, (char *) NULL, TRUE, NULL)) return 0;
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
}
if (fp->tf_tpath != (TerminalPath *) NULL)
{
@@ -785,8 +803,11 @@ DBTreeSrCells(scx, xMask, func, cdarg)
if (!DBDescendSubcell(cellUse, xMask))
return 0;
if ((cellUse->cu_def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(cellUse->cu_def, (char *) NULL, TRUE, NULL))
{
bool dereference = (cellUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(cellUse->cu_def, (char *) NULL, TRUE, dereference, NULL))
return 0;
}
context.tc_scx = scx;
context.tc_filter = &filter;
@@ -831,8 +852,11 @@ dbTreeCellSrFunc(scx, fp)
else
{
if ((use->cu_def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, NULL))
{
bool dereference = (use->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL))
return 0;
}
result = DBCellSrArea(scx, dbTreeCellSrFunc, (ClientData) fp);
}
return result;
@@ -1082,8 +1106,12 @@ DBCellSrArea(scx, func, cdarg)
context.tc_scx = scx;
if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(scx->scx_use->cu_def, (char *) NULL, TRUE, NULL))
{
bool dereference = (scx->scx_use->cu_def->cd_flags & CDDEREFERENCE) ?
TRUE : FALSE;
if (!DBCellRead(scx->scx_use->cu_def, (char *) NULL, TRUE, dereference, NULL))
return 0;
}
if (DBSrCellPlaneArea(scx->scx_use->cu_def->cd_cellPlane,
&scx->scx_area, dbCellSrFunc, (ClientData) &context))
@@ -1205,7 +1233,10 @@ DBCellEnum(cellDef, func, cdarg)
filter.tf_func = func;
filter.tf_arg = cdarg;
if ((cellDef->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(cellDef, (char *) NULL, TRUE, NULL)) return 0;
{
bool dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(cellDef, (char *) NULL, TRUE, dereference, NULL)) return 0;
}
if (DBSrCellPlaneArea(cellDef->cd_cellPlane,
&TiPlaneRect, dbEnumFunc, (ClientData) &filter))
return 1;
+5 -1
View File
@@ -73,8 +73,12 @@ DBDescendSubcell(use, xMask)
case CU_DESCEND_NO_SUBCKT:
if ((use->cu_def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, NULL))
{
bool dereference = (use->cu_def->cd_flags & CDDEREFERENCE) ?
TRUE : FALSE;
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL))
return FALSE;
}
return (DBIsSubcircuit(use->cu_def)) ? FALSE : TRUE;
case CU_DESCEND_NO_LOCK:
+34 -5
View File
@@ -661,6 +661,9 @@ dbcUnconnectFunc(tile, clientData)
* ----------------------------------------------------------------------------
*/
/* To do: Make the tpath entries dynamically allocated */
#define FLATTERMSIZE 1024
int
dbcConnectLabelFunc(scx, lab, tpath, csa2)
SearchContext *scx;
@@ -672,6 +675,8 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
Rect r;
Point offset;
int pos, rotate;
char newlabtext[FLATTERMSIZE];
char *newlabptr;
int dbcConnectFunc(); /* Forward declaration */
GeoTransRect(&scx->scx_trans, &lab->lab_rect, &r);
@@ -683,12 +688,29 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
/* the top level (Note: Could alter label to be placed with */
/* tpath). */
if (csa2->csa2_topscx->scx_use == scx->scx_use)
if (scx->scx_use != csa2->csa2_topscx->scx_use)
{
DBEraseLabelsByContent(def, &r, -1, lab->lab_text);
DBPutFontLabel(def, &r, lab->lab_font, lab->lab_size, rotate, &offset,
pos, lab->lab_text, lab->lab_type, lab->lab_flags);
int newllen = tpath->tp_next - tpath->tp_first;
newlabtext[0] = '\0';
if (newllen > 0)
strncpy(newlabtext, tpath->tp_first, newllen);
sprintf(newlabtext + newllen, "%s", lab->lab_text);
newlabptr = newlabtext;
}
else
newlabptr = lab->lab_text;
/* Do not repeat a label copy; check that the label doesn't */
/* already exist in the destination def first. */
if (DBCheckLabelsByContent(def, &r, lab->lab_type, lab->lab_text))
return 0;
if (DBCheckLabelsByContent(def, &r, lab->lab_type, newlabptr))
return 0;
DBEraseLabelsByContent(def, &r, -1, lab->lab_text);
DBPutFontLabel(def, &r, lab->lab_font, lab->lab_size, rotate, &offset,
pos, newlabptr, lab->lab_type, lab->lab_flags);
if (lab->lab_flags & PORT_DIR_MASK)
{
@@ -1024,6 +1046,13 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, destUse)
DBTreeSrTiles(scx, mask, xMask, dbcConnectFunc, (ClientData) &csa2);
while (csa2.csa2_top >= 0)
{
char pathstring[FLATTERMSIZE];
TerminalPath tpath;
tpath.tp_first = tpath.tp_next = pathstring;
tpath.tp_last = pathstring + FLATTERMSIZE;
pathstring[0] = '\0';
newmask = csa2.csa2_list[csa2.csa2_top].connectMask;
scx->scx_area = csa2.csa2_list[csa2.csa2_top].area;
newtype = csa2.csa2_list[csa2.csa2_top].dinfo;
@@ -1064,7 +1093,7 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, destUse)
searchtype |= TF_LABEL_ATTACH_NOT_SE;
}
}
DBTreeSrLabels(scx, newmask, xMask, NULL, searchtype,
DBTreeSrLabels(scx, newmask, xMask, &tpath, searchtype,
dbcConnectLabelFunc, (ClientData) &csa2);
}
freeMagic((char *)csa2.csa2_list);
+12 -4
View File
@@ -37,6 +37,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/
struct expandArg
{
bool ea_deref; /* TRUE if root def dereference flag is set */
int ea_xmask; /* Expand mask. */
int (*ea_func)(); /* Function to call for each cell whose
* status is changed.
@@ -81,7 +82,8 @@ DBExpand(cellUse, expandMask, expandFlag)
def = cellUse->cu_def;
if ((def->cd_flags & CDAVAILABLE) == 0)
{
if (!DBCellRead(def, (char *) NULL, TRUE, NULL))
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL))
return;
/* Note: we don't have to recompute the bbox here, because
* if it changed, then a timestamp violation must have occurred
@@ -142,9 +144,13 @@ DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
int dbExpandFunc(), dbUnexpandFunc();
SearchContext scontext;
struct expandArg arg;
bool dereference = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ?
TRUE : FALSE;
if ((rootUse->cu_def->cd_flags & CDAVAILABLE) == 0)
(void) DBCellRead(rootUse->cu_def, (char *) NULL, TRUE, NULL);
{
(void) DBCellRead(rootUse->cu_def, (char *) NULL, TRUE, dereference, NULL);
}
/*
* Walk through the area and set the expansion state
@@ -154,6 +160,7 @@ DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
arg.ea_xmask = expandMask;
arg.ea_func = func;
arg.ea_arg = cdarg;
arg.ea_deref = dereference;
scontext.scx_use = rootUse;
scontext.scx_trans = GeoIdentityTransform;
@@ -193,7 +200,7 @@ dbExpandFunc(scx, arg)
/* If the cell is unavailable, then don't expand it.
*/
if ((childUse->cu_def->cd_flags & CDAVAILABLE) == 0)
if(!DBCellRead(childUse->cu_def, (char *) NULL, TRUE, NULL))
if(!DBCellRead(childUse->cu_def, (char *) NULL, TRUE, arg->ea_deref, NULL))
{
TxError("Cell %s is unavailable. It could not be expanded.\n",
childUse->cu_def->cd_name);
@@ -303,7 +310,8 @@ dbReadAreaFunc(scx)
if ((def->cd_flags & CDAVAILABLE) == 0)
{
(void) DBCellRead(def, (char *) NULL, TRUE, NULL);
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
(void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL);
/* Note: we don't have to invoke DBReComputeBbox here because
* if the bbox changed then there was a timestamp mismatch and
* the timestamp code will take care of the bounding box later.
+66 -9
View File
@@ -264,7 +264,7 @@ file_is_not_writeable(name)
*/
bool
dbCellReadDef(f, cellDef, name, ignoreTech)
dbCellReadDef(f, cellDef, name, ignoreTech, dereference)
FILE *f; /* The file, already opened by the caller */
CellDef *cellDef; /* Pointer to definition of cell to be read in */
char *name; /* Name of file from which to read definition.
@@ -279,6 +279,7 @@ dbCellReadDef(f, cellDef, name, ignoreTech)
* names do not match, but an attempt will be
* made to read the file anyway.
*/
bool dereference; /* If TRUE, ignore path references in the input */
{
int cellStamp = 0, rectCount = 0, rectReport = 10000;
char line[2048], tech[50], layername[50];
@@ -437,7 +438,7 @@ dbCellReadDef(f, cellDef, name, ignoreTech)
*/
if (sscanf(line, "<< %s >>", layername) != 1)
{
if (!dbReadUse(cellDef, line, sizeof line, f, n, d))
if (!dbReadUse(cellDef, line, sizeof line, f, n, d, dereference))
goto badfile;
continue;
}
@@ -619,6 +620,9 @@ done:
}
}
}
/* Update timestamp flags */
DBFlagMismatches(cellDef);
cellDef->cd_timestamp = cellStamp;
if (cellStamp == 0)
{
@@ -860,7 +864,7 @@ DBReadBackup(name)
cellDef->cd_flags &= ~CDNOTFOUND;
cellDef->cd_flags |= CDAVAILABLE;
if (dbCellReadDef(f, cellDef, filename, TRUE) == FALSE)
if (dbCellReadDef(f, cellDef, filename, TRUE, FALSE) == FALSE)
return FALSE;
if (dbFgets(line, sizeof(line), f) == NULL)
@@ -869,6 +873,8 @@ DBReadBackup(name)
name);
return FALSE;
}
/* Update timestamp flags from dbCellReadDef() */
DBFlagMismatches(cellDef);
}
else
{
@@ -914,7 +920,7 @@ DBReadBackup(name)
*/
bool
DBCellRead(cellDef, name, ignoreTech, errptr)
DBCellRead(cellDef, name, ignoreTech, dereference, errptr)
CellDef *cellDef; /* Pointer to definition of cell to be read in */
char *name; /* Name of file from which to read definition.
* If NULL, then use cellDef->cd_file; if that
@@ -928,6 +934,7 @@ DBCellRead(cellDef, name, ignoreTech, errptr)
* names do not match, but an attempt will be
* made to read the file anyway.
*/
bool dereference; /* If TRUE then ignore path argument to uses */
int *errptr; /* Copy of errno set by file reading routine
* is placed here, unless NULL.
*/
@@ -945,7 +952,7 @@ DBCellRead(cellDef, name, ignoreTech, errptr)
else
{
result = (dbCellReadDef(f, cellDef, name, ignoreTech));
result = (dbCellReadDef(f, cellDef, name, ignoreTech, dereference));
#ifdef FILE_LOCKS
/* Close files that were locked by another user */
@@ -1188,13 +1195,14 @@ DBTestOpen(name, fullPath)
*/
bool
dbReadUse(cellDef, line, len, f, scalen, scaled)
dbReadUse(cellDef, line, len, f, scalen, scaled, dereference)
CellDef *cellDef; /* Cell whose cells are being read */
char *line; /* Line containing "use ..." */
int len; /* Size of buffer pointed to by line */
FILE *f; /* Input file */
int scalen; /* Multiply values in file by this */
int scaled; /* Divide values in file by this */
bool dereference; /* If TRUE, ignore path references */
{
int xlo, xhi, ylo, yhi, xsep, ysep, childStamp;
int absa, absb, absd, abse, nconv;
@@ -1225,7 +1233,7 @@ dbReadUse(cellDef, line, len, f, scalen, scaled)
pathptr = &path[0];
while (*pathptr == ' ' || *pathptr == '\t') pathptr++;
if (*pathptr == '\n') *pathptr = '\0';
if ((dereference == TRUE) || (*pathptr == '\n')) *pathptr = '\0';
locked = (useid[0] == CULOCKCHAR) ? TRUE : FALSE;
@@ -1432,9 +1440,22 @@ badTransform:
slashptr = strrchr(subCellDef->cd_file, '/');
if (slashptr != NULL)
{
bool pathOK = FALSE;
*slashptr = '\0';
if (strcmp(subCellDef->cd_file, pathptr))
/* Avoid generating error message if pathptr starts with '~' */
/* and the tilde-expanded name matches the subCellDef name */
if (*pathptr == '~')
{
char *homedir = getenv("HOME");
if (!strncmp(subCellDef->cd_file, homedir, strlen(homedir))
&& (!strcmp(subCellDef->cd_file + strlen(homedir),
pathptr + 1)))
pathOK = TRUE;
}
if ((pathOK == FALSE) && strcmp(subCellDef->cd_file, pathptr))
{
TxError("Duplicate cell in %s: Instance of cell %s is from "
"path %s but cell was previously read from %s.\n",
@@ -2345,6 +2366,8 @@ DBCellWriteFile(cellDef, f)
int reducer;
char *estring;
char lstring[256];
char *propvalue;
bool propfound;
#define FPRINTF(f,s)\
{\
@@ -2537,12 +2560,43 @@ DBCellWriteFile(cellDef, f)
}
/* And any properties */
/* NOTE: FIXED_BBOX is treated specially; values are database */
/* values and should be divided by reducer. Easiest to do it */
/* here and revert values after. */
propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &propfound);
if (propfound)
{
char *proporig, *propscaled;
Rect scalebox, bbox;
proporig = StrDup((char **)NULL, propvalue);
propscaled = mallocMagic(strlen(propvalue) + 5);
if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
&bbox.r_xtop, &bbox.r_ytop) == 4)
{
scalebox.r_xbot = bbox.r_xbot / reducer;
scalebox.r_xtop = bbox.r_xtop / reducer;
scalebox.r_ybot = bbox.r_ybot / reducer;
scalebox.r_ytop = bbox.r_ytop / reducer;
sprintf(propscaled, "%d %d %d %d",
bbox.r_xbot / reducer, bbox.r_ybot / reducer,
bbox.r_xtop / reducer, bbox.r_ytop / reducer);
DBPropPut(cellDef, "FIXED_BBOX", propscaled);
propvalue = proporig;
}
}
if (cellDef->cd_props != (ClientData)NULL)
{
FPRINTF(f, "<< properties >>\n");
DBPropEnum(cellDef, dbWritePropFunc, (ClientData)f);
}
if (propfound) DBPropPut(cellDef, "FIXED_BBOX", propvalue);
FPRINTF(f, "<< end >>\n");
if (fflush(f) == EOF || ferror(f))
@@ -2801,8 +2855,11 @@ DBCellWrite(cellDef, fileName)
#ifdef FILE_LOCKS
else
{
bool dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
/* Re-aquire the lock on the new file by opening it. */
DBCellRead(cellDef, NULL, TRUE, NULL);
DBCellRead(cellDef, NULL, TRUE, dereference, NULL);
}
#endif
}
+49 -6
View File
@@ -313,7 +313,55 @@ DBEraseLabel(cellDef, area, mask, areaReturn)
cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
return (erasedAny);
}
#define RECTEQUAL(r1, r2) ((r1)->r_xbot == (r2)->r_xbot \
&& (r1)->r_ybot == (r2)->r_ybot \
&& (r1)->r_xtop == (r2)->r_xtop \
&& (r1)->r_ytop == (r2)->r_ytop)
/*
* ----------------------------------------------------------------------------
*
* DBCheckLabelsByContent --
*
* Return any label found on the label list for the given
* CellDef that matches the given specification.
*
* Results:
* Returns a label if a match is found, otherwise returns NULL.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
Label *
DBCheckLabelsByContent(def, rect, type, text)
CellDef *def; /* Where to look for label to delete. */
Rect *rect; /* Coordinates of label. If NULL, then
* labels are searched regardless of coords.
*/
TileType type; /* Layer label is attached to. If < 0, then
* labels are searched regardless of type.
*/
char *text; /* Text associated with label. If NULL, then
* labels are searched regardless of text.
*/
{
Label *lab;
for (lab = def->cd_labels; lab; lab = lab->lab_next)
{
if ((rect != NULL) && !(RECTEQUAL(&lab->lab_rect, rect))) continue;
if ((type >= 0) && (type != lab->lab_type)) continue;
if ((text != NULL) && (strcmp(text, lab->lab_text) != 0)) continue;
return lab;
}
return NULL;
}
/*
* ----------------------------------------------------------------------------
*
@@ -348,11 +396,6 @@ DBEraseLabelsByContent(def, rect, type, text)
{
Label *lab, *labPrev;
#define RECTEQUAL(r1, r2) ((r1)->r_xbot == (r2)->r_xbot \
&& (r1)->r_ybot == (r2)->r_ybot \
&& (r1)->r_xtop == (r2)->r_xtop \
&& (r1)->r_ytop == (r2)->r_ytop)
for (labPrev = NULL, lab = def->cd_labels;
lab != NULL;
labPrev = lab, lab = lab->lab_next)
+26 -12
View File
@@ -294,20 +294,31 @@ DBTreeFindUse(name, use, scx)
* is read in from disk.
*/
if ((def->cd_flags & CDAVAILABLE) == 0)
(void) DBCellRead(def, (char *) NULL, TRUE, NULL);
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
(void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL);
}
/*
* Pull off the next component of path up to but not including
* any array subscripts.
*/
for (cp = name; *cp && *cp != '[' && *cp != '/'; cp++)
/* Nothing */;
csave = *cp;
*cp = '\0';
cp = name;
he = HashLookOnly(&def->cd_idHash, name);
*cp = csave;
if (he == NULL || HashGetValue(he) == NULL)
return;
{
/*
* Pull off the next component of path up to but not including
* any array subscripts.
* NOTE: This should check the array bounds and only remove
* array components that are expected, not array components
* embedded in the name.
*/
for (; *cp && *cp != '[' && *cp != '/'; cp++)
/* Nothing */;
csave = *cp;
*cp = '\0';
he = HashLookOnly(&def->cd_idHash, name);
*cp = csave;
if (he == NULL || HashGetValue(he) == NULL)
return;
}
use = (CellUse *) HashGetValue(he);
def = use->cu_def;
@@ -335,7 +346,10 @@ DBTreeFindUse(name, use, scx)
/* Ensure that the leaf cell is read in */
def = use->cu_def;
if ((def->cd_flags & CDAVAILABLE) == 0)
(void) DBCellRead(def, (char *) NULL, TRUE, NULL);
{
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
(void) DBCellRead(def, (char *) NULL, dereference, NULL);
}
scx->scx_use = use;
}
+17 -1
View File
@@ -66,11 +66,23 @@ DBPropPut(cellDef, name, value)
HashInit( (HashTable *) cellDef->cd_props, 8, 0);
}
htab = (HashTable *) cellDef->cd_props;
/* Special handling of FIXED_BBOX, which uses CDFIXEDBBOX as a quick lookup */
if (!strcmp(name, "FIXED_BBOX"))
{
if (value == (ClientData)NULL)
cellDef->cd_flags &= ~CDFIXEDBBOX;
else
cellDef->cd_flags |= CDFIXEDBBOX;
}
entry = HashFind(htab, name);
oldvalue = (char *)HashGetValue(entry);
if (oldvalue != NULL) freeMagic(oldvalue);
HashSetValue(entry, value);
if (value == (ClientData)NULL)
HashRemove(htab, name);
else
HashSetValue(entry, value);
}
/* ----------------------------------------------------------------------------
@@ -202,4 +214,8 @@ DBPropClearAll(cellDef)
HashKill(htab);
freeMagic((char *) htab);
cellDef->cd_props = (ClientData) NULL;
/* Since CDFIXEDBBOX requires a FIXED_BBOX property, clearing all */
/* properties necessarily means this flag must be clear. */
cellDef->cd_flags &= ~CDFIXEDBBOX;
}
+9 -8
View File
@@ -141,7 +141,7 @@ DBTechInitPlane()
for (dpp = dbTechDefaultPlanes; dpp->dp_names; dpp++)
{
cp = dbTechNameAdd(dpp->dp_names, (ClientData) dpp->dp_plane,
&dbPlaneNameLists);
&dbPlaneNameLists, FALSE);
if (cp == NULL)
{
TxError("DBTechInit: can't add plane names %s\n", dpp->dp_names);
@@ -224,7 +224,7 @@ DBTechInitType()
for (dtp = dbTechDefaultTypes; dtp->dt_names; dtp++)
{
cp = dbTechNameAdd(dtp->dt_names, (ClientData) dtp->dt_type,
&dbTypeNameLists);
&dbTypeNameLists, FALSE);
if (cp == NULL)
{
TxError("DBTechInit: can't add type names %s\n", dtp->dt_names);
@@ -283,7 +283,7 @@ DBTechAddPlane(sectionName, argc, argv)
return FALSE;
}
cp = dbTechNameAdd(argv[0], (ClientData) DBNumPlanes, &dbPlaneNameLists);
cp = dbTechNameAdd(argv[0], (ClientData) DBNumPlanes, &dbPlaneNameLists, FALSE);
if (cp == NULL)
return FALSE;
DBPlaneLongNameTbl[DBNumPlanes++] = cp;
@@ -315,7 +315,7 @@ DBTechAddNameToType(newname, ttype, canonical)
{
char *cp;
cp = dbTechNameAdd(newname, (ClientData) ttype, &dbTypeNameLists);
cp = dbTechNameAdd(newname, (ClientData) ttype, &dbTypeNameLists, TRUE);
if (canonical)
DBTypeLongNameTbl[ttype] = cp;
}
@@ -455,7 +455,7 @@ DBTechAddType(sectionName, argc, argv)
}
else
{
cp = dbTechNameAdd(argv[1], (ClientData) DBNumTypes, &dbTypeNameLists);
cp = dbTechNameAdd(argv[1], (ClientData) DBNumTypes, &dbTypeNameLists, FALSE);
if (cp == NULL)
return FALSE;
@@ -513,7 +513,7 @@ dbTechNewStackedType(type1, type2)
}
sprintf(buf, "%s+%s", DBTypeShortName(type1), DBTypeShortName(type2));
cp = dbTechNameAdd(buf, (ClientData) DBNumTypes, &dbTypeNameLists);
cp = dbTechNameAdd(buf, (ClientData) DBNumTypes, &dbTypeNameLists, FALSE);
if (cp == NULL)
{
TechError("Couldn't generate new stacking type %s\n", buf);
@@ -730,10 +730,11 @@ dbTechNameLookup(str, table)
*/
char *
dbTechNameAdd(name, cdata, ptable)
dbTechNameAdd(name, cdata, ptable, alias)
char *name; /* Comma-separated list of names to be added */
ClientData cdata; /* Value to be stored with each name above */
NameList *ptable; /* Table to which we will add names */
int alias; /* 1 if this is an alias (never make primary) */
{
char *cp;
char onename[BUFSIZ];
@@ -769,7 +770,7 @@ dbTechNameAdd(name, cdata, ptable)
}
}
if (primary)
if (primary && (alias == 0))
primary->sn_primary = TRUE;
return (first);
}
+28 -4
View File
@@ -126,6 +126,8 @@ DBFixMismatch()
while (mismatch != NULL)
{
bool dereference;
/* Be careful to remove the front element from the mismatch
* list before processing it, because while processing it we
* may add new elements to the list.
@@ -137,7 +139,8 @@ DBFixMismatch()
mismatch = mismatch->mm_next;
if (cellDef->cd_flags & CDPROCESSED) continue;
(void) DBCellRead(cellDef, (char *) NULL, TRUE, NULL);
dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
(void) DBCellRead(cellDef, (char *) NULL, TRUE, dereference, NULL);
/* Jimmy up the cell's current bounding box, so the following
* procedure call will absolutely and positively know that
@@ -267,6 +270,16 @@ dbStampFunc(cellDef)
* processing. When DBFixMismatch is called, it will notify
* the design-rule checker to recheck both wrongArea, and
* the cell's eventual correct area.
*
* This routine has been modified from a poor implementation. Previously
* the parent def of all uses of the cell being checked would be marked
* for a stamp mismatch check. However, when reading a cell with large
* numbers of instances, the list of instances would be parsed for every
* instance added, leading to an O(N^2) computation. Routine DBStampMismatch()
* has been broken into two parts. DBStampMismatch() only records the
* area to be checked. DBFlagMismatches() looks at the parents of each
* celldef only once, after all instances have been read.
*
* ----------------------------------------------------------------------------
*/
@@ -278,16 +291,27 @@ DBStampMismatch(cellDef, wrongArea)
*/
{
Mismatch *mm;
CellUse *parentUse;
mm = (Mismatch *) mallocMagic((unsigned) (sizeof (Mismatch)));
mm->mm_cellDef = cellDef;
mm->mm_oldArea = *wrongArea;
mm->mm_next = mismatch;
mismatch = mm;
}
for (parentUse = cellDef->cd_parents; parentUse != NULL;
parentUse = parentUse->cu_nextuse)
/*
* ----------------------------------------------------------------------------
* ----------------------------------------------------------------------------
*/
void
DBFlagMismatches(checkDef)
CellDef *checkDef;
{
CellUse *parentUse;
for (parentUse = checkDef->cd_parents; parentUse != NULL;
parentUse = parentUse->cu_nextuse)
{
if (parentUse->cu_parent == NULL) continue;
parentUse->cu_parent->cd_flags |= CDSTAMPSCHANGED;
+4
View File
@@ -396,6 +396,9 @@ typedef struct celldef
* with the option "gds readonly true".
* CDVISITED indicates that at least one instance of the cell was
* already output during a file write.
* CDDEREFERENCE is a flag indicating that when loading or expanding
* children of a cell, the path should be ignored and the cell
* path should be searched for the location.
*/
#define CDAVAILABLE 0x0001
@@ -413,6 +416,7 @@ typedef struct celldef
#define CDPROCESSEDGDS 0x1000
#define CDVENDORGDS 0x2000
#define CDVISITED 0x4000
#define CDDEREFERENCE 0x8000
/*
* Description of an array.
+1
View File
@@ -199,6 +199,7 @@ extern void DBUndoPutLabel();
extern void DBUndoEraseLabel();
extern void DBUndoCellUse();
extern void DBStampMismatch();
extern void DBFlagMismatches();
extern void DBTechAddNameToType();
extern void dbComputeBbox();