From 0ae54b500a3effe68bdb93d76a599dc9d8eed830 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 29 Apr 2024 17:43:37 -0400 Subject: [PATCH] Added the ability to track the first CellDef to fail to read and report it after "Failure to read in entire sub-tree". This will not report every failing cell (since it quits reading after the first failure) but will avoid the existing issue of printing nothing and leaving the user with no feedback as to which cell was the problem. --- VERSION | 2 +- calma/CalmaWrite.c | 5 ++++- calma/CalmaWriteZ.c | 5 ++++- cif/CIFwrite.c | 5 ++++- database/DBexpand.c | 30 +++++++++++++++++------------- database/database.h.in | 2 +- drc/DRCmain.c | 5 ++++- extract/ExtMain.c | 16 ++++++++++++---- extract/ExtTimes.c | 10 ++++++++-- lef/lefWrite.c | 6 ++++-- 10 files changed, 59 insertions(+), 27 deletions(-) diff --git a/VERSION b/VERSION index 7299c228..1f0285c5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.474 +8.3.475 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 70e027a8..a9bb6fe2 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -302,6 +302,7 @@ CalmaWrite(rootDef, f) { int oldCount = DBWFeedbackCount, problems, nerr; bool good; + CellDef *err_def; CellUse dummy; HashEntry *he; HashSearch hs; @@ -327,9 +328,11 @@ CalmaWrite(rootDef, f) */ dummy.cu_def = rootDef; - if (DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined)) + err_def = DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined); + if (err_def != NULL) { TxError("Failure to read entire subtree of the cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return FALSE; } diff --git a/calma/CalmaWriteZ.c b/calma/CalmaWriteZ.c index 3890ceb7..16e717df 100644 --- a/calma/CalmaWriteZ.c +++ b/calma/CalmaWriteZ.c @@ -277,6 +277,7 @@ CalmaWriteZ(rootDef, f) { int oldCount = DBWFeedbackCount, problems, nerr; bool good; + CellDef *err_def; CellUse dummy; HashEntry *he; HashSearch hs; @@ -302,9 +303,11 @@ CalmaWriteZ(rootDef, f) */ dummy.cu_def = rootDef; - if (DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined)) + err_def = DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined); + if (err_def != NULL) { TxError("Failure to read entire subtree of the cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return FALSE; } diff --git a/cif/CIFwrite.c b/cif/CIFwrite.c index 66913719..64e427cc 100644 --- a/cif/CIFwrite.c +++ b/cif/CIFwrite.c @@ -124,6 +124,7 @@ CIFWrite(rootDef, f) { bool good; int oldCount = DBWFeedbackCount; + CellDef *err_def; CellUse dummy; /* @@ -133,9 +134,11 @@ CIFWrite(rootDef, f) */ dummy.cu_def = rootDef; - if (DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE)) + err_def = DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Failure to read in entire subtree of the cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return (FALSE); } DBFixMismatch(); diff --git a/database/DBexpand.c b/database/DBexpand.c index 8be1cb6f..9e35544f 100644 --- a/database/DBexpand.c +++ b/database/DBexpand.c @@ -274,8 +274,8 @@ dbUnexpandFunc(scx, arg) * the given rectangle. * * Results: - * If "halt_on_error" is TRUE, then return 1 if any subcell could not - * be read. Otherwise, return 0. + * If "halt_on_error" is TRUE, then return a pointer to the first + * subcell that could not be read. Otherwise, return NULL. * * Side effects: * May make new cells known to the database. Sets the CDAVAILABLE @@ -284,7 +284,7 @@ dbUnexpandFunc(scx, arg) * ---------------------------------------------------------------------------- */ -int +CellDef * DBCellReadArea(rootUse, rootRect, halt_on_error) CellUse *rootUse; /* Root cell use from which search begins */ Rect *rootRect; /* Area to be read, in root coordinates */ @@ -292,32 +292,37 @@ DBCellReadArea(rootUse, rootRect, halt_on_error) { int dbReadAreaFunc(); SearchContext scontext; + CellDef *err_def = NULL; scontext.scx_use = rootUse; scontext.scx_trans = GeoIdentityTransform; scontext.scx_area = *rootRect; - if (dbReadAreaFunc(&scontext, halt_on_error) == 1) - return 1; + if (dbReadAreaFunc(&scontext, ((halt_on_error == TRUE) ? &err_def : NULL)) == 1) + return err_def; - return 0; + return NULL; } int -dbReadAreaFunc(scx, halt_on_error) +dbReadAreaFunc(scx, err_ptr) SearchContext *scx; /* Pointer to context specifying * the cell use to be read in, and * an area to be recursively read in * coordinates of the cell use's def. */ - bool halt_on_error; /* If TRUE, failure to find a cell causes a halt */ + CellDef **err_ptr; /* If non-NULL, failure to find a cell causes a halt + * and the CellDef in error is returned in err_def. + */ { CellDef *def = scx->scx_use->cu_def; if ((def->cd_flags & CDAVAILABLE) == 0) { if (DBCellRead(def, TRUE, TRUE, NULL) == FALSE) - if (halt_on_error) - return 1; + { + *err_ptr = def; + return 1; + } /* Note: we don't have to invoke DBReComputeBbox here because * if the bbox changed then there was a timestamp mismatch and @@ -325,9 +330,8 @@ dbReadAreaFunc(scx, halt_on_error) */ } - if (DBCellSrArea(scx, dbReadAreaFunc, (ClientData)halt_on_error)) - if (halt_on_error) - return 1; + if (DBCellSrArea(scx, dbReadAreaFunc, (ClientData)err_ptr)) + return 1; /* Be clever about handling arrays: if the search area covers this * whole definition, then there's no need to look at any other diff --git a/database/database.h.in b/database/database.h.in index 0981d485..4e0bf5db 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -784,7 +784,7 @@ extern bool DBCellRead(); extern bool DBTestOpen(); extern char *DBGetTech(); extern bool DBCellWrite(); -extern int DBCellReadArea(); +extern CellDef *DBCellReadArea(); extern void DBFileRecovery(); extern bool DBWriteBackup(); extern bool DBReadBackup(); diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 81d337fb..7f485b59 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -692,11 +692,14 @@ DRCCheck(use, area) */ { SearchContext scx; + CellDef *err_def; extern int drcCheckFunc(); /* Forward reference. */ - if (DBCellReadArea(use, area, TRUE)) + err_def = DBCellReadArea(use, area, TRUE); + if (err_def != NULL) { TxError("Failure to read in entire subtree of cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; } diff --git a/extract/ExtMain.c b/extract/ExtMain.c index d05aad4b..464cfab7 100644 --- a/extract/ExtMain.c +++ b/extract/ExtMain.c @@ -361,11 +361,14 @@ ExtAll(rootUse) CellUse *rootUse; { LinkedDef *defList = NULL; + CellDef *err_def; /* Make sure the entire subtree is read in */ - if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + err_def = DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Failure to read entire subtree of cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; } @@ -460,15 +463,17 @@ ExtUnique(rootUse, option) CellUse *rootUse; int option; { - CellDef *def; + CellDef *def, *err_def; LinkedDef *defList = NULL; int nwarn; int locoption; /* Make sure the entire subtree is read in */ - if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + err_def = DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Failure to read entire subtree of cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; } @@ -857,11 +862,14 @@ ExtIncremental(rootUse) CellUse *rootUse; { LinkedDef *defList = NULL; + CellDef *err_def; /* Make sure the entire subtree is read in */ - if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + err_def = DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Failure to read entire subtree of cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; } diff --git a/extract/ExtTimes.c b/extract/ExtTimes.c index f4b42227..1f1d21e7 100644 --- a/extract/ExtTimes.c +++ b/extract/ExtTimes.c @@ -167,11 +167,14 @@ ExtTimes(rootUse, f) double clip, inter; HashSearch hs; HashEntry *he; + CellDef *err_def; /* Make sure this cell is read in */ - if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + err_def = DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Failure to read entire subtree of cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; } @@ -1022,11 +1025,14 @@ ExtInterCount(rootUse, halo, f) FILE *f; { double inter; + CellDef *err_def; /* Make sure this cell is read in */ - if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + err_def = DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Failure to read entire subtree of cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; } diff --git a/lef/lefWrite.c b/lef/lefWrite.c index ef90335c..968ee0f3 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -2178,7 +2178,7 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefPinOnly, lefTopLayer, bool recurse; { HashTable propHashTbl, siteHashTbl; - CellDef *def, *rootdef; + CellDef *def, *rootdef, *err_def; FILE *f; char *filename; float scale = CIFGetOutputScale(1000); /* conversion to microns */ @@ -2186,9 +2186,11 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefPinOnly, lefTopLayer, rootdef = rootUse->cu_def; /* Make sure the entire subtree is read in */ - if (DBCellReadArea(rootUse, &rootdef->cd_bbox, TRUE)) + err_def = DBCellReadArea(rootUse, &rootdef->cd_bbox, TRUE); + if (err_def != NULL) { TxError("Could not read entire subtree of the cell.\n"); + TxError("Failed on cell %s.\n", err_def->cd_name); return; }