diff --git a/VERSION b/VERSION index d671d5db..1825b228 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.571 +8.3.572 diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 9d05d554..18a5492d 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -28,6 +28,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi #include "utils/magic.h" #include "utils/geometry.h" +#include "utils/signals.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" @@ -1478,19 +1479,28 @@ cifBloatAllFunc( if (op->co_distance > 0) { + Rect cifarea; + + cifarea.r_xbot = area.r_xbot; + cifarea.r_ybot = area.r_ybot; + cifarea.r_xtop = area.r_xtop; + cifarea.r_ytop = area.r_ytop; + /* Note: This is non-optimal, as it causes all tiles * in the "bloat" group to be re-processed for each * tile processed in the search group. However, it * is difficult to find an optimal method. */ STACKPUSH(t, ResetStack); - GeoClip(&area, &clipArea); - if (GEO_RECTNULL(&area)) + GeoClip(&cifarea, &clipArea); + if (GEO_RECTNULL(&cifarea)) continue; } - /* Diagonal: If expanding across the edge of a diagonal, */ - /* then just fill the whole tile. */ + /* Diagonal: If expanding across the edge of a diagonal, then */ + /* just fill the whole tile. Note that diagonal tiles are not */ + /* clipped; the clipping only determines if the tile is */ + /* outside the clip area. */ if (IsSplit(t)) { @@ -1505,8 +1515,11 @@ cifBloatAllFunc( CIFPaintTable, (PaintUndoInfo *) NULL); } else + { + GeoClip(&area, &clipArea); DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area, CIFPaintTable, (PaintUndoInfo *) NULL); + } /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) @@ -1547,6 +1560,7 @@ cifBloatAllFunc( TiSetClient(t, CIF_UNPROCESSED); } + if (SigInterruptPending) return 1; return 0; /* Keep the search alive. . . */ } @@ -4695,12 +4709,13 @@ cifBridgeLimFunc2( void cifInteractingRegions( CIFOp *op, + const Rect *area, /* Area of interest to check */ CellDef *cellDef, Plane *temps[], /* Planes to use for temporaries. */ Plane *plane) { Tile *tile = NULL, *t, *tp; - Rect area; + Rect rect; int i; TileType type; bool interacts; @@ -4709,7 +4724,7 @@ cifInteractingRegions( if (RegStack == (Stack *)NULL) RegStack = StackNew(64); - while (DBSrPaintArea((Tile *)tile, plane, &TiPlaneRect, &CIFSolidBits, + while (DBSrPaintArea((Tile *)tile, plane, area, &CIFSolidBits, cifSquaresInitFunc, (ClientData)NULL) != 0) { /* Now, search for (nontrivially) connected tiles in all */ @@ -4729,7 +4744,10 @@ cifInteractingRegions( TiSetClientINT(t, CIF_PROCESSED); /* Get tile area for interaction search */ - TiToRect(t, &area); + TiToRect(t, &rect); + + /* Ignore tiles outside of the search area */ + if (!GEO_SURROUND(area, &rect)) continue; /* "interacting" includes touching as well as overlapping, so expand * search by one unit in every direction and then check overlap. @@ -4738,10 +4756,10 @@ cifInteractingRegions( */ if ((pointertype)op->co_client & CIFOP_INT_TOUCHING) { - area.r_xbot -= 1; - area.r_xtop += 1; - area.r_ybot -= 1; - area.r_ytop += 1; + rect.r_xbot -= 1; + rect.r_xtop += 1; + rect.r_ybot -= 1; + rect.r_ytop += 1; } /* Check if this tile interacts with the rule's types, or skip */ @@ -4749,7 +4767,7 @@ cifInteractingRegions( if (!interacts) { - if (cifSrTiles2(op, &area, cellDef, temps, cifInteractFunc, (ClientData)NULL)) + if (cifSrTiles2(op, &rect, cellDef, temps, cifInteractFunc, (ClientData)NULL)) interacts = TRUE; } @@ -4802,8 +4820,8 @@ cifInteractingRegions( if (interacts) { - TiToRect(t, &area); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *)NULL); + TiToRect(t, &rect); + DBPaintPlane(cifPlane, &rect, CIFPaintTable, (PaintUndoInfo *)NULL); } /* Top */ @@ -4838,6 +4856,9 @@ cifInteractingRegions( STACKPUSH(tp, RegStack); } } + + /* Allow interrupts here */ + if (SigInterruptPending) break; } } @@ -5313,7 +5334,7 @@ CIFGenLayer( DBClearPaintPlane(nextPlane); cifPlane = nextPlane; - cifInteractingRegions(op, cellDef, temps, curPlane); + cifInteractingRegions(op, area, cellDef, temps, curPlane); temp = curPlane; curPlane = nextPlane; nextPlane = temp; diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 2641ca64..c07e48ff 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -234,7 +234,7 @@ cifParseLayers( */ { TileTypeBitMask curCifMask, curPaintMask; - char curLayer[40], *p, *cp; + char curLayer[512], *p, *cp; TileType paintType; int i; bool allResidues; @@ -246,6 +246,10 @@ cifParseLayers( { p = curLayer; + if (*string == '(') + while ((*string != ')') && (*string != 0)) + *p++ = *string++; + if (*string == '*') { allResidues = TRUE; @@ -263,7 +267,22 @@ cifParseLayers( if (paintMask != NULL) { - paintType = DBTechNameTypes(curLayer, &curPaintMask); + if (*curLayer == '(') + { + TileType t; + + /* Layer groups with parentheses can only be paint types, + * and will be parsed accordingly. Residues will be + * handled within the group. Set paintType to -3, which + * is flagged and handled below. + */ + DBTechNoisyNameMask(curLayer, &curPaintMask); + paintType = -3; + allResidues = FALSE; + } + else + paintType = DBTechNameTypes(curLayer, &curPaintMask); + if (paintType >= 0) goto okpaint; } else paintType = -2; @@ -299,7 +318,7 @@ okpaint: TechError("Ambiguous layer (type) \"%s\".\n", curLayer); continue; } - if (paintType >= 0) + if ((paintType >= 0) || (paintType == -3)) { if (paintType == TT_SPACE && spaceOK ==0) TechError("\"Space\" layer not permitted in CIF rules.\n"); diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index b51367c6..07100431 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "utils/magic.h" #include "textio/textio.h" +#include "utils/signals.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" @@ -134,7 +135,7 @@ drcFindOtherCells(use, area) * different for "drc why" commands than for "drc check". * * Returns: - * 0 to keep the search going. + * 0 to keep the search going. In case of an interrupt, return 1. * * ---------------------------------------------------------------------------- */ @@ -156,6 +157,9 @@ drcSubCopyErrors(tile, cxp) arg->dCD_clientData); (*(arg->dCD_errors))++; + /* Allow a break here */ + if (SigInterruptPending) return 1; + return 0; }