"Partly" corrected an issue in GDS read: The cd_client record is

used both for counting cells during GDS write and for saving
geometry data from the "copyup" operator during GDS read.  The write
routine does not clear the client record, and the read routine was
checking if the cd_client value was default.  Corrected the resulting
crash condition by resetting cd_client before GDS reads.  However, the
underlying problem is that the GDS read is reading data into a cell
that already exists in the database, and is not handling it robustly
by renaming the existing cell.  So this should be revisited.
This commit is contained in:
Tim Edwards 2020-11-20 19:56:41 -05:00
parent 0608784a18
commit b9f9f73c9b
5 changed files with 20 additions and 14 deletions

View File

@ -417,7 +417,7 @@ calmaParseStructure(filename)
/* If CDFLATGDS is already set, may need to remove */
/* existing planes and free memory. */
if ((cifReadCellDef->cd_client != (ClientData)CLIENTDEFAULT) &&
if ((cifReadCellDef->cd_client != (ClientData)0) &&
(cifReadCellDef->cd_flags & CDFLATGDS))
{
Plane **cifplanes = (Plane **)cifReadCellDef->cd_client;
@ -432,7 +432,7 @@ calmaParseStructure(filename)
}
}
freeMagic((char *)cifReadCellDef->cd_client);
cifReadCellDef->cd_client = (ClientData)CLIENTDEFAULT;
cifReadCellDef->cd_client = (ClientData)0;
}
TxPrintf("Saving contents of cell %s\n", cifReadCellDef->cd_name);
@ -917,8 +917,7 @@ calmaElementSref(filename)
for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++)
{
if ((def->cd_client != (ClientData)CLIENTDEFAULT) &&
(gdsplanes[pNum] != NULL))
if ((def->cd_client != (ClientData)0) && (gdsplanes[pNum] != NULL))
{
gdsCopyRec.plane = cifCurReadPlanes[pNum];
if (isArray)

View File

@ -98,8 +98,8 @@ calmaInputRescale(n, d)
{
/* Scale the GDS planes in this cell's cd_client record */
Plane **gdsplanes = (Plane **)def->cd_client;
/* Should not happen, but punt if client record is not set */
if (def->cd_client != (ClientData)CLIENTDEFAULT)
/* Should not happen, but punt if client record is not set; */
if (def->cd_client != (ClientData)0)
CIFScalePlanes(n, d, gdsplanes);
}
}

View File

@ -78,6 +78,7 @@ bool CalmaPostOrder = FALSE; /* If TRUE, forces the GDS parser to
* Added by Nishit 8/16/2004
*/
extern void calmaUnexpected();
extern int calmaWriteInitFunc();
bool calmaParseUnits();
@ -172,6 +173,12 @@ CalmaReadFile(file, filename)
CalmaPolygonCount = 0;
CalmaPathCount = 0;
/* Reset cd_client pointers (using init function from CalmaWrite.c) */
/* This is in case a cell already in memory is being referenced; */
/* it is probably better to avoid those kinds of naming collisions */
/* though. . . */
(void) DBCellSrDefs(0, calmaWriteInitFunc, (ClientData) NULL);
HashInit(&calmaDefInitHash, 32, 0);
calmaLApresent = FALSE;
calmaInputFile = file;

View File

@ -603,13 +603,13 @@ CIFPaintCurrent(filetype)
Plane **parray;
extern char *(cifReadLayers[MAXCIFRLAYERS]);
/* NOTE: There should be no need to check for cd_client
* here as cd_client should not be CLIENTDEFAULT if CDFLATGDS
* is set in flags. This condition has occurred, though, and
* needs to be debugged.
/* NOTE: The condition cd_client == 0 when CDFLATGDS
* indicates that the cell was already in memory when the
* GDS was read. This condition should be properly caught
* and handled.
*/
if ((cifReadCellDef->cd_flags & CDFLATGDS) &&
(cifReadCellDef->cd_client != (ClientData)CLIENTDEFAULT))
(cifReadCellDef->cd_client != (ClientData)0))
parray = (Plane **)cifReadCellDef->cd_client;
else
{
@ -1499,7 +1499,7 @@ CIFReadCellCleanup(filetype)
UndoDisable();
/* cifplanes should be valid, but don't crash magic if not */
if (cifplanes != (Plane **)CLIENTDEFAULT)
if (cifplanes != (Plane **)0)
{
for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++)
@ -1512,7 +1512,7 @@ CIFReadCellCleanup(filetype)
}
freeMagic((char *)def->cd_client);
}
def->cd_client = (ClientData)CLIENTDEFAULT;
def->cd_client = (ClientData)0;
#if 0
/* If the CDFLATTENED flag was not set, then this geometry */

View File

@ -3454,7 +3454,7 @@ CmdDrc(w, cmd)
}
#ifdef MAGIC_WRAPPER
if (count_total >= 0)
if ((count_total >= 0) || (!dolist))
{
if (dolist)
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(count_total));