From c1f4555ba055cb4d1808ed462dcae1aa373daa37 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 18 Apr 2023 11:01:58 -0400 Subject: [PATCH] Corrected behavior of "load ... -dereference" to bring back a previous behavior that had inadvertently been changed. In recent versions, "load -dereference" would incorrectly apply the dereferencing to rather than just its subcells. Cleaned up the code around DBCellRead() in the process, so everything is more straightforward (although probably more could be done in that regard). --- VERSION | 2 +- calma/CalmaWrite.c | 5 +--- calma/CalmaWriteZ.c | 5 +--- cif/CIFwrite.c | 6 ++--- commands/CmdCD.c | 5 ++-- commands/CmdE.c | 6 +---- commands/CmdSubrs.c | 4 +--- database/DBcellsrch.c | 53 +++++++++++++------------------------------ database/DBcellsubr.c | 7 ++---- database/DBexpand.c | 20 ++++++++-------- database/DBio.c | 20 ++++++++++++---- database/DBlabel2.c | 10 ++------ database/DBtimestmp.c | 5 +--- dbwind/DBWprocs.c | 15 ++++++++---- drc/DRCmain.c | 4 +--- extract/ExtInter.c | 12 ++++------ graphics/W3Dmain.c | 4 +--- lef/defRead.c | 5 +--- sim/SimDBstuff.c | 6 ++--- 19 files changed, 75 insertions(+), 119 deletions(-) diff --git a/VERSION b/VERSION index 1a106697..94572cb4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.391 +8.3.392 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index fe297041..abbcc9a7 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -891,11 +891,8 @@ calmaProcessDef(def, outf, do_library) /* Read the cell in if it is not already available. */ if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) + if (!DBCellRead(def, TRUE, TRUE, NULL)) return (0); - } /* * Flag an error if attempting to write the default (UNNAMED) cell diff --git a/calma/CalmaWriteZ.c b/calma/CalmaWriteZ.c index 650ad1db..7ecb46c7 100644 --- a/calma/CalmaWriteZ.c +++ b/calma/CalmaWriteZ.c @@ -842,11 +842,8 @@ calmaProcessDefZ(def, outf, do_library) /* Read the cell in if it is not already available. */ if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) + if (!DBCellRead(def, TRUE, TRUE, NULL)) return (0); - } /* * Flag an error if attempting to write the default (UNNAMED) cell diff --git a/cif/CIFwrite.c b/cif/CIFwrite.c index d5313a63..66913719 100644 --- a/cif/CIFwrite.c +++ b/cif/CIFwrite.c @@ -317,10 +317,8 @@ cifOut(outf) /* Read the cell in if it is not already available. */ if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) continue; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + continue; /* Add any subcells to the stack. This must be done before * outputting CIF to make sure that the subcells all have diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 4ca3caeb..a94fad1f 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -4644,7 +4644,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) { Point childPoint, editPoint, rootPoint; CellDef *def, *rootDef, *editDef; - bool hasChild, hasRoot, hasTrans, dereference; + bool hasChild, hasRoot, hasTrans; Rect rootBox, bbox; Transform *tx_cell, trans_cell; char **av; @@ -4740,8 +4740,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) * looked for then no new error message will be printed. */ def->cd_flags &= ~CDNOTFOUND; - dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) + if (!DBCellRead(def, TRUE, TRUE, NULL)) return (FALSE); DBReComputeBbox(def); dummy->cu_def = def; diff --git a/commands/CmdE.c b/commands/CmdE.c index 1197f09b..dcf45b0a 100644 --- a/commands/CmdE.c +++ b/commands/CmdE.c @@ -134,11 +134,7 @@ CmdEdit(w, cmd) return; } else if (!(EditCellUse->cu_def->cd_flags & CDAVAILABLE)) - { - bool dereference = (EditCellUse->cu_def->cd_flags & CDDEREFERENCE) ? - TRUE : FALSE; - DBCellRead(EditCellUse->cu_def, TRUE, dereference, NULL); - } + DBCellRead(EditCellUse->cu_def, TRUE, TRUE, NULL); if (EditCellUse->cu_def->cd_flags & CDNOEDIT) { diff --git a/commands/CmdSubrs.c b/commands/CmdSubrs.c index 692afce0..3c77ac7a 100644 --- a/commands/CmdSubrs.c +++ b/commands/CmdSubrs.c @@ -291,7 +291,6 @@ cmdFlushCell(def, force_deref) bool force_deref; { CellUse *parentUse; - bool dereference; if (def == NULL) return; @@ -324,8 +323,7 @@ cmdFlushCell(def, force_deref) } DBCellClearDef(def); DBCellClearAvail(def); - dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - (void) DBCellRead(def, TRUE, dereference, NULL); + (void) DBCellRead(def, TRUE, TRUE, NULL); DBCellSetAvail(def); DBReComputeBbox(def); DBCellSetModified(def, FALSE); diff --git a/database/DBcellsrch.c b/database/DBcellsrch.c index cceee44a..f527f84b 100644 --- a/database/DBcellsrch.c +++ b/database/DBcellsrch.c @@ -242,10 +242,8 @@ dbCellPlaneSrFunc(scx, fp) if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; context.tc_scx = scx; context.tc_filter = fp; @@ -364,10 +362,8 @@ dbCellUniqueTileSrFunc(scx, fp) if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; context.tc_scx = scx; context.tc_filter = fp; @@ -476,10 +472,8 @@ DBNoTreeSrTiles(scx, mask, xMask, func, cdarg) return 0; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; filter.tf_func = func; filter.tf_arg = cdarg; @@ -587,10 +581,8 @@ 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) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; for (lab = def->cd_labels; lab; lab = lab->lab_next) { @@ -694,10 +686,8 @@ dbCellLabelSrFunc(scx, fp) ASSERT(def != (CellDef *) NULL, "dbCellLabelSrFunc"); if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; /* Do not add a path name of a top level window */ if (strncmp(scx->scx_use->cu_id, "Topmost ", 8)) @@ -818,11 +808,8 @@ DBTreeSrCells(scx, xMask, func, cdarg) if (!DBDescendSubcell(cellUse, xMask)) return 0; if ((cellUse->cu_def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (cellUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(cellUse->cu_def, TRUE, dereference, NULL)) + if (!DBCellRead(cellUse->cu_def, TRUE, TRUE, NULL)) return 0; - } context.tc_scx = scx; context.tc_filter = &filter; @@ -866,11 +853,8 @@ dbTreeCellSrFunc(scx, fp) else { if ((use->cu_def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (use->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(use->cu_def, TRUE, dereference, NULL)) + if (!DBCellRead(use->cu_def, TRUE, TRUE, NULL)) return 0; - } } if (fp->tf_xmask == CU_DESCEND_ALL) { @@ -1126,12 +1110,8 @@ DBCellSrArea(scx, func, cdarg) context.tc_scx = scx; if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (scx->scx_use->cu_def->cd_flags & CDDEREFERENCE) ? - TRUE : FALSE; - if (!DBCellRead(scx->scx_use->cu_def, TRUE, dereference, NULL)) + if (!DBCellRead(scx->scx_use->cu_def, TRUE, TRUE, NULL)) return 0; - } if (DBSrCellPlaneArea(scx->scx_use->cu_def->cd_cellPlane, &scx->scx_area, dbCellSrFunc, (ClientData) &context)) @@ -1253,10 +1233,9 @@ DBCellEnum(cellDef, func, cdarg) filter.tf_func = func; filter.tf_arg = cdarg; if ((cellDef->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(cellDef, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(cellDef, TRUE, TRUE, NULL)) + return 0; + if (DBSrCellPlaneArea(cellDef->cd_cellPlane, &TiPlaneRect, dbEnumFunc, (ClientData) &filter)) return 1; diff --git a/database/DBcellsubr.c b/database/DBcellsubr.c index 52eacb24..ecddd710 100644 --- a/database/DBcellsubr.c +++ b/database/DBcellsubr.c @@ -76,12 +76,9 @@ DBDescendSubcell(use, xMask) case CU_DESCEND_NO_SUBCKT: if ((use->cu_def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (use->cu_def->cd_flags & CDDEREFERENCE) ? - TRUE : FALSE; - if (!DBCellRead(use->cu_def, TRUE, dereference, NULL)) + if (!DBCellRead(use->cu_def, TRUE, TRUE, NULL)) return FALSE; - } + return (DBIsSubcircuit(use->cu_def)) ? FALSE : TRUE; case CU_DESCEND_NO_LOCK: diff --git a/database/DBexpand.c b/database/DBexpand.c index 2f076791..8be1cb6f 100644 --- a/database/DBexpand.c +++ b/database/DBexpand.c @@ -82,8 +82,7 @@ DBExpand(cellUse, expandMask, expandFlag) def = cellUse->cu_def; if ((def->cd_flags & CDAVAILABLE) == 0) { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) + if (!DBCellRead(def, TRUE, TRUE, NULL)) return; /* Note: we don't have to recompute the bbox here, because * if it changed, then a timestamp violation must have occurred @@ -144,13 +143,9 @@ 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, TRUE, dereference, NULL); - } + (void) DBCellRead(rootUse->cu_def, TRUE, TRUE, NULL); /* * Walk through the area and set the expansion state @@ -160,7 +155,7 @@ DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg) arg.ea_xmask = expandMask; arg.ea_func = func; arg.ea_arg = cdarg; - arg.ea_deref = dereference; + arg.ea_deref = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; scontext.scx_use = rootUse; scontext.scx_trans = GeoIdentityTransform; @@ -200,12 +195,16 @@ 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, TRUE, arg->ea_deref, NULL)) + { + /* If the parent is dereferenced, then the child should be, too */ + if (arg->ea_deref) childUse->cu_def->cd_flags |= CDDEREFERENCE; + if(!DBCellRead(childUse->cu_def, TRUE, TRUE, NULL)) { TxError("Cell %s is unavailable. It could not be expanded.\n", childUse->cu_def->cd_name); return 2; } + } childUse->cu_expandMask |= arg->ea_xmask; if (arg->ea_func != NULL) @@ -316,8 +315,7 @@ dbReadAreaFunc(scx, halt_on_error) if ((def->cd_flags & CDAVAILABLE) == 0) { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (DBCellRead(def, TRUE, dereference, NULL) == FALSE) + if (DBCellRead(def, TRUE, TRUE, NULL) == FALSE) if (halt_on_error) return 1; diff --git a/database/DBio.c b/database/DBio.c index eb984cb3..5bc9bc9e 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -1198,25 +1198,37 @@ DBCellRead(cellDef, ignoreTech, dereference, 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 */ + bool dereference; /* If TRUE then ignore path argument to cellDef */ int *errptr; /* Copy of errno set by file reading routine * is placed here, unless NULL. */ { FILETYPE f; - bool result; + bool result, usederef, locderef; if (errptr != NULL) *errptr = 0; + /* NOTE: "dereference" indicates whether or not to dereference + * the cellDef itself. To determine if subcells of cellDef + * should be dereferenced, use the CDDEREFERENCE flag in the + * cellDef. + */ + usederef = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; + /* "locderef" indicates whether or not to use the CDDEREFERENCE + * for the cellDef itself. If dereference is FALSE, then never + * dereference. Otherwise, follow the flag value. + */ + locderef = (dereference == TRUE) ? usederef : FALSE; + if (cellDef->cd_flags & CDAVAILABLE) result = TRUE; - else if ((f = dbReadOpen(cellDef, TRUE, dereference, errptr)) == NULL) + else if ((f = dbReadOpen(cellDef, TRUE, locderef, errptr)) == NULL) result = FALSE; else { - result = (dbCellReadDef(f, cellDef, ignoreTech, dereference)); + result = (dbCellReadDef(f, cellDef, ignoreTech, usederef)); #ifdef FILE_LOCKS /* Close files that were locked by another user */ diff --git a/database/DBlabel2.c b/database/DBlabel2.c index 6113dbec..b43d01ef 100644 --- a/database/DBlabel2.c +++ b/database/DBlabel2.c @@ -294,10 +294,7 @@ DBTreeFindUse(name, use, scx) * is read in from disk. */ if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - (void) DBCellRead(def, TRUE, dereference, NULL); - } + (void) DBCellRead(def, TRUE, TRUE, NULL); cp = name; he = HashLookOnly(&def->cd_idHash, name); @@ -346,10 +343,7 @@ DBTreeFindUse(name, use, scx) /* Ensure that the leaf cell is read in */ def = use->cu_def; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - (void) DBCellRead(def, TRUE, dereference, NULL); - } + DBCellRead(def, TRUE, TRUE, NULL); scx->scx_use = use; } diff --git a/database/DBtimestmp.c b/database/DBtimestmp.c index 3172e7c7..1c27fc3d 100644 --- a/database/DBtimestmp.c +++ b/database/DBtimestmp.c @@ -130,8 +130,6 @@ 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. @@ -143,8 +141,7 @@ DBFixMismatch() mismatch = mismatch->mm_next; if (cellDef->cd_flags & CDPROCESSED) continue; - dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - (void) DBCellRead(cellDef, TRUE, dereference, NULL); + (void) DBCellRead(cellDef, TRUE, TRUE, NULL); /* Jimmy up the cell's current bounding box, so the following * procedure call will absolutely and positively know that diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index c22d35dd..8cb504d4 100644 --- a/dbwind/DBWprocs.c +++ b/dbwind/DBWprocs.c @@ -471,15 +471,22 @@ DBWloadWindow(window, name, flags) newEditDef = DBCellNewDef(rootname); } - /* If the name differs from the root name, then set the file */ - /* path to be the same as "name". */ + /* If dereferencing, set the appropriate flag in newEditDef. */ if (dereference) newEditDef->cd_flags |= CDDEREFERENCE; - else if ((newEditDef->cd_file == NULL) && strcmp(name, rootname)) + + /* If the name differs from the root name, then set the file */ + /* path to be the same as "name". */ + + if ((newEditDef->cd_file == NULL) && strcmp(name, rootname)) newEditDef->cd_file = StrDup((char **)NULL, name); - if (!DBCellRead(newEditDef, ignoreTech, dereference, &error_val)) + /* A cell name passed on the "load" command line is never + * dereferenced itself; "dereference" applies only to its + * (unloaded) descendents. + */ + if (!DBCellRead(newEditDef, ignoreTech, FALSE, &error_val)) { if (error_val == ENOENT) { diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 7e0f0dc0..87441cf8 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -966,15 +966,13 @@ drcFindFunc(scx, finddata) CellDef *def; HashEntry *h; int drcFindFunc2(); - bool dereference; def = scx->scx_use->cu_def; h = HashFind(finddata->deft, (char *)def); if (HashGetValue(h) != 0) return 0; HashSetValue(h, 1); - dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - (void) DBCellRead(def, TRUE, dereference, NULL); + (void) DBCellRead(def, TRUE, TRUE, NULL); if (DBSrPaintArea((Tile *) NULL, def->cd_planes[PL_DRC_ERROR], &def->cd_bbox, &DBAllButSpaceBits, drcFindFunc2, diff --git a/extract/ExtInter.c b/extract/ExtInter.c index c5783490..aa302daa 100644 --- a/extract/ExtInter.c +++ b/extract/ExtInter.c @@ -424,10 +424,8 @@ extTreeSrPaintArea(scx, func, cdarg) int pNum; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; filter.tf_func = func; filter.tf_arg = cdarg; @@ -464,10 +462,8 @@ extTreeSrFunc(scx, fp) int pNum; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return (0); - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; context.tc_scx = scx; context.tc_filter = fp; diff --git a/graphics/W3Dmain.c b/graphics/W3Dmain.c index 964003db..26e33325 100644 --- a/graphics/W3Dmain.c +++ b/graphics/W3Dmain.c @@ -1392,14 +1392,12 @@ W3DloadWindow(window, name) CellDef *newEditDef; CellUse *newEditUse; Rect loadBox; - bool dereference; newEditDef = DBCellLookDef(name); if (newEditDef == (CellDef *)NULL) return FALSE; - dereference = (newEditDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(newEditDef, TRUE, dereference, NULL)) + if (!DBCellRead(newEditDef, TRUE, TRUE, NULL)) return FALSE; DBReComputeBbox(newEditDef); diff --git a/lef/defRead.c b/lef/defRead.c index 7cf50622..3efa5225 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -2214,15 +2214,12 @@ DefReadComponents(f, rootDef, sname, oscale, total) if (defMacro == (CellDef *)NULL) { - bool dereference; - /* Before giving up, assume that this cell has a */ /* magic .mag layout file. */ defMacro = DBCellNewDef(token); defMacro->cd_flags &= ~CDNOTFOUND; - dereference = (defMacro->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(defMacro, TRUE, dereference, NULL)) + if (!DBCellRead(defMacro, TRUE, TRUE, NULL)) { LefError(DEF_ERROR, "Cell %s is not defined. Maybe you " "have not read the corresponding LEF file?\n", diff --git a/sim/SimDBstuff.c b/sim/SimDBstuff.c index 2ae46c1d..1c74f950 100644 --- a/sim/SimDBstuff.c +++ b/sim/SimDBstuff.c @@ -760,10 +760,8 @@ SimCellTileSrFunc(scx, fp) if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0; if ((def->cd_flags & CDAVAILABLE) == 0) - { - bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - if (!DBCellRead(def, TRUE, dereference, NULL)) return 0; - } + if (!DBCellRead(def, TRUE, TRUE, NULL)) + return 0; context.tc_scx = scx; context.tc_filter = fp;