mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-09-07 11:31:01 +02:00
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:
+41
-10
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user