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/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 2b365224..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 @@ -748,9 +743,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 +757,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 +797,11 @@ DRCCount(use, area) } } HashKill(&dupTable); + + /* Restore the CDAVAILABLE flag */ + if (recurse == FALSE) + use->cu_def->cd_flags |= CDAVAILABLE; + return dcl; } @@ -833,6 +841,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/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 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);