From b62efea43df54a08d3a928d90378d7c68f499dd7 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 25 Feb 2020 09:52:06 -0500 Subject: [PATCH 1/2] Corrected the last commit for fixing the "drc count" command option, which had been changed a few months back to remove the individual cell count and only list the top level cell. The behavior has been changed a bit so that "list" returns values for the top level cell only, but "listall" returns a complete list. "drc list count total" gives the DRC count for the top cell, but "drc listall count total" gives the DRC count for everything (probably not very useful). Also: Implemented a behavior by request to automatically removed the (UNNAMED) cell whenever a new cell is loaded and the (UNNAMED) cell has not been modified. --- VERSION | 2 +- commands/CmdCD.c | 2 +- dbwind/DBWprocs.c | 22 +++++++++++++++++++++- drc/DRCmain.c | 19 ++++++++++++++++++- windows/windMove.c | 1 + 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 6022050e..8ca3c547 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.2.187 +8.2.188 diff --git a/commands/CmdCD.c b/commands/CmdCD.c index d91da3a6..0d31dff3 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -3322,7 +3322,7 @@ CmdDrc(w, cmd) rootArea = w->w_surfaceArea; rootUse = (CellUse *) window->w_surfaceID; - dcl = DRCCount(rootUse, &rootArea); + dcl = DRCCount(rootUse, &rootArea, doforall); while (dcl != NULL) { if (count_total >= 0) diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index 95458ec0..2bf4fca1 100644 --- a/dbwind/DBWprocs.c +++ b/dbwind/DBWprocs.c @@ -289,13 +289,14 @@ DBWloadWindow(window, name, ignoreTech, expand, dereference) bool expand; /* Indicates whether or not to expand the cell */ bool dereference; /* If TRUE, ignore path references in the input */ { - CellDef *newEditDef; + CellDef *newEditDef, *deleteDef; CellUse *newEditUse; void DisplayWindow(); int res, newEdit, error_val; int xadd, yadd; Rect loadBox; char *rootname; + bool isUnnamed; int UnexpandFunc(); /* forward declaration */ loadBox.r_xbot = loadBox.r_ybot = 0; @@ -305,6 +306,19 @@ DBWloadWindow(window, name, ignoreTech, expand, dereference) newEdit = !WindSearch((WindClient) DBWclientID, (ClientData) NULL, (Rect *) NULL, dbwLoadFunc, (ClientData) window); + /* The (UNNAMED) cell generally gets in the way, so delete it if */ + /* any new cell is loaded and (UNNAMED) has no contents. */ + + if (window->w_surfaceID == (ClientData)NULL) + deleteDef = NULL; + else + { + deleteDef = ((CellUse *)window->w_surfaceID)->cu_def; + if (strcmp(deleteDef->cd_name, "(UNNAMED)") || + deleteDef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED)) + deleteDef = NULL; + } + if ((name == (char *) NULL) || (name[0] == '\0')) { /* @@ -503,6 +517,12 @@ DBWloadWindow(window, name, ignoreTech, expand, dereference) if (newEdit) DBWAreaChanged(newEditDef, &newEditDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); + + /* If the cell before loading was (UNNAMED) and it was */ + /* never modified, then delete it now. */ + + if (deleteDef != NULL) + DBCellDelete(deleteDef->cd_name, TRUE); } /* This function is called for each cell whose expansion status changed. diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 2b365224..09d6e2d9 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -748,9 +748,10 @@ drcCheckFunc(scx, cdarg) */ DRCCountList * -DRCCount(use, area) +DRCCount(use, area, recurse) CellUse *use; /* Top-level use of hierarchy. */ Rect *area; /* Area in which violations are counted. */ + bool recurse; /* If TRUE, count errors in all subcells */ { DRCCountList *dcl, *newdcl; HashTable dupTable; @@ -761,12 +762,19 @@ DRCCount(use, area) CellDef *def; extern int drcCountFunc(); + /* Shouldn't happen? */ + if (!(use->cu_def->cd_flags & CDAVAILABLE)) return NULL; + /* Use a hash table to make sure that we don't output information * for any cell more than once. */ HashInit(&dupTable, 16, HT_WORDKEYS); + /* Clearing CDAVAILABLE from cd_flags keeps the count from recursing */ + if (recurse == FALSE) + use->cu_def->cd_flags &= ~CDAVAILABLE; + scx.scx_use = use; scx.scx_x = use->cu_xlo; scx.scx_y = use->cu_ylo; @@ -794,6 +802,11 @@ DRCCount(use, area) } } HashKill(&dupTable); + + /* Restore the CDAVAILABLE flag */ + if (recurse == FALSE) + use->cu_def->cd_flags |= CDAVAILABLE; + return dcl; } @@ -833,6 +846,10 @@ drcCountFunc(scx, dupTable) if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0) return 0; + /* Scan children recursively. */ + + DBCellSrArea(scx, drcCountFunc, (ClientData)dupTable); + /* As a special performance hack, if the complete cell area is * handled here, don't bother to look at any more array elements. */ diff --git a/windows/windMove.c b/windows/windMove.c index 0f91b5f4..d1420ef8 100644 --- a/windows/windMove.c +++ b/windows/windMove.c @@ -290,6 +290,7 @@ WindCreate(client, frameArea, isHint, argc, argv) w->w_grdata2 = (ClientData) NULL; w->w_backingStore = (ClientData)NULL; w->w_redrawAreas = (ClientData) NULL; + w->w_surfaceID = (ClientData) NULL; w->w_iconname = NULL; for (id = 0; ((1 << id) & windWindowMask) != 0; id++) /* advance id */ ; windWindowMask |= (1 << id); From 2beb5ee0e9412870fec76c92464477b79d5f28bc Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 25 Feb 2020 13:57:41 -0500 Subject: [PATCH 2/2] Modified the handling of "why" strings in the DRC mechanism, so that DRC records contain an index into a string array instead of containing a copy of a string. This is preliminary to changing the way the DRC error plane is painted, so that the types painted will mark the error type. This will (1) allow "drc why" to simply scan the DRC error plane rather than running the DRC engine, (2) allow DRC errors to be counted by area rather than by tile, and (3) let the DRC count be the same whether done by "drc listall why" or "drc count". --- drc/DRCarray.c | 2 +- drc/DRCbasic.c | 2 +- drc/DRCcif.c | 9 ++- drc/DRCmain.c | 49 ++++++++-------- drc/DRCsubcell.c | 2 +- drc/DRCtech.c | 142 ++++++++++++++++++++++++++++++----------------- drc/drc.h | 28 ++++------ 7 files changed, 130 insertions(+), 104 deletions(-) diff --git a/drc/DRCarray.c b/drc/DRCarray.c index 75039503..4e1aa133 100644 --- a/drc/DRCarray.c +++ b/drc/DRCarray.c @@ -46,7 +46,7 @@ static DRCCookie drcArrayCookie = { 0, 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, - "This layer can't abut or partially overlap between array elements", + DRC_ARRAY_OVERLAP_TAG, (DRCCookie *) NULL }; diff --git a/drc/DRCbasic.c b/drc/DRCbasic.c index 77ecd09b..a25b51ec 100644 --- a/drc/DRCbasic.c +++ b/drc/DRCbasic.c @@ -47,7 +47,7 @@ static DRCCookie drcOverlapCookie = { 0, 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, - "Can't overlap those layers", + DRC_OVERLAP_TAG, (DRCCookie *) NULL }; diff --git a/drc/DRCcif.c b/drc/DRCcif.c index 477ae23f..e3382fc5 100644 --- a/drc/DRCcif.c +++ b/drc/DRCcif.c @@ -48,7 +48,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "utils/malloc.h" #include "utils/utils.h" -extern char *drcWhyDup(); extern int drcCifTile(); extern int areaCifCheck(); extern void drcCheckCifMaxwidth(); @@ -169,7 +168,7 @@ drcCifWidth(argc, argv) char *layername = argv[1]; int scalefactor; int centidistance = atoi(argv[2]); - char *why = drcWhyDup(argv[3]); + int why = drcWhyCreate(argv[3]); TileTypeBitMask set, setC, tmp1; int thislayer = -1; DRCCookie *dpnew,*dpnext; @@ -228,7 +227,7 @@ drcCifSpacing(argc, argv) char *argv[]; { char *adjacency = argv[4]; - char *why = drcWhyDup(argv[5]); + int why = drcWhyCreate(argv[5]); DRCCookie *dpnext, *dpnew; int needReverse = FALSE; TileType i, j; @@ -1065,7 +1064,7 @@ drcCifArea(argc, argv) char *layers = argv[1]; int centiarea = atoi(argv[2]); int centihorizon = atoi(argv[3]); - char *why = drcWhyDup(argv[4]); + int why = drcWhyCreate(argv[4]); TileTypeBitMask set, setC, tmp1; DRCCookie *dpnext, *dpnew; TileType i, j; @@ -1126,7 +1125,7 @@ drcCifMaxwidth(argc, argv) char *layers = argv[1]; int centidistance = atoi(argv[2]); char *bends = argv[3]; - char *why = drcWhyDup(argv[4]); + int why = drcWhyCreate(argv[4]); TileTypeBitMask set, setC, tmp1; DRCCookie *dpnext, *dpnew; TileType i, j; diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 09d6e2d9..6bb67818 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -69,9 +69,8 @@ TileType DRCErrorType; /* Type of error tile to paint. */ /* Used by drcPrintError: */ -HashTable DRCErrorTable; /* Hash table used to eliminate duplicate - * error strings. - */ +int *DRCErrorList; /* List of DRC error type counts */ +HashTable DRCErrorTable; /* Table of DRC errors and geometry */ /* Global variables used by all DRC modules to record statistics. * For each statistic we keep two values, the count since stats @@ -183,11 +182,12 @@ drcSubstitute (cptr) DRCCookie * cptr; /* Design rule violated */ { static char *why_out = NULL; - char *whyptr = cptr->drcc_why, *sptr, *wptr; + char *whyptr, *sptr, *wptr; int subscnt = 0, whylen; float oscale, value; extern float CIFGetOutputScale(); + whyptr = DRCCurStyle->DRCWhyList[cptr->drcc_tag]; while ((sptr = strchr(whyptr, '%')) != NULL) { subscnt++; @@ -195,7 +195,7 @@ drcSubstitute (cptr) } if (subscnt == 0) return whyptr; /* No substitutions */ - whyptr = cptr->drcc_why; + whyptr = DRCCurStyle->DRCWhyList[cptr->drcc_tag]; whylen = strlen(whyptr) + 20 * subscnt; if (why_out != NULL) freeMagic(why_out); why_out = (char *)mallocMagic(whylen * sizeof(char)); @@ -256,7 +256,7 @@ drcSubstitute (cptr) * * Side effects: * DRCErrorCount is incremented. The text associated with - * the error is entered into DRCErrorTable, and, if this is + * the error is entered into DRCErrorList, and, if this is * the first time that entry has been seen, then the error * text is printed. If the area parameter is non-NULL, then * only errors intersecting that area are considered. @@ -279,12 +279,11 @@ drcPrintError (celldef, rect, cptr, scx) area = &scx->scx_area; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; DRCErrorCount += 1; - h = HashFind(&DRCErrorTable, cptr->drcc_why); - i = (spointertype) HashGetValue(h); + + i = DRCErrorList[cptr->drcc_tag]; if (i == 0) TxPrintf("%s\n", drcSubstitute(cptr)); - i++; - HashSetValue(h, (spointertype)i); + DRCErrorList[cptr->drcc_tag] = i + 1; } /* Same routine as above, but output goes to a Tcl list and is appended */ @@ -308,8 +307,7 @@ drcListError (celldef, rect, cptr, scx) area = &scx->scx_area; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; DRCErrorCount += 1; - h = HashFind(&DRCErrorTable, cptr->drcc_why); - i = (spointertype) HashGetValue(h); + i = DRCErrorList[cptr->drcc_tag]; if (i == 0) { Tcl_Obj *lobj; @@ -318,8 +316,7 @@ drcListError (celldef, rect, cptr, scx) Tcl_NewStringObj(drcSubstitute(cptr), -1)); Tcl_SetObjResult(magicinterp, lobj); } - i += 1; - HashSetValue(h, (spointertype)i); + DRCErrorList[cptr->drcc_tag] = i + 1; } /* Same routine as above, but output for every single error is recorded */ @@ -475,11 +472,15 @@ DRCWhy(dolist, use, area) { SearchContext scx; Rect box; + int i; extern int drcWhyFunc(); /* Forward reference. */ - /* Create a hash table to used for eliminating duplicate messages. */ + /* Create a hash table to eliminate duplicate messages. */ + + DRCErrorList = (int *)mallocMagic((DRCCurStyle->DRCWhySize + 1) * sizeof(int)); + for (i = 0; i <= DRCCurStyle->DRCWhySize; i++) + DRCErrorList[i] = 0; - HashInit(&DRCErrorTable, 16, HT_STRINGKEYS); DRCErrorCount = 0; box = DRCdef->cd_bbox; @@ -494,12 +495,9 @@ DRCWhy(dolist, use, area) drcWhyFunc(&scx, (pointertype)dolist); UndoEnable(); - /* Delete the hash table now that we're finished (otherwise there - * will be a core leak. - */ - - HashKill(&DRCErrorTable); - + /* Delete the error list */ + freeMagic(DRCErrorList); + /* Redisplay the DRC yank definition in case anyone is looking * at it. */ @@ -532,7 +530,7 @@ DRCWhyAll(use, area, fout) HashEntry *he; Tcl_Obj *lobj, *robj; - /* Create a hash table to used for eliminating duplicate messages. */ + /* Create a hash table for storing all of the results */ HashInit(&DRCErrorTable, 16, HT_STRINGKEYS); DRCErrorCount = 0; @@ -566,10 +564,7 @@ DRCWhyAll(use, area, fout) } Tcl_SetObjResult(magicinterp, robj); - /* Delete the hash table now that we're finished (otherwise there - * will be a core leak. - */ - + /* Delete the error table now that we're finished */ HashKill(&DRCErrorTable); /* Redisplay the DRC yank definition in case anyone is looking diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index 53eca616..7688a826 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -59,7 +59,7 @@ static DRCCookie drcSubcellCookie = { 0, 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, - "This layer can't abut or partially overlap between subcells", + DRC_SUBCELL_OVERLAP_TAG, (DRCCookie *) NULL }; diff --git a/drc/DRCtech.c b/drc/DRCtech.c index dd49a0d4..48009a51 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -61,6 +61,11 @@ global int DRCRuleOptimization = TRUE; static int drcRulesSpecified = 0; static int drcRulesOptimized = 0; +/* Rules with unique names are tagged with a reference number */ +/* for use in placing errors into the DRC error plane. */ + +static int DRCtag = 0; + /* * Forward declarations. */ @@ -281,21 +286,14 @@ drcTechFreeStyle() dp = DRCCurStyle->DRCRulesTbl[i][j]; while (dp != NULL) { - char *old = (char *) dp; + char *old = (char *)dp; dp = dp->drcc_next; freeMagic(old); } } - /* Clear the DRCWhyList */ - - while (DRCCurStyle->DRCWhyList != NULL) - { - old = (char *) DRCCurStyle->DRCWhyList; - StrDup(&(DRCCurStyle->DRCWhyList->dwl_string), (char *) NULL); - DRCCurStyle->DRCWhyList = DRCCurStyle->DRCWhyList->dwl_next; - freeMagic(old); - } + /* Clear the Why string list */ + freeMagic(DRCCurStyle->DRCWhyList); freeMagic(DRCCurStyle); DRCCurStyle = NULL; @@ -329,31 +327,54 @@ drcTechNewStyle() /* * ---------------------------------------------------------------------------- - * drcWhyDup -- + * drcWhyCreate -- * - * Duplicate a shared "why" string using StrDup() and remember it so we can - * free it sometime later, in drcWhyClear(). + * Create a hash entry for the DRC "why" string, if it does not already + * exist. * * Returns: - * A copy of the given string. + * A pointer to the drcWhy structure containing the string and tag. * * Side effects: - * Adds to the DRCWhyList. Calls StrDup(). + * Adds to the DRCWhyList if whystring has not been used before. + * Calls StrDup() and increments DRCWhySize. DRCWhyList is allocated + * in blocks of 50 at a time and only expands when filled. + * Temporary hash table DRCErrorTable is used to determine if a + * string entry is unique. It is cleared after the technology file + * has been processed. * ---------------------------------------------------------------------------- */ -char * -drcWhyDup(why) - char * why; +int +drcWhyCreate(whystring) + char *whystring; { - struct drcwhylist * new; + HashEntry *he; - new = (struct drcwhylist *) mallocMagic((unsigned) (sizeof *new)); - new->dwl_string = StrDup((char **) NULL, why); - new->dwl_next = DRCCurStyle->DRCWhyList; - DRCCurStyle->DRCWhyList = new; + he = HashLookOnly(&DRCErrorTable, whystring); + if (he != NULL) + return (int)((pointertype)HashGetValue(he)); - return new->dwl_string; + /* Grow the list in increments of 50 */ + if ((DRCCurStyle->DRCWhySize % 50) == 0) + { + int i; + char **newList; + newList = (char **)mallocMagic((DRCCurStyle->DRCWhySize + 51) * sizeof(char *)); + for (i = 0; i < DRCCurStyle->DRCWhySize; i++) + newList[i] = DRCCurStyle->DRCWhyList[i]; + if (DRCCurStyle->DRCWhySize > 0) + freeMagic((char *)DRCCurStyle->DRCWhyList); + DRCCurStyle->DRCWhyList = newList; + } + DRCCurStyle->DRCWhySize++; + + he = HashFind(&DRCErrorTable, whystring); + HashSetValue(he, (char *)((pointertype)DRCCurStyle->DRCWhySize)); + + DRCCurStyle->DRCWhyList[DRCCurStyle->DRCWhySize] = StrDup((char **)NULL, whystring); + + return DRCCurStyle->DRCWhySize; } /* @@ -535,12 +556,29 @@ DRCTechStyleInit() DRCCurStyle->ds_status = TECH_NOT_LOADED; TTMaskZero(&DRCCurStyle->DRCExactOverlapTypes); - DRCCurStyle->DRCWhyList = NULL; DRCCurStyle->DRCTechHalo = 0; DRCCurStyle->DRCScaleFactorN = 1; DRCCurStyle->DRCScaleFactorD = 1; DRCCurStyle->DRCStepSize = 0; DRCCurStyle->DRCFlags = (char)0; + DRCCurStyle->DRCWhySize = 0; + + HashInit(&DRCErrorTable, 16, HT_STRINGKEYS); + + /* First DRC entry is associated with the statically-allocated */ + /* drcArrayCookie and has a tag of DRC_ARRAY_OVERLAP_TAG = 1 */ + /* (see DRCarray.c). */ + drcWhyCreate("This layer can't abut or partially overlap between array elements"); + + /* Second DRC entry is associated with the statically-allocated */ + /* drcOverlapCookie and has a tag of DRC_OVERLAP_TAG = 2 */ + /* (see DRCbasic.c). */ + drcWhyCreate("Can't overlap those layers"); + + /* Third DRC entry is associated with the statically-allocated */ + /* drcSubcellCookie and has a tag of DRC_SUBCELL_OVERLAP_TAG = 3 */ + /* (see DRCsubcell.c). */ + drcWhyCreate("This layer can't abut or partially overlap between subcells"); DRCTechHalo = 0; @@ -872,18 +910,18 @@ DRCTechLine(sectionName, argc, argv) } void -drcCifAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefrom) +drcCifAssign(cookie, dist, next, mask, corner, tag, cdist, flags, planeto, planefrom) DRCCookie *cookie, *next; int dist, cdist; TileTypeBitMask *mask, *corner; - char *why; + int tag; int flags, planeto, planefrom; { (cookie)->drcc_dist = dist; (cookie)->drcc_next = next; (cookie)->drcc_mask = *mask; (cookie)->drcc_corner = *corner; - (cookie)->drcc_why = why; + (cookie)->drcc_tag = tag; (cookie)->drcc_cdist = cdist; (cookie)->drcc_flags = flags; (cookie)->drcc_edgeplane = planefrom; @@ -900,7 +938,7 @@ drcAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefro DRCCookie *cookie, *next; int dist, cdist; TileTypeBitMask *mask, *corner; - char *why; + int why; int flags, planeto, planefrom; { /* Diagnostic */ @@ -1088,7 +1126,7 @@ drcExtend(argc, argv) char *layers1 = argv[1]; char *layers2 = argv[2]; int distance = atoi(argv[3]); - char *why; + int why; TileTypeBitMask set1, setC; DRCCookie *dp, *dpnew, *dptrig; TileType i, j; @@ -1100,10 +1138,10 @@ drcExtend(argc, argv) if (!strncmp(argv[4], "exact_", 6)) { exact = TRUE; - why = drcWhyDup(argv[5]); + why = drcWhyCreate(argv[5]); } else - why = drcWhyDup(argv[4]); + why = drcWhyCreate(argv[4]); ptest = DBTechNoisyNameMask(layers1, &set1); pMask1 = CoincidentPlanes(&set1, ptest); @@ -1257,7 +1295,7 @@ drcWidth(argc, argv) { char *layers = argv[1]; int distance = atoi(argv[2]); - char *why = drcWhyDup(argv[3]); + int why = drcWhyCreate(argv[3]); TileTypeBitMask set, setC; PlaneMask pmask, pset, ptest; DRCCookie *dp, *dpnew; @@ -1342,7 +1380,7 @@ drcArea(argc, argv) char *layers = argv[1]; int distance = atoi(argv[2]); int horizon = atoi(argv[3]); - char *why = drcWhyDup(argv[4]); + int why = drcWhyCreate(argv[4]); TileTypeBitMask set, setC; DRCCookie *dp, *dpnew; TileType i, j; @@ -1442,7 +1480,7 @@ drcMaxwidth(argc, argv) char *layers = argv[1]; int distance = atoi(argv[2]); char *bends = argv[3]; - char *why; + int why; TileTypeBitMask set, setC; DRCCookie *dp, *dpnew; TileType i, j; @@ -1469,7 +1507,7 @@ drcMaxwidth(argc, argv) bend = 0; else bend = DRC_BENDS; - why = drcWhyDup(argv[3]); + why = drcWhyCreate(argv[3]); } else { @@ -1480,7 +1518,7 @@ drcMaxwidth(argc, argv) TechError("unknown bend option %s\n",bends); return (0); } - why = drcWhyDup(argv[4]); + why = drcWhyCreate(argv[4]); } for (i = 0; i < DBNumTypes; i++) @@ -1531,7 +1569,7 @@ drcAngles(argc, argv) { char *layers = argv[1]; int angles = atoi(argv[2]); - char *why = drcWhyDup(argv[3]); + int why = drcWhyCreate(argv[3]); TileTypeBitMask set; DRCCookie *dp, *dpnew; int plane; @@ -1599,7 +1637,7 @@ drcSpacing3(argc, argv) char *layers3 = argv[5]; int distance = atoi(argv[3]); char *adjacency = argv[4]; - char *why = drcWhyDup(argv[6]); + int why = drcWhyCreate(argv[6]); TileTypeBitMask set1, set2, set3; int plane; DRCCookie *dp, *dpnew; @@ -2151,7 +2189,7 @@ drcSpacing(argc, argv) { char *layers1 = argv[1], *layers2; char *adjacency; - char *why; + int why; TileTypeBitMask set1, set2, tmp1, tmp2; PlaneMask pmask1, pmask2, pmaskA, pmaskB, ptest; int wwidth, distance, plane, plane2, runlength; @@ -2172,7 +2210,7 @@ drcSpacing(argc, argv) layers2 = argv[4]; distance = atoi(argv[5]); adjacency = argv[6]; - why = drcWhyDup(argv[7]); + why = drcWhyCreate(argv[7]); } else { @@ -2180,7 +2218,7 @@ drcSpacing(argc, argv) distance = atoi(argv[4]); runlength = distance; adjacency = argv[5]; - why = drcWhyDup(argv[6]); + why = drcWhyCreate(argv[6]); } /* TxPrintf("Info: DRCtech: widespacing rule for %s width %d:" " spacing must be %d\n", layers1, wwidth, distance); */ @@ -2191,7 +2229,7 @@ drcSpacing(argc, argv) distance = atoi(argv[3]); adjacency = argv[4]; wwidth = distance; - why = drcWhyDup(argv[5]); + why = drcWhyCreate(argv[5]); runlength = distance; if (argc >= 7) { @@ -2325,7 +2363,7 @@ drcEdge(argc, argv) int distance = atoi(argv[3]); char *okTypes = argv[4], *cornerTypes = argv[5]; int cdist = atoi(argv[6]); - char *why = drcWhyDup(argv[7]); + int why = drcWhyCreate(argv[7]); bool fourway = (strcmp(argv[0], "edge4way") == 0); TileTypeBitMask set1, set2, setC, setM; DRCCookie *dp, *dpnew; @@ -2491,7 +2529,7 @@ drcOverhang(argc, argv) { char *layers2 = argv[1], *layers1 = argv[2]; int distance = atoi(argv[3]); - char *why = drcWhyDup(argv[4]); + int why = drcWhyCreate(argv[4]); TileTypeBitMask set1, set2, setM, setC, setN, set2inv; DRCCookie *dp, *dpnew, *dptrig; int plane, plane2; @@ -2627,7 +2665,7 @@ drcRectOnly(argc, argv) char *argv[]; { char *layers = argv[1]; - char *why = drcWhyDup(argv[2]); + int why = drcWhyCreate(argv[2]); TileTypeBitMask set1, set2, setC; PlaneMask pmask, pset, ptest; DRCCookie *dp, *dpnew; @@ -2727,7 +2765,7 @@ drcSurround(argc, argv) char *layers1 = argv[1], *layers2 = argv[2]; int distance = atoi(argv[3]); char *presence = argv[4]; - char *why = drcWhyDup(argv[5]); + int why = drcWhyCreate(argv[5]); TileTypeBitMask set1, set2, setM, invM, setR; DRCCookie *dp, *dpnew, *dptrig; int plane1, plane2; @@ -3100,7 +3138,7 @@ drcRectangle(argc, argv) char *argv[]; { char *layers = argv[1]; - char *why = drcWhyDup(argv[4]); + int why = drcWhyCreate(argv[4]); TileTypeBitMask types, nottypes; int maxwidth; static char *drcRectOpt[4] = {"any", "even", "odd", 0}; @@ -3466,6 +3504,9 @@ drcTechFinalStyle(style) DRCCookie **dpp, **dp2back; TileType i, j; + /* Done with DRCErrorTable */ + HashKill(&DRCErrorTable); + /* If the scale factor is not 1, then divide all distances by */ /* the scale factor, take the ceiling, and save the (negative) */ /* remainder. */ @@ -3587,7 +3628,6 @@ drcTechFinalStyle(style) } else { - /* Don't free the shared drcc_why string here! */ freeMagic((char *)dptest); drcRulesOptimized++; } @@ -3682,7 +3722,8 @@ drcTechFinalStyle(style) /* TxPrintf("For edge %s-%s, \"%s\" covers \"%s\"\n", DBTypeShortName(i), DBTypeShortName(j), - next->drcc_why, dp->drcc_why); + DRCCurStyle->DRCWhyList[next->drcc_tag], + DRCCurStyle->DRCWhyList[dp->drcc_tag]); */ dp2back = &(style->DRCRulesTbl[i][j]); while (*dp2back != dp) @@ -3704,7 +3745,6 @@ drcTechFinalStyle(style) else *dp2back = dp->drcc_next; - /* Don't free the shared drcc_why string here! */ freeMagic((char *) dp); drcRulesOptimized += 1; } diff --git a/drc/drc.h b/drc/drc.h index 6f3e98c6..69f6ff35 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -39,10 +39,15 @@ typedef struct drccookie int drcc_edgeplane; /* Plane of edge */ int drcc_plane; /* Index of plane on which to check * legal types. */ - char *drcc_why; /* Explanation of error found */ + int drcc_tag; /* Tag to explanation of error found */ struct drccookie *drcc_next; } DRCCookie; +/* These DRC tags in DRCcookie are predefined. */ +#define DRC_ARRAY_OVERLAP_TAG 1 +#define DRC_OVERLAP_TAG 2 +#define DRC_SUBCELL_OVERLAP_TAG 3 + /* *This is size "int" because it holds an area for DRC_AREA rules, */ /* and therefore may have twice the bit length of a normal rule distance. */ @@ -142,22 +147,6 @@ typedef struct drckeep char *ds_name; } DRCKeep; -/* - * DRC "why" strings are potentially referred to hundreds of times by - * DRC cookies in the rule table. Rather than creating hundreds of - * copies of each string, we create just one copy and let all the cookies - * point to that one copy. - * - * Since we can't free these shared "why" strings when we delete a cookie, - * we keep a list of these strings and free them all when convenient. - */ - -typedef struct drcwhylist -{ - char * dwl_string; - struct drcwhylist * dwl_next; -} drcWhyList; - /* * Structure defining a DRC style */ @@ -173,7 +162,8 @@ typedef struct drcstyle int DRCTechHalo; /* largest action distance of design rules */ int DRCStepSize; /* chunk size for decomposing large areas */ char DRCFlags; /* Option flags */ - drcWhyList *DRCWhyList; + char **DRCWhyList; /* Indexed list of "why" text strings */ + int DRCWhySize; /* Length of DRCWhyList */ PaintResultType DRCPaintTable[NP][NT][NT]; } DRCStyle; @@ -229,6 +219,7 @@ extern DRCKeep *DRCStyleList; /* List of available DRC styles */ extern DRCStyle *DRCCurStyle; /* Current DRC style in effect */ extern CellDef *DRCdef; /* Current cell being checked for DRC */ extern CellUse *DRCuse, *DRCDummyUse; +extern HashTable DRCErrorTable; /* DRC errors, hashed by name */ /* * Internal procedures @@ -241,6 +232,7 @@ extern int drcExactOverlapTile(); extern void drcInitRulesTbl(); extern void drcAssign(); extern void drcCifAssign(); +extern int drcWhyCreate(); /* * Exported procedures