diff --git a/.gitconfig b/.gitconfig deleted file mode 100644 index d4f587dd..00000000 --- a/.gitconfig +++ /dev/null @@ -1,5 +0,0 @@ -[filter "header"] - smudge = ./.git-expand-header %f - clean = sed -e's/\\$Header:[^$]*\\$/\\$Header\\$/g' -[diff "gds"] - textconv = hexdump -v -C diff --git a/.gitignore b/.gitignore index fb7af471..18ea638f 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,13 @@ scmos/scmos-sub.tech scmos/scmos-tm.tech scmos/scmos.tech scmos/scmosWR.tech +scmos/nmos.tech tcltk/magic.sh tcltk/magic.tcl tcltk/magicdnull tcltk/magicexec tcltk/ext2spice.sh tcltk/ext2sim.sh +magic/tclmagic.dylib +tcltk/magicdnull.dSYM/ +tcltk/magicexec.dSYM/ diff --git a/VERSION b/VERSION index 0eea60da..b89ac070 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.82 +8.3.124 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index f7a80472..b3568a49 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -290,6 +290,8 @@ calmaParseStructure(filename) off_t filepos; bool was_called; bool was_initialized; + bool predefined; + bool do_flatten; CellDef *def; /* Make sure this is a structure; if not, let the caller know we're done */ @@ -299,6 +301,7 @@ calmaParseStructure(filename) /* Read the structure name */ was_initialized = FALSE; + predefined = FALSE; if (!calmaSkipExact(CALMA_BGNSTR)) goto syntaxerror; if (!calmaReadStringRecord(CALMA_STRNAME, &strname)) goto syntaxerror; TxPrintf("Reading \"%s\".\n", strname); @@ -345,16 +348,18 @@ calmaParseStructure(filename) freeMagic(newname); } } - cifReadCellDef = calmaFindCell(strname, &was_called); + cifReadCellDef = calmaFindCell(strname, &was_called, &predefined); + if (predefined == TRUE) + { + calmaNextCell(); + return TRUE; + } DBCellClearDef(cifReadCellDef); DBCellSetAvail(cifReadCellDef); HashSetValue(he, cifReadCellDef); cifCurReadPlanes = cifSubcellPlanes; cifReadCellDef->cd_flags &= ~CDDEREFERENCE; - /* Done with strname */ - if (strname != NULL) freeMagic(strname); - /* For read-only cells, set flag in def */ if (CalmaReadOnly) cifReadCellDef->cd_flags |= CDVENDORGDS; @@ -403,7 +408,36 @@ calmaParseStructure(filename) /* cifReadCellDef->cd_flags |= CDNOEDIT; */ } - /* Make sure it ends with an ENDSTR record */ + /* Check if the cell name matches the pattern list of cells to flatten */ + + do_flatten = FALSE; + if ((CalmaFlattenUsesByName != NULL) && (!was_called)) + { + int i = 0; + char *pattern; + + while (TRUE) + { + pattern = CalmaFlattenUsesByName[i]; + if (pattern == NULL) break; + i++; + + /* Check pattern against strname */ + if (Match(pattern, strname)) + { + do_flatten = TRUE; + break; + } + } + } + if (CalmaFlattenUses && (!was_called) && (npaths < CalmaFlattenLimit) + && (nsrefs == 0)) + do_flatten = TRUE; + + /* Done with strname */ + if (strname != NULL) freeMagic(strname); + + /* Make sure the structure ends with an ENDSTR record */ if (!calmaSkipExact(CALMA_ENDSTR)) goto syntaxerror; /* @@ -411,13 +445,13 @@ calmaParseStructure(filename) * cell by painting when instanced. But---if this cell was * instanced before it was defined, then it can't be flattened. */ - if (CalmaFlattenUses && (!was_called) && (npaths < CalmaFlattenLimit) - && (nsrefs == 0)) + + if (do_flatten) { /* If CDFLATGDS is already set, may need to remove */ /* existing planes and free memory. */ - if ((cifReadCellDef->cd_client != (ClientData)CLIENTDEFAULT) && + if ((cifReadCellDef->cd_client != (ClientData)0) && (cifReadCellDef->cd_flags & CDFLATGDS)) { Plane **cifplanes = (Plane **)cifReadCellDef->cd_client; @@ -432,7 +466,7 @@ calmaParseStructure(filename) } } freeMagic((char *)cifReadCellDef->cd_client); - cifReadCellDef->cd_client = (ClientData)CLIENTDEFAULT; + cifReadCellDef->cd_client = (ClientData)0; } TxPrintf("Saving contents of cell %s\n", cifReadCellDef->cd_name); @@ -610,7 +644,7 @@ calmaElementSref(filename) */ def = calmaLookCell(sname); - if (!def && (CalmaPostOrder || CalmaFlattenUses)) + if (!def && (CalmaPostOrder || CalmaFlattenUses || (CalmaFlattenUsesByName != NULL))) { /* Force the GDS parser to read the cell definition in * post-order. If cellname "sname" is not defined before @@ -659,14 +693,14 @@ calmaElementSref(filename) scalen = 1; scaled = cifCurReadStyle->crs_multiplier / crsMultiplier; } - CIFScalePlanes(scalen, scaled, cifCurReadPlanes); + CIFScalePlanes(scaled, scalen, cifCurReadPlanes); } } else { TxPrintf("Cell definition %s does not exist!\n", sname); fseek(calmaInputFile, originalFilePos, SEEK_SET); - def = calmaFindCell(sname, NULL); + def = calmaFindCell(sname, NULL, NULL); /* Cell flags set to "dereferenced" in case there is no */ /* definition in the GDS file. If there is a definition */ /* made after the instance, then the flag will be cleared. */ @@ -674,7 +708,7 @@ calmaElementSref(filename) } } - if (!def) def = calmaFindCell(sname, NULL); + if (!def) def = calmaFindCell(sname, NULL, NULL); if (DBIsAncestor(def, cifReadCellDef)) { @@ -917,8 +951,7 @@ calmaElementSref(filename) for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { - if ((def->cd_client != (ClientData)CLIENTDEFAULT) && - (gdsplanes[pNum] != NULL)) + if ((def->cd_client != (ClientData)0) && (gdsplanes[pNum] != NULL)) { gdsCopyRec.plane = cifCurReadPlanes[pNum]; if (isArray) @@ -1032,13 +1065,16 @@ gdsCopyPaintFunc(tile, gdsCopyRec) */ CellDef * -calmaFindCell(name, was_called) +calmaFindCell(name, was_called, predefined) char *name; /* Name of desired cell */ bool *was_called; /* If this cell is in the hash table, then it * was instanced before it was defined. We * need to know this so as to avoid flattening * the cell if requested. */ + bool *predefined; /* If this cell was in memory before the GDS + * file was read, then this flag gets set. + */ { HashEntry *h; @@ -1060,6 +1096,16 @@ calmaFindCell(name, was_called) */ DBReComputeBbox(def); } + else + { + TxPrintf("Warning: cell %s already existed before reading GDS!\n", + name); + if (CalmaNoDuplicates) + { + if (predefined) *predefined = TRUE; + TxPrintf("Using pre-existing cell definition\n"); + } + } HashSetValue(h, def); if (was_called) *was_called = FALSE; } diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index a3f64969..4158f4f8 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -98,8 +98,8 @@ calmaInputRescale(n, d) { /* Scale the GDS planes in this cell's cd_client record */ Plane **gdsplanes = (Plane **)def->cd_client; - /* Should not happen, but punt if client record is not set */ - if (def->cd_client != (ClientData)CLIENTDEFAULT) + /* Should not happen, but punt if client record is not set; */ + if (def->cd_client != (ClientData)0) CIFScalePlanes(n, d, gdsplanes); } } diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index a145078b..152d9976 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -63,6 +63,11 @@ bool CalmaFlattenUses = FALSE; /* If TRUE, small cells in the input * performance when handling contacts * saved as subcell arrays. */ +char **CalmaFlattenUsesByName = NULL; /* NULL-terminated list of strings + * to do glob-style pattern matching + * to determine what cells to flatten + * by cellname. + */ bool CalmaReadOnly = FALSE; /* Set files to read-only and * retain file position information * so cells can be written verbatim. @@ -77,7 +82,13 @@ bool CalmaPostOrder = FALSE; /* If TRUE, forces the GDS parser to * flatten cells that are contact cuts. * Added by Nishit 8/16/2004 */ +bool CalmaNoDuplicates = FALSE; /* If TRUE, then if a cell exists in + * memory with the same name as a cell + * in the GDS file, then the cell in + * the GDS file is skipped. + */ extern void calmaUnexpected(); +extern int calmaWriteInitFunc(); bool calmaParseUnits(); @@ -172,6 +183,12 @@ CalmaReadFile(file, filename) CalmaPolygonCount = 0; CalmaPathCount = 0; + /* Reset cd_client pointers (using init function from CalmaWrite.c) */ + /* This is in case a cell already in memory is being referenced; */ + /* it is probably better to avoid those kinds of naming collisions */ + /* though. . . */ + (void) DBCellSrDefs(0, calmaWriteInitFunc, (ClientData) NULL); + HashInit(&calmaDefInitHash, 32, 0); calmaLApresent = FALSE; calmaInputFile = file; @@ -368,7 +385,7 @@ CalmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { fprintf(calmaErrorFile, "Error while reading cell \"%s\" ", cifReadCellDef->cd_name); - fprintf(calmaErrorFile, "(byte position %"DLONG_PREFIX"ld): ", + fprintf(calmaErrorFile, "(byte position %"DLONG_PREFIX"d): ", (dlong)filepos); fprintf(calmaErrorFile, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 41732d23..ff4b83e9 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -53,11 +53,13 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c #include "utils/stack.h" /* Exports */ -bool CalmaDoLibrary = FALSE; /* If TRUE, do not output the top level */ -bool CalmaDoLabels = TRUE; /* If FALSE, don't output labels with GDS-II */ -bool CalmaDoLower = TRUE; /* If TRUE, allow lowercase labels. */ -bool CalmaFlattenArrays = FALSE; /* If TRUE, output arrays as individual uses */ -bool CalmaAddendum = FALSE; /* If TRUE, do not output readonly cell defs */ +bool CalmaDoLibrary = FALSE; /* If TRUE, do not output the top level */ +bool CalmaDoLabels = TRUE; /* If FALSE, don't output labels with GDS-II */ +bool CalmaDoLower = TRUE; /* If TRUE, allow lowercase labels. */ +bool CalmaFlattenArrays = FALSE; /* If TRUE, output arrays as individual uses */ +bool CalmaAddendum = FALSE; /* If TRUE, do not output readonly cell defs */ +bool CalmaNoDateStamp = FALSE; /* If TRUE, output zero for creation date stamp */ +bool CalmaAllowUndefined = FALSE; /* If TRUE, allow calls to undefined cells */ /* Experimental stuff---not thoroughly tested (as of Sept. 2007)! */ bool CalmaContactArrays = FALSE; /* If TRUE, output contacts as subcell arrays */ @@ -304,7 +306,12 @@ CalmaWrite(rootDef, f) */ dummy.cu_def = rootDef; - DBCellReadArea(&dummy, &rootDef->cd_bbox); + if (DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined)) + { + TxError("Failure to read entire subtree of the cell.\n"); + return FALSE; + } + DBFixMismatch(); /* @@ -396,7 +403,10 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) /* Output structure begin */ calmaOutRH(28, CALMA_BGNSTR, CALMA_I2, outf); - calmaOutDate(def->cd_timestamp, outf); + if (CalmaNoDateStamp) + calmaOutDate(time((time_t *) 0), outf); + else + calmaOutDate(def->cd_timestamp, outf); calmaOutDate(time((time_t *) 0), outf); /* Find the structure's unique prefix, in case structure calls subcells */ @@ -799,15 +809,19 @@ calmaProcessDef(def, outf, do_library) if (isReadOnly && hasContent && CalmaAddendum) return (0); - /* Give some feedback to the user */ - TxPrintf(" Writing cell %s\n", def->cd_name); - /* * Output the definitions for any of our descendants that have * not already been output. Numbers are assigned to the subcells - * as they are output. + * as they are output. If the cell will get a "full dump" (by + * having GDS_START but no GDS_END), then do not output any subcells, + * as they are expected to be in the referenced GDS file. */ - (void) DBCellEnum(def, calmaProcessUse, (ClientData) outf); + if (!hasContent || hasGDSEnd) + if (DBCellEnum(def, calmaProcessUse, (ClientData) outf) != 0) + return 1; + + /* Give some feedback to the user */ + TxPrintf(" Generating output for cell %s\n", def->cd_name); if (isReadOnly && hasContent) { @@ -826,14 +840,22 @@ calmaProcessDef(def, outf, do_library) /* This is a rare error, but if the subcell is inside */ /* another vendor GDS, it would not normally be output. */ - DBPropGet(def->cd_parents->cu_parent, "GDS_FILE", &isReadOnly); - if (!isReadOnly || isAbstract) - TxError("Calma output error: Can't find GDS file \"%s\" " - "for vendor cell \"%s\". Using magic's " - "internal definition\n", filename, - def->cd_name); + DBPropGet((def->cd_parents->cu_parent == NULL) ? def : + def->cd_parents->cu_parent, "GDS_FILE", &isReadOnly); if (isReadOnly) + { def->cd_flags |= CDVENDORGDS; + return 0; /* Ignore without raising an error */ + } + + TxError("Calma output error: Can't find GDS file \"%s\" " + "for vendor cell \"%s\". It will not be output.\n", + filename, def->cd_name); + + if (CalmaAllowUndefined) + return 0; + else + return 1; } else if (isAbstract || (!hasGDSEnd)) { @@ -867,7 +889,10 @@ calmaProcessDef(def, outf, do_library) /* Output structure header */ calmaOutRH(28, CALMA_BGNSTR, CALMA_I2, outf); - calmaOutDate(def->cd_timestamp, outf); + if (CalmaNoDateStamp) + calmaOutDate(time((time_t *) 0), outf); + else + calmaOutDate(def->cd_timestamp, outf); calmaOutDate(time((time_t *) 0), outf); /* Name structure the same as the magic cellname */ @@ -922,7 +947,7 @@ calmaProcessDef(def, outf, do_library) if (!do_library) calmaOutFunc(def, outf, &TiPlaneRect); - return (0); + return 0; } @@ -964,7 +989,10 @@ calmaOutFunc(def, f, cliprect) /* Output structure begin */ calmaOutRH(28, CALMA_BGNSTR, CALMA_I2, f); - calmaOutDate(def->cd_timestamp, f); + if (CalmaNoDateStamp) + calmaOutDate(time((time_t *) 0), f); + else + calmaOutDate(def->cd_timestamp, f); calmaOutDate(time((time_t *) 0), f); /* Output structure name */ @@ -2693,7 +2721,10 @@ calmaOutHeader(rootDef, f) /* Beginning of library */ calmaOutRH(28, CALMA_BGNLIB, CALMA_I2, f); - calmaOutDate(rootDef->cd_timestamp, f); + if (CalmaNoDateStamp) + calmaOutDate(time((time_t *) 0), f); + else + calmaOutDate(rootDef->cd_timestamp, f); calmaOutDate(time((time_t *) 0), f); /* Library name (name of root cell) */ diff --git a/calma/calma.h b/calma/calma.h index bedc169b..d37d50f3 100644 --- a/calma/calma.h +++ b/calma/calma.h @@ -31,13 +31,17 @@ extern bool CalmaDoLabels; extern bool CalmaDoLibrary; extern bool CalmaDoLower; extern bool CalmaAddendum; +extern bool CalmaNoDuplicates; +extern bool CalmaNoDateStamp; extern bool CalmaMergeTiles; extern bool CalmaFlattenArrays; extern bool CalmaNoDRCCheck; extern bool CalmaFlattenUses; +extern char **CalmaFlattenUsesByName; extern bool CalmaReadOnly; extern bool CalmaContactArrays; extern bool CalmaPostOrder; +extern bool CalmaAllowUndefined; /* Externally-visible procedures: */ extern bool CalmaWrite(); diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 6eda31ee..9136ac45 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -1086,6 +1086,7 @@ cifFoundFunc(tile, BloatStackPtr) typedef struct _bloatStruct { CIFOp *op; CellDef *def; + TileTypeBitMask connect; Plane **temps; } BloatStruct; @@ -1114,7 +1115,7 @@ cifBloatAllFunc(tile, bls) BloatStruct *bls; { Rect area; - TileTypeBitMask connect; + TileTypeBitMask *connect; Tile *t, *tp; TileType type, ttype; BloatData *bloats; @@ -1128,28 +1129,9 @@ cifBloatAllFunc(tile, bls) op = bls->op; def = bls->def; temps = bls->temps; + connect = &bls->connect; bloats = (BloatData *)op->co_client; - /* Create a mask of all connecting types (these must be in a single - * plane), then call a search function to find all connecting material - * of these types (if the bloat types are temp layers, then this mask - * is not used). - */ - - if (bloats->bl_plane < 0) - { - /* bl_plane == -1 indicates bloating into a CIF templayer, and */ - /* so the only connecting type should be CIF_SOLIDTYPE. */ - TTMaskSetType(&connect, CIF_SOLIDTYPE); - } - else - { - TTMaskZero(&connect); - for (i = 0; i < TT_MAXTYPES; i++) - if (bloats->bl_distance[i] != 0) - TTMaskSetType(&connect, i); - } - /* This search function is based on drcCheckArea */ if (BloatStack == (Stack *)NULL) @@ -1181,7 +1163,7 @@ cifBloatAllFunc(tile, bls) { int pNum = DBPlane(type); pmask = (bloats->bl_plane < 0) ? 0 : - CoincidentPlanes(&connect, PlaneNumToMaskBit(pNum)); + CoincidentPlanes(connect, PlaneNumToMaskBit(pNum)); if (pmask == 0) TiToRect(tile, &area); if (bloats->bl_plane < 0) { @@ -1212,7 +1194,7 @@ cifBloatAllFunc(tile, bls) } else DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &area, - &connect, cifFoundFunc, (ClientData)(&BloatStack)); + connect, cifFoundFunc, (ClientData)(&BloatStack)); } else PUSHTILE(t, BloatStack); @@ -1236,22 +1218,22 @@ cifBloatAllFunc(tile, bls) /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) - if (TTMaskHasType(&connect, TiGetBottomType(tp))) + if (TTMaskHasType(connect, TiGetBottomType(tp))) PUSHTILE(tp, BloatStack); /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) - if (TTMaskHasType(&connect, TiGetRightType(tp))) + if (TTMaskHasType(connect, TiGetRightType(tp))) PUSHTILE(tp, BloatStack); /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) - if (TTMaskHasType(&connect, TiGetTopType(tp))) + if (TTMaskHasType(connect, TiGetTopType(tp))) PUSHTILE(tp, BloatStack); /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) - if (TTMaskHasType(&connect, TiGetLeftType(tp))) + if (TTMaskHasType(connect, TiGetLeftType(tp))) PUSHTILE(tp, BloatStack); } @@ -1296,20 +1278,6 @@ cifBloatAllFunc(tile, bls) } } - /* Reset marked tiles */ - - if (bloats->bl_plane < 0) /* Bloat types are CIF types */ - { - temps = bls->temps; - for (ttype = 0; ttype < TT_MAXTYPES; ttype++, temps++) - if (bloats->bl_distance[ttype] > 0) - (void) DBSrPaintArea((Tile *)NULL, *temps, &TiPlaneRect, - &CIFSolidBits, cifProcessResetFunc, (ClientData)NULL); - } - else - DBSrPaintArea((Tile *)NULL, def->cd_planes[bloats->bl_plane], &TiPlaneRect, - &connect, cifProcessResetFunc, (ClientData)NULL); - return 0; /* Keep the search alive. . . */ } @@ -1322,6 +1290,7 @@ typedef struct _bridgeStruct { /* Bridge Check data structure */ typedef struct _bridgeCheckStruct { Tile *tile; /* Tile that triggered search (ignore this tile) */ + Rect *area; /* Area of search */ int direction; /* What outside corner to look for */ Tile *violator; /* Return the violator tile in this space */ TileType checktype; /* Type to check for, either TT_SPACE or CIF_SOLIDTYPE */ @@ -1330,8 +1299,6 @@ typedef struct _bridgeCheckStruct { /* Direction flags */ #define BRIDGE_NW 1 #define BRIDGE_SW 2 -#define BRIDGE_SE 3 -#define BRIDGE_NE 4 /* * ---------------------------------------------------------------------------- @@ -1351,20 +1318,163 @@ GetEuclideanWidthGrid(width) { int weuclid; int delta; + int limit; + + limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander; + limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10; weuclid = (int)(ceil((double)width * 0.70711)); - if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) + if (CIFCurStyle && (limit > 1)) { - delta = weuclid % CIFCurStyle->cs_gridLimit; + delta = weuclid % limit; if (delta > 0) { weuclid -= delta; - weuclid += CIFCurStyle->cs_gridLimit; + weuclid += limit; } } return weuclid; } +/* + * ---------------------------------------------------------------------------- + * + * GetExpandedAreaGrid -- + * + * Given a pointer "area" to a Rect and a minimum layer width "width", + * find the minimum size rectangle that expands "area" in all directions + * equally to ensure that the length of the diagonal of the expanded + * area is greater than or equal to "width". This is used by the + * "bridge" operator to ensure that the bridging rectangle meets the + * minimum layer width requirement. + * + * Results: + * None. + * + * Side effects: + * The Rect structure pointed to by "area" may be altered. + * + * Notes: + * The calculation needed depends on the geometry. If there is a + * horizontal gap between the tiles, then the bridging shape must + * be as tall as the minimum width rule; this is the vertical + * case (horiz = FALSE). If there is a vertical gap between the + * tiles, then the bridging shape must be as wide as the minimum + * width rule; this is the horizontal case (horiz = TRUE). Then + * calculate the length of the bridging shape in the other direction + * needed to ensure that the join of the bridging shape and the + * preexisting shapes is always wide enough to satisfy the width + * rule. Which calculation is needed depends on whether the shapes + * are catecorner (overlap = FALSE) or overlapping in one direction + * (overlap = TRUE). + * + * ---------------------------------------------------------------------------- + */ + +void +GetExpandedAreaGrid(wrule, space, area) + int wrule; + bool space; + Rect *area; +{ + bool horiz; + bool overlap; + Rect r; + + int width, height, dx, dy, a, b, delta, dx2, dy2, limit; + + overlap = FALSE; + if (area->r_xbot > area->r_xtop) + { + overlap = TRUE; + horiz = (space) ? FALSE : TRUE; + } + if (area->r_ybot > area->r_ytop) + { + overlap = TRUE; + horiz = (space) ? TRUE : FALSE; + } + + GeoCanonicalRect(area, &r); + width = r.r_xtop - r.r_xbot; + height = r.r_ytop - r.r_ybot; + + if (overlap == FALSE) + horiz = (width > height); + + if (horiz) + { + a = wrule - width; + dx = (int)ceilf((float)a / 2.0); + if (overlap || space) + b = wrule * wrule - (width + dx) * (width + dx); + else + b = wrule * wrule - dx * dx; + if (space && !overlap) + dy = (int)ceilf(sqrtf((float)b) - height); + else + dy = (int)ceilf(sqrtf((float)b)); + + b = wrule * wrule - width * width; + dy2 = (int)ceilf((sqrtf((float)b) - height) / 2.0); + if (dy2 > dy) dy = dy2; + } + else + { + a = wrule - height; + dy = (int)ceilf((float)a / 2.0); + if (overlap || space) + b = wrule * wrule - (height + dy) * (height + dy); + else + b = wrule * wrule - dy * dy; + if (space && !overlap) + dx = (int)ceilf(sqrtf((float)b) - width); + else + dx = (int)ceilf(sqrtf((float)b)); + + b = wrule * wrule - height * height; + dx2 = (int)ceilf((sqrtf((float)b) - width) / 2.0); + if (dx2 > dx) dx = dx2; + } + + r.r_xbot -= dx; + r.r_xtop += dx; + r.r_ybot -= dy; + r.r_ytop += dy; + + limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander; + limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10; + + if (CIFCurStyle && (limit > 1)) + { + delta = r.r_xbot % limit; + if (delta > 0) + r.r_xbot -= delta; + else if (delta < 0) + r.r_xbot -= limit + delta; + + delta = r.r_xtop % limit; + if (delta > 0) + r.r_xtop += limit - delta; + else if (delta < 0) + r.r_xtop -= delta; + + delta = r.r_ybot % limit; + if (delta > 0) + r.r_ybot -= delta; + else if (delta < 0) + r.r_ybot -= limit + delta; + + delta = r.r_ytop % limit; + if (delta > 0) + r.r_ytop += limit - delta; + else if (delta < 0) + r.r_ytop -= delta; + } + + *area = r; +} + /* * ---------------------------------------------------------------------------- * @@ -1407,14 +1517,13 @@ cifBridgeFunc1(tile, brs) Tile *tp1, *tp2, *tpx; int width = brs->bridge->br_width; int spacing = growDistance; - int weuclid; BridgeCheckStruct brcs; int cifBridgeCheckFunc(); /* Forward reference */ /* If tile is marked, then it has been handled, so ignore it */ if (tile->ti_client != (ClientData)CIF_UNPROCESSED) return 0; - /* Find each tile outside corner (up to four) */ + /* Find each tile outside corner (only two cases need to be checked) */ /* Check for NE outside corner */ tp1 = TR(tile); /* Tile on right side at the top of this tile */ @@ -1430,55 +1539,20 @@ cifBridgeFunc1(tile, brs) /* Find violator tiles */ brcs.tile = tile; + brcs.area = &area; brcs.direction = BRIDGE_SW; brcs.checktype = TT_SPACE; if (DBSrPaintArea((Tile *) NULL, plane, &area, &CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) { tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - area.r_xtop = MAX(RIGHT(tile), LEFT(tpx) + weuclid); - area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + weuclid); + area.r_xbot = RIGHT(tile); + area.r_ybot = TOP(tile); + area.r_xtop = LEFT(tpx); + area.r_ytop = BOTTOM(tpx); - area.r_xbot = MIN(LEFT(tpx), RIGHT(tile) - weuclid); - area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - weuclid); - - /* Trivial implementation: fill box */ - /* (to do: use stairstep to avoid filling unnecessary areas) */ - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - } - - /* Check for SW outside corner */ - tp1 = BL(tile); /* Tile on left side at the bottom of this tile */ - tp2 = LB(tile); /* Tile on bottom side at the left of this tile */ - if ((TiGetRightType(tp1) == TT_SPACE) && - (TiGetTopType(tp2) == TT_SPACE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - spacing; - area.r_xtop = LEFT(tile) + width; - area.r_ybot = BOTTOM(tile) - spacing; - area.r_ytop = BOTTOM(tile) + width; - - /* Find violator tiles */ - brcs.tile = tile; - brcs.direction = BRIDGE_NE; - brcs.checktype = TT_SPACE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) - { - tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - weuclid); - area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - weuclid); - - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + weuclid); - area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + weuclid); + GetExpandedAreaGrid(width, FALSE, &area); /* Trivial implementation: fill box */ /* (to do: use stairstep to avoid filling unnecessary areas) */ @@ -1500,62 +1574,26 @@ cifBridgeFunc1(tile, brs) /* Find violator tiles */ brcs.tile = tile; + brcs.area = &area; brcs.direction = BRIDGE_NW; brcs.checktype = TT_SPACE; if (DBSrPaintArea((Tile *) NULL, plane, &area, &CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) { tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - area.r_xtop = MAX(RIGHT(tile), LEFT(tpx) + weuclid); - area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - weuclid); + area.r_xbot = RIGHT(tile); + area.r_ybot = TOP(tpx); + area.r_xtop = LEFT(tpx); + area.r_ytop = BOTTOM(tile); - area.r_xbot = MIN(LEFT(tpx), RIGHT(tile) - weuclid); - area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + weuclid); + GetExpandedAreaGrid(width, FALSE, &area); /* Trivial implementation: fill box */ /* (to do: use stairstep to avoid filling unnecessary areas) */ DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); } } - - /* Check for NW outside corner */ - for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1)); - for (tp2 = RT(tile); LEFT(tp1) > LEFT(tile); tp2 = BL(tp1)); - if ((TiGetRightType(tp1) == TT_SPACE) && - (TiGetBottomType(tp2) == TT_SPACE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - spacing; - area.r_xtop = LEFT(tile) + width; - area.r_ybot = TOP(tile) - width; - area.r_ytop = TOP(tile) + spacing; - - /* Find violator tiles */ - brcs.tile = tile; - brcs.direction = BRIDGE_SE; - brcs.checktype = TT_SPACE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &CIFSolidBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) - { - tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - weuclid); - area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + weuclid); - - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + weuclid); - area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - weuclid); - - /* Trivial implementation: fill box */ - /* (to do: use stairstep to avoid filling unnecessary areas) */ - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - } - return 0; } @@ -1582,6 +1620,7 @@ SetMinBoxGrid(area, width) int wtest; int wtot; int delta; + int limit; wtest = (area->r_xtop - area->r_xbot); wtot = area->r_xtop + area->r_xbot; @@ -1598,21 +1637,24 @@ SetMinBoxGrid(area, width) area->r_ytop = (wtot + width) / 2; } - if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) + limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander; + limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10; + + if (CIFCurStyle && (limit > 1)) { - delta = abs(area->r_xbot) % CIFCurStyle->cs_gridLimit; + delta = abs(area->r_xbot) % limit; if (delta > 0) { if (area->r_xbot < 0) { area->r_xbot += delta; - area->r_xbot -= CIFCurStyle->cs_gridLimit; + area->r_xbot -= limit; } else area->r_xbot -= delta; } - delta = abs(area->r_xtop) % CIFCurStyle->cs_gridLimit; + delta = abs(area->r_xtop) % limit; if (delta > 0) { if (area->r_xtop < 0) @@ -1620,23 +1662,23 @@ SetMinBoxGrid(area, width) else { area->r_xtop -= delta; - area->r_xtop += CIFCurStyle->cs_gridLimit; + area->r_xtop += limit; } } - delta = abs(area->r_ybot) % CIFCurStyle->cs_gridLimit; + delta = abs(area->r_ybot) % limit; if (delta > 0) { if (area->r_ybot < 0) { area->r_ybot += delta; - area->r_ybot -= CIFCurStyle->cs_gridLimit; + area->r_ybot -= limit; } else area->r_ybot -= delta; } - delta = abs(area->r_ytop) % CIFCurStyle->cs_gridLimit; + delta = abs(area->r_ytop) % limit; if (delta > 0) { if (area->r_ytop < 0) @@ -1644,7 +1686,7 @@ SetMinBoxGrid(area, width) else { area->r_ytop -= delta; - area->r_ytop += CIFCurStyle->cs_gridLimit; + area->r_ytop += limit; } } } @@ -1691,7 +1733,7 @@ cifBridgeFunc2(tile, brs) Rect area; Tile *tp1, *tp2, *tpx; int width = brs->bridge->br_width; - int weuclid, wtest; + int wtest; int spacing = growDistance; BridgeCheckStruct brcs; int cifBridgeCheckFunc(); /* Forward reference */ @@ -1699,7 +1741,7 @@ cifBridgeFunc2(tile, brs) /* If tile is marked, then it has been handled, so ignore it */ if (tile->ti_client != (ClientData)CIF_UNPROCESSED) return 0; - /* Find each tile outside corner (up to four) */ + /* Find each tile outside corner (only two cases need to be checked) */ /* Check for NE outside corner */ tp1 = TR(tile); /* Tile on right side at the top of this tile */ @@ -1715,61 +1757,20 @@ cifBridgeFunc2(tile, brs) /* Find violator tiles */ brcs.tile = tile; + brcs.area = &area; brcs.direction = BRIDGE_SW; - brcs.checktype = TT_SPACE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) - { - tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - - area.r_xbot = LEFT(tpx) - weuclid; - area.r_ytop = TOP(tile) + weuclid; - - area.r_xtop = RIGHT(tile) + weuclid; - area.r_ybot = BOTTOM(tpx) - weuclid; - - /* Box must meet width and height requirements */ - SetMinBoxGrid(&area, width); - - /* Trivial implementation: fill box */ - /* (to do: use stairstep to avoid filling unnecessary areas) */ - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - } - - /* Check for SW outside corner */ - tp1 = BL(tile); /* Tile on left side at the bottom of this tile */ - tp2 = LB(tile); /* Tile on bottom side at the left of this tile */ - if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) && - (TiGetTopType(tp2) == CIF_SOLIDTYPE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - width; - area.r_xtop = LEFT(tile) + spacing; - area.r_ybot = BOTTOM(tile) - width; - area.r_ytop = BOTTOM(tile) + spacing; - - /* Find violator tiles */ - brcs.tile = tile; - brcs.direction = BRIDGE_NE; brcs.checktype = CIF_SOLIDTYPE; if (DBSrPaintArea((Tile *) NULL, plane, &area, &DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) { tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - area.r_xbot = LEFT(tile) - weuclid; - area.r_ytop = TOP(tpx) + weuclid; + area.r_xbot = RIGHT(tile); + area.r_ybot = TOP(tile); + area.r_xtop = LEFT(tpx); + area.r_ytop = BOTTOM(tpx); - area.r_xtop = RIGHT(tpx) + weuclid; - area.r_ybot = BOTTOM(tile) - weuclid; - - /* Box must meet width and height requirements */ - SetMinBoxGrid(&area, width); + GetExpandedAreaGrid(width, TRUE, &area); /* Trivial implementation: fill box */ /* (to do: use stairstep to avoid filling unnecessary areas) */ @@ -1791,68 +1792,26 @@ cifBridgeFunc2(tile, brs) /* Find violator tiles */ brcs.tile = tile; + brcs.area = &area; brcs.direction = BRIDGE_NW; brcs.checktype = CIF_SOLIDTYPE; if (DBSrPaintArea((Tile *) NULL, plane, &area, &DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) { tpx = brcs.violator; - /* Resize box to satisfy width requirement on both ends */ - weuclid = GetEuclideanWidthGrid(width); - area.r_xbot = LEFT(tpx) - weuclid; - area.r_ytop = TOP(tpx) + weuclid; + area.r_xbot = RIGHT(tile); + area.r_ybot = TOP(tpx); + area.r_xtop = LEFT(tpx); + area.r_ytop = BOTTOM(tile); - area.r_xtop = RIGHT(tile) + weuclid; - area.r_ybot = BOTTOM(tile) - weuclid; - - /* Box must meet width and height requirements */ - SetMinBoxGrid(&area, width); + GetExpandedAreaGrid(width, TRUE, &area); /* Trivial implementation: fill box */ /* (to do: use stairstep to avoid filling unnecessary areas) */ DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); } } - - /* Check for NW outside corner */ - for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1)); - for (tp2 = RT(tile); LEFT(tp2) > LEFT(tile); tp2 = BL(tp2)); - if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) && - (TiGetBottomType(tp2) == CIF_SOLIDTYPE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - width; - area.r_xtop = LEFT(tile) + spacing; - area.r_ybot = TOP(tile) - spacing; - area.r_ytop = TOP(tile) + width; - - /* Find violator tiles */ - brcs.tile = tile; - brcs.direction = BRIDGE_SE; - brcs.checktype = CIF_SOLIDTYPE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &DBSpaceBits, cifBridgeCheckFunc, (ClientData)&brcs) == 1) - { - tpx = brcs.violator; - weuclid = GetEuclideanWidthGrid(width); - - /* Resize box to satisfy width requirement on both ends */ - area.r_xbot = LEFT(tile) - weuclid; - area.r_ytop = TOP(tile) + weuclid; - - area.r_xtop = RIGHT(tpx) + weuclid; - area.r_ybot = BOTTOM(tpx) - weuclid; - - /* Box must meet width and height requirements */ - SetMinBoxGrid(&area, width); - - /* Trivial implementation: fill box */ - /* (to do: use stairstep to avoid filling unnecessary areas) */ - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - } - return 0; } @@ -1879,6 +1838,9 @@ cifBridgeCheckFunc(tile, brcs) switch (dir) { case BRIDGE_NW: + /* Ignore tile if NW corner is not in the search area */ + if (LEFT(tile) <= brcs->area->r_xbot || TOP(tile) >= brcs->area->r_ytop) + break; /* Ignore tile if split, and SE corner is clipped */ if (TiGetRightType(tile) == checktype || TiGetBottomType(tile) == checktype) break; @@ -1891,45 +1853,22 @@ cifBridgeCheckFunc(tile, brcs) return 1; /* Violator found */ } break; - case BRIDGE_NE: - /* Ignore tile if split, and SW corner is clipped */ - if (TiGetLeftType(tile) == checktype || TiGetBottomType(tile) == checktype) - break; - tp1 = RT(tile); - tp2 = TR(tile); - if ((TiGetBottomType(tp1) == checktype) && - (TiGetLeftType(tp2) == checktype)) - { - brcs->violator = tile; - return 1; /* Violator found */ - } - break; case BRIDGE_SW: + /* Ignore tile if SW corner is not in the search area */ + if (LEFT(tile) <= brcs->area->r_xbot || BOTTOM(tile) <= brcs->area->r_ybot) + break; /* Ignore tile if split, and NE corner is clipped */ if (TiGetRightType(tile) == checktype || TiGetTopType(tile) == checktype) break; tp1 = LB(tile); tp2 = BL(tile); - if ((TiGetTopType(tp1) == checktype) && + if ((TiGetTopType(tp1) == checktype) || (TiGetRightType(tp2) == checktype)) { brcs->violator = tile; return 1; /* Violator found */ } break; - case BRIDGE_SE: - /* Ignore tile if split, and NW corner is clipped */ - if (TiGetLeftType(tile) == checktype || TiGetTopType(tile) == checktype) - break; - for (tp1 = LB(tile); RIGHT(tp1) < RIGHT(tile); tp1 = TR(tp1)); - for (tp2 = TR(tile); BOTTOM(tp2) > BOTTOM(tile); tp2 = LB(tp2)); - if ((TiGetTopType(tp1) == checktype) && - (TiGetLeftType(tp2) == checktype)) - { - brcs->violator = tile; - return 1; /* Violator found */ - } - break; } return 0; /* Nothing found here, so keep going */ } @@ -1979,9 +1918,13 @@ cifCloseFunc(tile, plane) /* tile areas into the destination plane. */ if ((atotal != INFINITY) && (atotal < growDistance)) + { cifGatherFunc(tile, &atotal, CLOSE_FILL); + } else + { cifGatherFunc(tile, &atotal, CLOSE_DONE); + } return 0; } @@ -2004,11 +1947,12 @@ cifGatherFunc(tile, atotal, mode) TiToRect(tile, &area); - /* Boundary tiles indicate an unclosed area, so set the area total to */ - /* INFINITY and don't try to run calculations on it. */ + /* Boundary tiles indicate an unclosed area, so set the area total to */ + /* INFINITY and don't try to run calculations on it. NOTE: TiPlaneRect */ + /* is slightly smaller than the plane boundaries on all sides. */ - if ((area.r_xbot == TiPlaneRect.r_xbot) || (area.r_ybot == TiPlaneRect.r_ybot) || - (area.r_xtop == TiPlaneRect.r_xtop) || (area.r_ytop == TiPlaneRect.r_ytop)) + if ((area.r_xbot <= TiPlaneRect.r_xbot) || (area.r_ybot <= TiPlaneRect.r_ybot) || + (area.r_xtop >= TiPlaneRect.r_xtop) || (area.r_ytop >= TiPlaneRect.r_ytop)) *atotal = INFINITY; /* Stop accumulating if already larger than growDistance to avoid the */ @@ -2016,6 +1960,7 @@ cifGatherFunc(tile, atotal, mode) if (mode == CLOSE_SEARCH) { if ((*atotal != INFINITY) && (*atotal < growDistance)) + { locarea = (dlong)(area.r_xtop - area.r_xbot) * (dlong)(area.r_ytop - area.r_ybot); if (IsSplit(tile)) locarea /= 2; @@ -2023,6 +1968,7 @@ cifGatherFunc(tile, atotal, mode) *atotal = INFINITY; else *atotal += (int)locarea; + } } else if (mode == CLOSE_FILL) { @@ -3426,7 +3372,7 @@ cifSlotFunc(area, op, numY, numX, cut, vertical) Rect *cut; /* initial (lower left) cut area */ bool vertical; /* if TRUE, slot is aligned vertically */ { - int i, j, xpitch, ypitch, delta; + int i, j, xpitch, ypitch, delta, limit; int *axtop, *axbot, *aytop, *aybot; int *sxtop, *sxbot, *sytop, *sybot; int *rows, *columns; @@ -3479,9 +3425,12 @@ calcX: /* Check that we are not violating any gridlimit */ - if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) + limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander; + limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10; + + if (CIFCurStyle && (limit > 1)) { - delta = abs(*sxbot) % CIFCurStyle->cs_gridLimit; + delta = abs(*sxbot) % limit; if (delta > 0) { if (*sxbot >= 0) @@ -3509,9 +3458,9 @@ calcY: /* Check that we are not violating any gridlimit */ - if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) + if (CIFCurStyle && (limit > 1)) { - delta = abs(*sybot) % CIFCurStyle->cs_gridLimit; + delta = abs(*sybot) % limit; if (delta > 0) { if (*sybot >= 0) @@ -3562,11 +3511,14 @@ cifSquareFunc(area, op, rows, columns, cut) int *rows, *columns; /* Return values: # rows and # columns, */ Rect *cut; /* initial (lower left) cut area. */ { - int pitch, delta; + int pitch, delta, limit; bool glimit; SquaresData *squares = (SquaresData *)op->co_client; - glimit = (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) ? TRUE : FALSE; + limit = CIFCurStyle->cs_gridLimit * CIFCurStyle->cs_expander; + limit /= (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10; + + glimit = (CIFCurStyle && (limit > 1)) ? TRUE : FALSE; pitch = squares->sq_size + squares->sq_sep; /* Compute the real border to leave around the sides. If only @@ -3606,7 +3558,7 @@ sqX: if (glimit) { - delta = abs(cut->r_xbot) % CIFCurStyle->cs_gridLimit; + delta = abs(cut->r_xbot) % limit; if (delta > 0) { area->r_xtop -= 2 * delta; @@ -3634,7 +3586,7 @@ sqY: if (glimit) { - delta = abs(cut->r_ybot) % CIFCurStyle->cs_gridLimit; + delta = abs(cut->r_ybot) % limit; if (delta > 0) { area->r_ytop -= 2 * delta; @@ -4017,6 +3969,7 @@ bridgeLimCheckFunc(tile, brlimcs) switch (dir) { case BRIDGE_NW: /* Ignore tile if split, and SE corner is clipped */ + if (IsSplit(tile)) if (TiGetRightType(tile) == checktype || TiGetBottomType(tile) == checktype) break; for (tp1 = RT(tile); LEFT(tp1) > LEFT(tile); tp1 = BL(tp1)); @@ -4036,29 +3989,9 @@ bridgeLimCheckFunc(tile, brlimcs) return 1; /* Violator found */ } break; - case BRIDGE_NE: - /* Ignore tile if split, and SW corner is clipped */ - if (TiGetLeftType(tile) == checktype || TiGetBottomType(tile) == checktype) - break; - tp1 = RT(tile); - tp2 = TR(tile); - if ((TiGetBottomType(tp1) == checktype) && - (TiGetLeftType(tp2) == checktype)) - { - dx = LEFT(self) - RIGHT(tile); - dy = BOTTOM(self) - TOP(tile); - if ((dx > 0) && (dy > 0)) - { - sqcheck = (long)dx*dx + (long)dy*dy; - if (sqcheck >= sqdistance) - return 0; - } - brlimcs->violator = tile; - return 1; /* Violator found */ - } - break; case BRIDGE_SW: /* Ignore tile if split, and NE corner is clipped */ + if (IsSplit(tile)) if (TiGetRightType(tile) == checktype || TiGetTopType(tile) == checktype) break; tp1 = LB(tile); @@ -4078,27 +4011,6 @@ bridgeLimCheckFunc(tile, brlimcs) return 1; /* Violator found */ } break; - case BRIDGE_SE: - /* Ignore tile if split, and NW corner is clipped */ - if (TiGetLeftType(tile) == checktype || TiGetTopType(tile) == checktype) - break; - for (tp1 = LB(tile); RIGHT(tp1) < RIGHT(tile); tp1 = TR(tp1)); - for (tp2 = TR(tile); BOTTOM(tp2) > BOTTOM(tile); tp2 = LB(tp2)); - if ((TiGetTopType(tp1) == checktype) && - (TiGetLeftType(tp2) == checktype)) - { - dx = LEFT(self) - RIGHT(tile); - dy = BOTTOM(tile) - TOP(self); - if ((dx > 0) && (dy > 0)) - { - sqcheck = (long)dx*dx + (long)dy*dy; - if (sqcheck >= sqdistance) - return 0; - } - brlimcs->violator = tile; - return 1; /* Violator found */ - } - break; } return 0; /* Nothing found here, so keep going */ } @@ -4233,68 +4145,6 @@ cifBridgeLimFunc1(tile, brlims) } } - /* Check for SW outside corner */ - tp1 = BL(tile); /* Tile on left side at the bottom of this tile */ - tp2 = LB(tile); /* Tile on bottom side at the left of this tile */ - if ((TiGetRightType(tp1) == TT_SPACE) && - (TiGetTopType(tp2) == TT_SPACE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - spacing; - area.r_xtop = LEFT(tile); - area.r_ybot = BOTTOM(tile) - spacing; - area.r_ytop = BOTTOM(tile); - - /* Find violator tiles */ - brlimcs.tile = tile; - brlimcs.direction = BRIDGE_NE; - brlimcs.checktype = TT_SPACE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &CIFSolidBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1) - { - tpx = brlimcs.violator; - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width); - area.r_ytop = MAX(TOP(tpx), BOTTOM(tile)); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx)); - area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - width); - if (bridgeLimSrTiles(brlims, &area, FALSE)) - { - /* First option of bridge can be implemented (there are not limiting tiles in the area)*/ - area.r_ytop = TOP(tpx); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - area.r_xbot = LEFT(tile); - area.r_ytop = MAX(TOP(tpx), BOTTOM(tile)); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - else - { - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile)); - area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + width); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width); - area.r_ybot = MIN(BOTTOM(tile), TOP(tpx)); - if (bridgeLimSrTiles(brlims, &area, FALSE)) - { - /* Second option of bridge can be implemented (there are not limiting tiles in the area)*/ - area.r_ybot = BOTTOM(tile); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - area.r_xtop = RIGHT(tpx); - area.r_ybot = MIN(BOTTOM(tile), TOP(tpx)); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - else - { - /* Last option (Limiting tiles are present on both sides, those areas must be excluded from the bridge)*/ - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width); - area.r_ytop = MAX(TOP(tpx), BOTTOM(tile) + width); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width); - area.r_ybot = MIN(BOTTOM(tile), TOP(tpx) - width); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - bridgeErase(brlims, &area); - } - } - } - } - /* Check for SE outside corner */ for (tp1 = TR(tile); BOTTOM(tp1) > BOTTOM(tile); tp1 = LB(tp1)); for (tp2 = LB(tile); RIGHT(tp1) < RIGHT(tile); tp2 = TR(tp2)); @@ -4357,68 +4207,6 @@ cifBridgeLimFunc1(tile, brlims) } } - /* Check for NW outside corner */ - for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1)); - for (tp2 = RT(tile); LEFT(tp1) > LEFT(tile); tp2 = BL(tp1)); - if ((TiGetRightType(tp1) == TT_SPACE) && - (TiGetBottomType(tp2) == TT_SPACE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - spacing; - area.r_xtop = LEFT(tile); - area.r_ybot = TOP(tile); - area.r_ytop = TOP(tile) + spacing; - - /* Find violator tiles */ - brlimcs.tile = tile; - brlimcs.direction = BRIDGE_SE; - brlimcs.checktype = TT_SPACE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &CIFSolidBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1) - { - tpx = brlimcs.violator; - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile)); - area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - width); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width); - area.r_ytop = MAX(TOP(tile), BOTTOM(tpx)); - if (bridgeLimSrTiles(brlims, &area, FALSE)) - { - /* First option of bridge can be implemented (there are not limiting tiles in the area)*/ - area.r_xtop = RIGHT(tpx); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile)); - area.r_ytop = TOP(tile); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - else - { - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width); - area.r_ybot = MIN(BOTTOM(tpx), TOP(tile)); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx)); - area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + width); - if (bridgeLimSrTiles(brlims, &area, FALSE)) - { - /* Second option of bridge can be implemented (there are not limiting tiles in the area)*/ - area.r_xbot = LEFT(tile); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx)); - area.r_ybot = BOTTOM(tpx); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - } - else - { - /* Last option (Limiting tiles are present on both sides, those areas must be excluded from the bridge)*/ - area.r_xtop = MAX(RIGHT(tpx), LEFT(tile) + width); - area.r_ybot = MIN(BOTTOM(tpx), TOP(tile) - width); - area.r_xbot = MIN(LEFT(tile), RIGHT(tpx) - width); - area.r_ytop = MAX(TOP(tile), BOTTOM(tpx) + width); - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - bridgeErase(brlims, &area); - } - } - } - } - return 0; } @@ -4502,51 +4290,6 @@ cifBridgeLimFunc2(tile, brlims) } } - /* Check for SW outside corner */ - tp1 = BL(tile); /* Tile on left side at the bottom of this tile */ - tp2 = LB(tile); /* Tile on bottom side at the left of this tile */ - if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) && - (TiGetTopType(tp2) == CIF_SOLIDTYPE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - width; - area.r_xtop = LEFT(tile); - area.r_ybot = BOTTOM(tile) - width; - area.r_ytop = BOTTOM(tile); - - /* Find violator tiles */ - brlimcs.tile = tile; - brlimcs.direction = BRIDGE_NE; - brlimcs.checktype = CIF_SOLIDTYPE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &DBSpaceBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1) - { - tpx = brlimcs.violator; - area.r_xtop = RIGHT(tpx); - area.r_ytop = TOP(tpx); - area.r_xbot = LEFT(tile) - width; - area.r_ybot = BOTTOM(tile) - width; - - thirdOption = 0; - if (!bridgeLimSrTiles(brlims, &area, FALSE)) - { - area.r_xtop = RIGHT(tpx) + width; - area.r_ytop = TOP(tpx) + width; - area.r_xbot = LEFT(tile); - area.r_ybot = BOTTOM(tile); - if (!bridgeLimSrTiles(brlims, &area, FALSE)) - { - area.r_xbot = LEFT(tile) - width; - area.r_ybot = BOTTOM(tile) - width; - thirdOption = 1; - } - } - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - if (thirdOption) - bridgeErase(brlims, &area); - } - } - /* Check for SE outside corner */ for (tp1 = TR(tile); BOTTOM(tp1) > BOTTOM(tile); tp1 = LB(tp1)); for (tp2 = LB(tile); RIGHT(tp2) < RIGHT(tile); tp2 = TR(tp2)); @@ -4592,51 +4335,6 @@ cifBridgeLimFunc2(tile, brlims) } } - /* Check for NW outside corner */ - for (tp1 = BL(tile); TOP(tp1) < TOP(tile); tp1 = RT(tp1)); - for (tp2 = RT(tile); LEFT(tp2) > LEFT(tile); tp2 = BL(tp2)); - if ((TiGetRightType(tp1) == CIF_SOLIDTYPE) && - (TiGetBottomType(tp2) == CIF_SOLIDTYPE)) - { - /* Set search box */ - area.r_xbot = LEFT(tile) - width; - area.r_xtop = LEFT(tile); - area.r_ybot = TOP(tile); - area.r_ytop = TOP(tile) + width; - - /* Find violator tiles */ - brlimcs.tile = tile; - brlimcs.direction = BRIDGE_SE; - brlimcs.checktype = CIF_SOLIDTYPE; - if (DBSrPaintArea((Tile *) NULL, plane, &area, - &DBSpaceBits, bridgeLimCheckFunc, (ClientData)&brlimcs) == 1) - { - tpx = brlimcs.violator; - area.r_xtop = RIGHT(tpx) + width; - area.r_ytop = TOP(tile); - area.r_xbot = LEFT(tile); - area.r_ybot = BOTTOM(tpx) - width; - - thirdOption = 0; - if (!bridgeLimSrTiles(brlims, &area, FALSE)) - { - area.r_xtop = RIGHT(tpx); - area.r_ytop = TOP(tile) + width; - area.r_xbot = LEFT(tile) - width; - area.r_ybot = BOTTOM(tpx); - if (!bridgeLimSrTiles(brlims, &area, FALSE)) - { - area.r_xtop = RIGHT(tpx) + width; - area.r_ybot = BOTTOM(tpx) - width; - thirdOption = 1; - } - } - DBPaintPlane(cifPlane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); - if (thirdOption) - bridgeErase(brlims, &area); - } - } - return 0; } @@ -4696,7 +4394,11 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) BridgeStruct brs; BridgeLimStruct brlims; BridgeData *bridge; + BloatData *bloats; bool hstop = FALSE; + char *propvalue; + bool found; + int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ? cifGrowEuclideanFunc : cifGrowFunc; @@ -4968,8 +4670,47 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) bls.op = op; bls.def = cellDef; bls.temps = temps; - cifSrTiles(op, area, cellDef, temps, - cifBloatAllFunc, (ClientData)&bls); + + /* Create a mask of all connecting types (these must be in a single + * plane), then call a search function to find all connecting material + * of these types (if the bloat types are temp layers, then this mask + * is not used). + */ + + bloats = (BloatData *)op->co_client; + if (bloats->bl_plane < 0) + { + /* bl_plane == -1 indicates bloating into a CIF templayer, */ + /* so the only connecting type should be CIF_SOLIDTYPE. */ + TTMaskSetOnlyType(&bls.connect, CIF_SOLIDTYPE); + } + else + { + int i; + TTMaskZero(&bls.connect); + for (i = 0; i < TT_MAXTYPES; i++) + if (bloats->bl_distance[i] != 0) + TTMaskSetType(&bls.connect, i); + } + + cifSrTiles(op, area, cellDef, temps, cifBloatAllFunc, (ClientData)&bls); + + /* Reset marked tiles */ + + if (bloats->bl_plane < 0) /* Bloat types are CIF types */ + { + bls.temps = temps; + for (ttype = 0; ttype < TT_MAXTYPES; ttype++, bls.temps++) + if (bloats->bl_distance[ttype] > 0) + (void) DBSrPaintArea((Tile *)NULL, *bls.temps, &TiPlaneRect, + &CIFSolidBits, cifProcessResetFunc, + (ClientData)NULL); + } + else + DBSrPaintArea((Tile *)NULL, cellDef->cd_planes[bloats->bl_plane], + &TiPlaneRect, &bls.connect, cifProcessResetFunc, + (ClientData)NULL); + break; case CIFOP_SQUARES: @@ -5064,9 +4805,6 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) if (origDef && (origDef->cd_flags & CDFIXEDBBOX)) { - char *propvalue; - bool found; - propvalue = (char *)DBPropGet(origDef, "FIXED_BBOX", &found); if (!found) break; if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, @@ -5123,6 +4861,57 @@ CIFGenLayer(op, area, cellDef, origDef, temps, hier, clientdata) CIFPaintTable, (PaintUndoInfo *)NULL); break; + /* The CIFOP_MASKHINTS operator checks the current cell for */ + /* a property with "MASKHINTS_" followed by the name saved */ + /* in the co_client record. If there is such a property, */ + /* then the property value is parsed for geometry in */ + /* internal units, grouped in sets of four values llx lly */ + /* urx ury. */ + + case CIFOP_MASKHINTS: + { + int j, numfound; + char propname[512]; + char *propptr; + char *layername = (char *)op->co_client; + + sprintf(propname, "MASKHINTS_%s", layername); + + propvalue = (char *)DBPropGet(cellDef, propname, &found); + if (!found) break; /* No mask hints available */ + propptr = propvalue; + while (*propptr) + { + numfound = sscanf(propptr, "%d %d %d %d", + &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop); + + if (numfound != 4) + { + /* To do: Allow keyword "rect", "tri", or "poly" + * at the start of the list and parse accordingly. + * For now, this only flags an error. + */ + TxError("%s: Cannot read rectangle values.\n", propname); + break; + } + cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; + bbox.r_xbot *= cifScale; + bbox.r_xtop *= cifScale; + bbox.r_ybot *= cifScale; + bbox.r_ytop *= cifScale; + cifScale = 1; + DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox, + CIFPaintTable, (PaintUndoInfo *)NULL); + for (j = 0; j < 4; j++) + { + while (*propptr && isspace(*propptr)) propptr++; + while (*propptr && !isspace(*propptr)) propptr++; + } + } + } + break; + default: continue; } diff --git a/cif/CIFhier.c b/cif/CIFhier.c index 4759862c..9d2860e5 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #endif /* not lint */ #include +#include #include "tcltk/tclmagic.h" #include "utils/magic.h" @@ -201,6 +202,193 @@ cifHierCleanup() SigEnableInterrupts(); } +/* + * ---------------------------------------------------------------------------- + * + * cifMaskHints -- + * + * Copy a mask hint into a target cell by adding it to the + * property list of the target cell. If the target cell already + * has the same mask hint key, then the mask hint value is + * appended to the property in the target cell def. + * + * Returns: + * 0 to keep the search going. + * + * Side effects: + * Modifies properties of the target cell def. + * + * ---------------------------------------------------------------------------- + */ + +int +cifMaskHints(name, value, targetDef) + char *name; + char *value; + CellDef *targetDef; +{ + char *propvalue, *newval; + bool propfound; + + if (!strncmp(name, "MASKHINTS_", 10)) + { + /* Check if name exists already in the flattened cell */ + propvalue = (char *)DBPropGet(targetDef, name, &propfound); + if (propfound) + { + /* Append value to the property */ + newval = mallocMagic(strlen(value) + strlen(propvalue) + 2); + sprintf(newval, "%s %s", propvalue, value); + } + else + newval = StrDup((char **)NULL, value); + + DBPropPut(targetDef, name, newval); + } + return 0; +} + +/* + * ---------------------------------------------------------------------------- + * + * CIFCopyMaskHints -- + * + * Callback function to copy mask hints from one cell into another. + * + * Results: + * None. + * + * Side effects: + * May modify properties in the target cell. + * + * ---------------------------------------------------------------------------- + */ + +void +CIFCopyMaskHints(sourceDef, targetDef) + CellDef *sourceDef; + CellDef *targetDef; +{ + DBPropEnum(sourceDef, cifMaskHints, targetDef); +} + +/* Structure used by cifFlatMaskHints, below */ + +typedef struct _maskHintsData +{ + Transform *mh_trans; + CellDef *mh_def; +} MaskHintsData; + +/* + * ---------------------------------------------------------------------------- + * + * cifFlatMaskHints -- + * + * Copy a mask hint into a flattened cell by transforming it into the + * coordinate system of the flattened cell, and adding it to the + * property list of the flattened cell. + * + * Returns: + * 0 to keep the search going. + * + * Side effects: + * Modifies properties of the cell def passed in MaskHintsData. + * + * ---------------------------------------------------------------------------- + */ + +int +cifFlatMaskHints(name, value, mhd) + char *name; + char *value; + MaskHintsData *mhd; +{ + Rect r, newr; + char *vptr, *newval, *lastval, *propvalue; + bool propfound; + int lastlen; + + if (!strncmp(name, "MASKHINTS_", 10)) + { + newval = (char *)NULL; + vptr = value; + while (*vptr != '\0') + { + if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot, + &r.r_xtop, &r.r_ytop) == 4) + { + /* Transform rectangle to top level coordinates */ + GeoTransRect(mhd->mh_trans, &r, &newr); + lastval = newval; + lastlen = (lastval) ? strlen(lastval) : 0; + newval = mallocMagic(40 + lastlen); + if (lastval) + strcpy(newval, lastval); + else + *newval = '\0'; + sprintf(newval + lastlen, "%s%d %d %d %d", (lastval) ? " " : "", + newr.r_xbot, newr.r_ybot, newr.r_xtop, newr.r_ytop); + if (lastval) freeMagic(lastval); + + /* Parse through the four values and check if there's more */ + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + } + } + + /* Check if name exists already in the flattened cell */ + propvalue = (char *)DBPropGet(mhd->mh_def, name, &propfound); + if (propfound) + { + /* Append newval to the property */ + lastval = newval; + newval = mallocMagic(strlen(lastval) + strlen(propvalue) + 2); + sprintf(newval, "%s %s", propvalue, lastval); + freeMagic(lastval); + } + DBPropPut(mhd->mh_def, name, newval); + } + return 0; +} + +/* + * ---------------------------------------------------------------------------- + * + * cifHierCopyMaskHints -- + * + * Callback function to copy mask hints from a subcell into a flattened + * cell, which is passed in the clientData record. + * + * Results: + * Always returns 0 to keep the search alive. + * + * Side effects: + * May modify properties in the flattened cell. + * + * ---------------------------------------------------------------------------- + */ + +int +cifHierCopyMaskHints(scx, clientData) + SearchContext *scx; + ClientData clientData; +{ + MaskHintsData mhd; + + mhd.mh_trans = &scx->scx_trans; + mhd.mh_def = (CellDef *)clientData; + + DBPropEnum(scx->scx_use->cu_def, cifFlatMaskHints, &mhd); + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -245,9 +433,8 @@ cifHierCopyFunc(tile, cxp) if (cxp->tc_scx->scx_use->cu_def->cd_flags & CDVENDORGDS) { if (!CIFCurStyle) - return 0; - else if (!(CIFCurStyle->cs_flags & CWF_SEE_VENDOR)) - return 0; + if (!(CIFCurStyle->cs_flags & CWF_SEE_NO_VENDOR)) + return 0; } /* Ignore space tiles, since they won't do anything anyway. */ @@ -320,6 +507,11 @@ cifHierCellFunc(scx) (void) DBTreeSrTiles(&newscx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + /* Flatten mask hints in the area of interest */ + CIFCopyMaskHints(scx->scx_use->cu_def, CIFComponentDef); + DBTreeSrCells(&newscx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + /* Set CIFErrorDef to NULL to ignore errors here... these will * get reported anyway when the cell is CIF'ed non-hierarchically, * so there's no point in making a second report here. @@ -421,6 +613,44 @@ cifHierCheckFunc(tile, plane) return 0; } +/* + * ---------------------------------------------------------------------------- + * + * cifHierTempCheckFunc -- + * + * This function is like cifHierCheckFunc() (see above), but is used + * for "templayers", where any parent/child disagreement should be + * considered a non-issue as far as output is concerned. Only the + * actual mask layer will report any problems. + * + * Results: + * Always returns 0 to keep the search alive. + * + * Side effects: + * Error messages may be output. + * + * ---------------------------------------------------------------------------- + */ + +int +cifHierTempCheckFunc(tile, plane) + Tile *tile; /* Tile containing CIF. */ + Plane *plane; /* Plane to check against and modify. */ +{ + Rect area; + + TiToRect(tile, &area); + + if (IsSplit(tile)) + DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable, + (PaintUndoInfo *) NULL); + else + DBPaintPlane(plane, &area, CIFEraseTable, (PaintUndoInfo *) NULL); + + CIFTileOps++; + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -490,9 +720,14 @@ cifCheckAndErase(style) { CIFErrorLayer = i; if (CIFComponentPlanes[i] == NULL) continue; - (void) DBSrPaintArea((Tile *) NULL, CIFComponentPlanes[i], - &TiPlaneRect, &CIFSolidBits, cifHierCheckFunc, - (ClientData) CIFTotalPlanes[i]); + if (CIFCurStyle->cs_layers[i]->cl_flags & CIF_TEMP) + (void) DBSrPaintArea((Tile *) NULL, CIFComponentPlanes[i], + &TiPlaneRect, &CIFSolidBits, cifHierTempCheckFunc, + (ClientData) CIFTotalPlanes[i]); + else + (void) DBSrPaintArea((Tile *) NULL, CIFComponentPlanes[i], + &TiPlaneRect, &CIFSolidBits, cifHierCheckFunc, + (ClientData) CIFTotalPlanes[i]); } } @@ -595,6 +830,11 @@ CIFGenSubcells(def, area, output) GEO_EXPAND(&interaction, CIFCurStyle->cs_radius, &scx.scx_area); (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFTotalDef); + /* Flatten mask hints in the area of interest */ + CIFCopyMaskHints(def, CIFTotalDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFTotalDef); + CIFErrorDef = def; CIFGen(CIFTotalDef, def, &interaction, CIFTotalPlanes, &CIFCurStyle->cs_hierLayers, TRUE, TRUE, TRUE, @@ -720,10 +960,16 @@ cifHierElementFunc(use, transform, x, y, checkArea) scx.scx_use = use; (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFTotalDef); + CIFCopyMaskHints(use->cu_def, CIFTotalDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFTotalDef); DBCellClearDef(CIFComponentDef); (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + CIFCopyMaskHints(use->cu_def, CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); CIFErrorDef = (CellDef *) NULL; CIFGen(CIFComponentDef, use->cu_def, checkArea, CIFComponentPlanes, diff --git a/cif/CIFint.h b/cif/CIFint.h index fcde35e3..c7b3d127 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -142,6 +142,7 @@ typedef struct cifop * CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated * CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps * CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers + * CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any. */ #define CIFOP_AND 1 @@ -166,6 +167,7 @@ typedef struct cifop #define CIFOP_CLOSE 20 #define CIFOP_BRIDGE 21 #define CIFOP_BRIDGELIM 22 +#define CIFOP_MASKHINTS 23 /* Added by Tim 10/21/2004 */ @@ -224,12 +226,9 @@ typedef struct * * CIF_TEMP: Means that this is a temporary layer used to build * up CIF information. It isn't output in the CIF file. - * CIF_BBOX_TOP: Indicates that the bounding box rectangle should - * only be generated if the cell is a top-level cell. */ #define CIF_TEMP 1 -#define CIF_BBOX_TOP 2 /* The following data structure describes a complete set of CIF * layers. The number of CIF layers (MAXCIFLAYERS) must not be @@ -307,8 +306,8 @@ typedef struct cifstyle #define CWF_GROW_SLIVERS 0x02 #define CWF_ANGSTROMS 0x04 #define CWF_GROW_EUCLIDEAN 0x08 -#define CWF_SEE_VENDOR 0x10 /* Override vendor GDS flag in cells */ -#define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */ +#define CWF_SEE_NO_VENDOR 0x10 /* Hide magic's GDS from vendor cells */ +#define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */ #define CWF_STRING_LIMIT 0x40 /* Use older Calma format character limit */ /* procedures */ @@ -321,7 +320,9 @@ extern void CIFClearPlanes(); extern Plane *CIFGenLayer(); extern void CIFInitCells(); extern int cifHierCopyFunc(); +extern int cifHierCopyMaskHints(); extern void CIFLoadStyle(); +extern void CIFCopyMaskHints(); /* Shared variables and structures: */ diff --git a/cif/CIFmain.c b/cif/CIFmain.c index fb2ea1af..e12b6110 100644 --- a/cif/CIFmain.c +++ b/cif/CIFmain.c @@ -259,7 +259,8 @@ CIFSetStyle(name) * print out the valid styles. */ { - CIFKeep *style, *match; + CIFKeep *style, *match, *exactmatch; + bool ambiguous = FALSE; int length; if (name == NULL) return; @@ -269,18 +270,25 @@ CIFSetStyle(name) for (style = CIFStyleList; style != NULL; style = style->cs_next) { - if (strncmp(name, style->cs_name, length) == 0) + if (!strcmp(name, style->cs_name)) { + match = style; + ambiguous = FALSE; + break; + } + else if (!strncmp(name, style->cs_name, length)) { - if (match != NULL) - { - TxError("CIF output style \"%s\" is ambiguous.\n", name); - CIFPrintStyle(FALSE, TRUE, TRUE); - return; - } + if (match != NULL) ambiguous = TRUE; match = style; } } + if (ambiguous) + { + TxError("CIF output style \"%s\" is ambiguous.\n", name); + CIFPrintStyle(FALSE, TRUE, TRUE); + return; + } + if (match != NULL) { CIFLoadStyle(match->cs_name); diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 10dd823a..ed2c6d00 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -386,8 +386,10 @@ CIFInputRescale(n, d) } } - CIFScalePlanes(n, d, cifEditCellPlanes); - if (cifEditCellPlanes != cifSubcellPlanes) + CIFScalePlanes(n, d, cifCurReadPlanes); + if (cifCurReadPlanes != cifEditCellPlanes) + CIFScalePlanes(n, d, cifEditCellPlanes); + if (cifEditCellPlanes != cifSubcellPlanes && cifCurReadPlanes != cifSubcellPlanes) CIFScalePlanes(n, d, cifSubcellPlanes); CIFReadWarning("CIF style %s: units rescaled by factor of %d / %d\n", @@ -603,13 +605,13 @@ CIFPaintCurrent(filetype) Plane **parray; extern char *(cifReadLayers[MAXCIFRLAYERS]); - /* NOTE: There should be no need to check for cd_client - * here as cd_client should not be CLIENTDEFAULT if CDFLATGDS - * is set in flags. This condition has occurred, though, and - * needs to be debugged. + /* NOTE: The condition cd_client == 0 when CDFLATGDS + * indicates that the cell was already in memory when the + * GDS was read. This condition should be properly caught + * and handled. */ if ((cifReadCellDef->cd_flags & CDFLATGDS) && - (cifReadCellDef->cd_client != (ClientData)CLIENTDEFAULT)) + (cifReadCellDef->cd_client != (ClientData)0)) parray = (Plane **)cifReadCellDef->cd_client; else { @@ -1499,7 +1501,7 @@ CIFReadCellCleanup(filetype) UndoDisable(); /* cifplanes should be valid, but don't crash magic if not */ - if (cifplanes != (Plane **)CLIENTDEFAULT) + if (cifplanes != (Plane **)0) { for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) @@ -1512,7 +1514,7 @@ CIFReadCellCleanup(filetype) } freeMagic((char *)def->cd_client); } - def->cd_client = (ClientData)CLIENTDEFAULT; + def->cd_client = (ClientData)0; #if 0 /* If the CDFLATTENED flag was not set, then this geometry */ diff --git a/cif/CIFsee.c b/cif/CIFsee.c index e450e003..8eff6a5b 100644 --- a/cif/CIFsee.c +++ b/cif/CIFsee.c @@ -21,6 +21,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #endif /* not lint */ #include +#include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" @@ -162,6 +163,10 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + CIFCopyMaskHints(rootDef, CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + oldCount = DBWFeedbackCount; CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, @@ -278,6 +283,10 @@ CIFSeeLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + CIFCopyMaskHints(rootDef, CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + oldCount = DBWFeedbackCount; CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, (ClientData)NULL); @@ -414,10 +423,11 @@ typedef struct { } coverstats; void -CIFCoverageLayer(rootDef, area, layer) +CIFCoverageLayer(rootDef, area, layer, dolist) CellDef *rootDef; /* Def in which to compute CIF coverage */ Rect *area; /* Area in which to compute coverage */ char *layer; /* CIF layer for coverage computation. */ + bool dolist; /* If TRUE, report only the value, in decimal */ { coverstats cstats; int i, scale; @@ -443,6 +453,10 @@ CIFCoverageLayer(rootDef, area, layer) scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); + CIFCopyMaskHints(rootDef, CIFComponentDef); + DBTreeSrCells(&scx, 0, cifHierCopyMaskHints, + (ClientData)CIFComponentDef); + CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE, (ClientData)NULL); DBCellClearDef(CIFComponentDef); @@ -470,12 +484,26 @@ CIFCoverageLayer(rootDef, area, layer) atotal = (long long)(cstats.bounds.r_xtop - cstats.bounds.r_xbot); atotal *= (long long)(cstats.bounds.r_ytop - cstats.bounds.r_ybot); - TxPrintf("%s Area = %lld CIF units^2\n", doBox ? "Cursor Box" : + if (dolist) + { +#ifdef MAGIC_WRAPPER + Tcl_Obj *pobj; + + pobj = Tcl_NewDoubleObj((double)fcover); + Tcl_SetObjResult(magicinterp, pobj); +#else + TxPrintf("%g\n", fcover); +#endif + } + else + { + TxPrintf("%s Area = %lld CIF units^2\n", doBox ? "Cursor Box" : "Cell", btotal); - TxPrintf("Layer Bounding Area = %lld CIF units^2\n", atotal); - TxPrintf("Layer Total Area = %lld CIF units^2\n", cstats.coverage); - TxPrintf("Coverage in %s = %1.1f%%\n", doBox ? "box" : + TxPrintf("Layer Bounding Area = %lld CIF units^2\n", atotal); + TxPrintf("Layer Total Area = %lld CIF units^2\n", cstats.coverage); + TxPrintf("Coverage in %s = %1.1f%%\n", doBox ? "box" : "cell", 100.0 * fcover); + } } int diff --git a/cif/CIFtech.c b/cif/CIFtech.c index ce939289..fa9c9e29 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -991,8 +991,8 @@ CIFTechLine(sectionName, argc, argv) CIFCurStyle->cs_flags |= CWF_PERMISSIVE_LABELS; else if (strcmp(argv[i], "grow-euclidean") == 0) CIFCurStyle->cs_flags |= CWF_GROW_EUCLIDEAN; - else if (strcmp(argv[i], "see-vendor") == 0) - CIFCurStyle->cs_flags |= CWF_SEE_VENDOR; + else if (strcmp(argv[i], "see-no-vendor") == 0) + CIFCurStyle->cs_flags |= CWF_SEE_NO_VENDOR; else if (strcmp(argv[i], "no-errors") == 0) CIFCurStyle->cs_flags |= CWF_NO_ERRORS; else if (strcmp(argv[i], "string-limit") == 0) @@ -1054,6 +1054,8 @@ CIFTechLine(sectionName, argc, argv) newOp->co_opcode = CIFOP_MAXRECT; else if (strcmp(argv[0], "boundary") == 0) newOp->co_opcode = CIFOP_BOUNDARY; + else if (strcmp(argv[0], "mask-hints") == 0) + newOp->co_opcode = CIFOP_MASKHINTS; else if (strcmp(argv[0], "close") == 0) newOp->co_opcode = CIFOP_CLOSE; else if (strcmp(argv[0], "bridge") == 0) @@ -1247,6 +1249,11 @@ bloatCheck: &newOp->co_cifMask, FALSE); break; + case CIFOP_MASKHINTS: + if (argc != 2) goto wrongNumArgs; + newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]); + break; + case CIFOP_MAXRECT: if (argc == 2) { @@ -1537,10 +1544,12 @@ cifComputeRadii(layer, des) for (op = layer->cl_ops; op != NULL; op = op->co_next) { - /* BBOX and NET operators should never be used hierarchically */ - /* so ignore any grow/shrink operators that come after them. */ + /* BBOX, NET, and MASKHINTS operators should never be used */ + /* hierarchically so ignore any grow/shrink operators that */ + /* come after them. */ - if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET) + if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET || + op->co_opcode == CIFOP_MASKHINTS) break; /* If CIF layers are used, switch to the max of current @@ -1565,11 +1574,11 @@ cifComputeRadii(layer, des) switch (op->co_opcode) { - case CIFOP_AND: break; - - case CIFOP_ANDNOT: break; - - case CIFOP_OR: break; + case CIFOP_AND: + case CIFOP_ANDNOT: + case CIFOP_OR: + case CIFOP_MASKHINTS: + break; case CIFOP_GROW: case CIFOP_GROWMIN: @@ -1850,13 +1859,15 @@ CIFTechFinal() /* Presence of op->co_opcode in CIFOP_OR indicates a copy */ /* of the SquaresData pointer from a following operator */ /* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */ - /* as a flag field, while CIFOP_NET uses it for a string. */ + /* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */ + /* uses it for a string. */ else { switch (op->co_opcode) { case CIFOP_OR: case CIFOP_BBOX: + case CIFOP_MASKHINTS: case CIFOP_BOUNDARY: case CIFOP_MAXRECT: case CIFOP_NET: @@ -2388,6 +2399,7 @@ CIFTechOutputScale(n, d) case CIFOP_OR: case CIFOP_BBOX: case CIFOP_BOUNDARY: + case CIFOP_MASKHINTS: case CIFOP_MAXRECT: case CIFOP_NET: break; @@ -2425,7 +2437,7 @@ CIFTechOutputScale(n, d) /* Reduce the scale and all distances by the greatest common */ /* factor of everything. */ - /* fprintf(stderr, "All CIF units divisible by %d\n", lexpand); */ + /* fprintf(stderr, "All CIF units divisible by %d\n", lexpand); */ /* fflush(stderr); */ lgcf = FindGCF(ostyle->cs_scaleFactor, ostyle->cs_expander); @@ -2502,9 +2514,10 @@ CIFTechOutputScale(n, d) bridge->br_width /= lexpand; break; default: - /* op->co_opcode in CIFOP_OR is a pointer copy */ - /* and in CIFOP_BBOX and CIFOP_MAXRECT is a */ - /* flag, and in CIFOP_NET is a string. */ + /* op->co_opcode in CIFOP_OR is a pointer copy, */ + /* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */ + /* and in CIFOP_NET and CIFOP_MASKHINTS is a */ + /* string. */ break; } } diff --git a/cif/CIFwrite.c b/cif/CIFwrite.c index 8f40c2b2..0dbfcc67 100644 --- a/cif/CIFwrite.c +++ b/cif/CIFwrite.c @@ -132,14 +132,18 @@ CIFWrite(rootDef, f) */ dummy.cu_def = rootDef; - DBCellReadArea(&dummy, &rootDef->cd_bbox); + if (DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE)) + { + TxError("Failure to read in entire subtree of the cell.\n"); + return (FALSE); + } DBFixMismatch(); if (CIFCurStyle->cs_reducer == 0) { TxError("The current CIF output style can only be used for writing\n"); TxError("Calma output. Try picking another output style.\n"); - return (TRUE); + return (FALSE); } /* diff --git a/commands/CmdCD.c b/commands/CmdCD.c index fda146a9..047b9a85 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -94,18 +94,22 @@ bool cmdDumpParseArgs(); #define CALMA_CONTACTS 3 #define CALMA_DRCCHECK 4 #define CALMA_FLATTEN 5 -#define CALMA_ORDERING 6 -#define CALMA_LABELS 7 -#define CALMA_LIBRARY 8 -#define CALMA_LOWER 9 -#define CALMA_MERGE 10 -#define CALMA_READ 11 -#define CALMA_READONLY 12 -#define CALMA_RESCALE 13 -#define CALMA_WARNING 14 -#define CALMA_WRITE 15 -#define CALMA_POLYS 16 -#define CALMA_PATHS 17 +#define CALMA_FLATGLOB 6 +#define CALMA_ORDERING 7 +#define CALMA_LABELS 8 +#define CALMA_LIBRARY 9 +#define CALMA_LOWER 10 +#define CALMA_MERGE 11 +#define CALMA_NO_STAMP 12 +#define CALMA_NO_DUP 13 +#define CALMA_READ 14 +#define CALMA_READONLY 15 +#define CALMA_RESCALE 16 +#define CALMA_WARNING 17 +#define CALMA_WRITE 18 +#define CALMA_POLYS 19 +#define CALMA_PATHS 20 +#define CALMA_UNDEFINED 21 #define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */ @@ -122,7 +126,9 @@ CmdCalma(w, cmd) extern int CalmaFlattenLimit; static char *gdsExts[] = {".gds", ".gds2", ".strm", "", NULL}; - static char *cmdCalmaYesNo[] = { "no", "false", "off", "yes", "true", "on", 0 }; + static char *cmdCalmaYesNo[] = { + "no", "false", "off", "0", "yes", "true", "on", "1", 0 }; + static char *cmdCalmaAllowDisallow[] = {"disallow", "0", "allow", "1", 0}; static char *cmdCalmaWarnOptions[] = { "default", "none", "align", "limit", "redirect", "help", 0 }; static char *cmdCalmaOption[] = @@ -133,11 +139,14 @@ CmdCalma(w, cmd) "contacts [yes|no] optimize output by arraying contacts as subcells", "drccheck [yes|no] mark all cells as needing DRC checking", "flatten [yes|no|limit] flatten simple cells (e.g., contacts) on input", + "flatglob [|none] flatten cells by name with glob patterning", "ordering [on|off] cause cells to be read in post-order", "labels [yes|no] cause labels to be output when writing GDS-II", "library [yes|no] do not output the top level, only subcells", "lower [yes|no] allow both upper and lower case in labels", "merge [yes|no] merge tiles into polygons in the output", + "noduplicates [yes|no] do not read cells that exist before reading GDS", + "nodatestamp [yes|no] write a zero value creation date stamp", "read file read Calma GDS-II format from \"file\"\n" " into edit cell", "readonly [yes|no] set cell as read-only and generate output from GDS file", @@ -149,6 +158,8 @@ CmdCalma(w, cmd) " put non-Manhattan polygons into subcells", "path subcells [yes|no]\n" " put wire paths into individual subcells", + "undefined [allow|disallow]\n" + " [dis]allow writing of GDS with calls to undefined cells", NULL }; @@ -220,15 +231,16 @@ CmdCalma(w, cmd) else if (cmd->tx_argc != 3) { wrongNumArgs: - TxError("Wrong number of arguments in \"gds\" command."); - TxError(" Try \":gds help\" for help.\n"); + TxError("Wrong number of arguments in \"%s\" command.", + cmd->tx_argv[0]); + TxError(" Try \":%s help\" for help.\n", cmd->tx_argv[0]); return; } option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaDoLabels = (option < 3) ? FALSE : TRUE; + CalmaDoLabels = (option < 4) ? FALSE : TRUE; return; case CALMA_LIBRARY: @@ -248,7 +260,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaDoLibrary = (option < 3) ? FALSE : TRUE; + CalmaDoLibrary = (option < 4) ? FALSE : TRUE; return; case CALMA_ADDENDUM: @@ -268,7 +280,27 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaAddendum = (option < 3) ? FALSE : TRUE; + CalmaAddendum = (option < 4) ? FALSE : TRUE; + return; + + case CALMA_UNDEFINED: + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaAllowUndefined)); +#else + TxPrintf("Writing of GDS file with undefined cells is %sallowed.\n", + (CalmaAllowUndefined) ? "" : "dis"); +#endif + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + option = Lookup(cmd->tx_argv[2], cmdCalmaAllowDisallow); + if (option < 0) + goto wrongNumArgs; + CalmaAllowUndefined = (option < 2) ? FALSE : TRUE; return; case CALMA_CONTACTS: @@ -290,7 +322,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaContactArrays = (option < 3) ? FALSE : TRUE; + CalmaContactArrays = (option < 4) ? FALSE : TRUE; return; case CALMA_DRCCHECK: @@ -310,7 +342,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaNoDRCCheck = (option < 3) ? TRUE : FALSE; + CalmaNoDRCCheck = (option < 4) ? TRUE : FALSE; return; case CALMA_FLATTEN: @@ -341,7 +373,103 @@ CmdCalma(w, cmd) goto wrongNumArgs; } else - CalmaFlattenUses = (option < 3) ? FALSE : TRUE; + CalmaFlattenUses = (option < 4) ? FALSE : TRUE; + return; + + case CALMA_FLATGLOB: + + if (cmd->tx_argc == 2) + { + if (CalmaFlattenUsesByName != NULL) + { + int i = 0; + char *pattern; +#ifdef MAGIC_WRAPPER + Tcl_Obj *lobj = Tcl_NewListObj(0, NULL); + while (TRUE) + { + pattern = CalmaFlattenUsesByName[i]; + if (pattern == NULL) break; + i++; + Tcl_ListObjAppendElement(magicinterp, lobj, + Tcl_NewStringObj(pattern, -1)); + } + Tcl_SetObjResult(magicinterp, lobj); +#else + TxPrintf("Glob patterns for cells to flatten:\n"); + while (TRUE) + { + pattern = CalmaFlattenUsesByName[i]; + if (pattern == NULL) break; + i++; + TxPrintf(" \"%s\"\n", pattern); + } +#endif + } + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + if (!strcasecmp(cmd->tx_argv[2], "none")) + { + int i = 0; + if (CalmaFlattenUsesByName == (char **)NULL) return; + while (TRUE) + { + char *pattern = CalmaFlattenUsesByName[i]; + if (pattern == NULL) break; + freeMagic(pattern); + i++; + } + freeMagic(CalmaFlattenUsesByName); + CalmaFlattenUsesByName = (char **)NULL; + } + else + { + char **newpatterns; + char *pattern; + int i = 0; + + if (CalmaFlattenUsesByName == (char **)NULL) + i = 1; + else + { + while (TRUE) + { + pattern = CalmaFlattenUsesByName[i++]; + if (pattern == NULL) break; + } + } + newpatterns = (char **)mallocMagic((i + 1) * sizeof(char *)); + i = 0; + if (CalmaFlattenUsesByName != (char **)NULL) + { + while (TRUE) + { + pattern = CalmaFlattenUsesByName[i]; + if (pattern == NULL) break; + newpatterns[i] = StrDup((char **)NULL, pattern); + i++; + } + } + newpatterns[i++] = StrDup((char **)NULL, cmd->tx_argv[2]); + newpatterns[i] = (char *)NULL; + + i = 0; + if (CalmaFlattenUsesByName != (char **)NULL) + { + while (TRUE) + { + pattern = CalmaFlattenUsesByName[i]; + if (pattern == NULL) break; + freeMagic(pattern); + i++; + } + freeMagic(CalmaFlattenUsesByName); + } + CalmaFlattenUsesByName = newpatterns; + } return; case CALMA_ORDERING: @@ -364,7 +492,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaPostOrder = (option < 3) ? FALSE : TRUE; + CalmaPostOrder = (option < 4) ? FALSE : TRUE; return; case CALMA_ARRAYS: @@ -384,7 +512,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaFlattenArrays = (option < 3) ? FALSE : TRUE; + CalmaFlattenArrays = (option < 4) ? FALSE : TRUE; return; case CALMA_LOWER: @@ -404,7 +532,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaDoLower = (option < 3) ? FALSE : TRUE; + CalmaDoLower = (option < 4) ? FALSE : TRUE; return; case CALMA_MERGE: @@ -426,7 +554,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaMergeTiles = (option < 3) ? FALSE : TRUE; + CalmaMergeTiles = (option < 4) ? FALSE : TRUE; return; case CALMA_POLYS: @@ -448,7 +576,47 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[3], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaSubcellPolygons = (option < 3) ? FALSE : TRUE; + CalmaSubcellPolygons = (option < 4) ? FALSE : TRUE; + return; + + case CALMA_NO_DUP: + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaNoDuplicates)); +#else + TxPrintf("Cell defs that exist before reading GDS will not be paresd.\n", + (CalmaNoDuplicates) ? "not " : ""); +#endif + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); + if (option < 0) + goto wrongNumArgs; + CalmaNoDuplicates = (option < 4) ? FALSE : TRUE; + return; + + case CALMA_NO_STAMP: + if (cmd->tx_argc == 2) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaNoDateStamp)); +#else + TxPrintf("Structures will contain a %s header creation date stamp.\n", + (CalmaNoDateStamp) ? "zero" : "valid"); +#endif + return; + } + else if (cmd->tx_argc != 3) + goto wrongNumArgs; + + option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); + if (option < 0) + goto wrongNumArgs; + CalmaNoDateStamp = (option < 4) ? FALSE : TRUE; return; case CALMA_PATHS: @@ -470,7 +638,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[3], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaSubcellPaths = (option < 3) ? FALSE : TRUE; + CalmaSubcellPaths = (option < 4) ? FALSE : TRUE; return; case CALMA_READONLY: @@ -490,7 +658,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CalmaReadOnly = (option < 3) ? FALSE : TRUE; + CalmaReadOnly = (option < 4) ? FALSE : TRUE; return; case CALMA_RESCALE: @@ -510,7 +678,7 @@ CmdCalma(w, cmd) option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo); if (option < 0) goto wrongNumArgs; - CIFRescaleAllow = (option < 3) ? FALSE : TRUE; + CIFRescaleAllow = (option < 4) ? FALSE : TRUE; if (!CIFRescaleAllow) CIFWarningLevel = CIF_WARN_LIMIT; return; @@ -667,8 +835,10 @@ CmdCellname(w, cmd) "window list top-level cell of a layout window", "create create a new cell definition", "delete delete the named cell definition", + "dereference reload the named cell from the search paths", "filepath list the full path of the file for the cell", "flags list option flags of the indicated cell definition", + "timestamp list the cell timestamp", "lock lock the named cell (prevent changes to cell use)", "unlock unlock the named cell (allow changes to cell use)", "property list or set cell definition properties", @@ -681,10 +851,11 @@ CmdCellname(w, cmd) }; typedef enum { IDX_CHILDREN, IDX_PARENTS, IDX_EXISTS, IDX_SELF, IDX_INSTANCE, IDX_CHILDINST, IDX_CELLDEF, IDX_ALLCELLS, - IDX_TOPCELLS, IDX_IN_WINDOW, IDX_CREATE, - IDX_DELETE, IDX_FILEPATH, IDX_FLAGS, IDX_LOCK, IDX_UNLOCK, - IDX_PROPERTY, IDX_ABUTMENT, IDX_ORIENTATION, IDX_RENAME, - IDX_READWRITE, IDX_MODIFIED } optionType; + IDX_TOPCELLS, IDX_IN_WINDOW, IDX_CREATE, IDX_DELETE, + IDX_DEREFERENCE, IDX_FILEPATH, IDX_FLAGS, IDX_TIMESTAMP, + IDX_LOCK, IDX_UNLOCK, IDX_PROPERTY, IDX_ABUTMENT, + IDX_ORIENTATION, IDX_RENAME, IDX_READWRITE, + IDX_MODIFIED } optionType; if (strstr(cmd->tx_argv[0], "in")) is_cellname = FALSE; @@ -721,8 +892,9 @@ CmdCellname(w, cmd) if (option < 0) goto badusage; if ((locargc > 3) && (option != IDX_RENAME) && (option != IDX_DELETE) && - (option != IDX_READWRITE) && (option != IDX_PROPERTY) && - (option != IDX_FILEPATH) && (option != IDX_ORIENTATION)) + (option != IDX_DEREFERENCE) && (option != IDX_READWRITE) && + (option != IDX_PROPERTY) && (option != IDX_FILEPATH) && + (option != IDX_ORIENTATION) && (option != IDX_TIMESTAMP)) goto badusage; if ((locargc > 4) && (option != IDX_PROPERTY)) @@ -768,6 +940,7 @@ CmdCellname(w, cmd) return; case IDX_IN_WINDOW: case IDX_READWRITE: case IDX_FLAGS: case IDX_PROPERTY: case IDX_FILEPATH: case IDX_MODIFIED: + case IDX_DEREFERENCE: case IDX_TIMESTAMP: TxError("Function unimplemented for instances.\n"); return; case IDX_DELETE: @@ -845,6 +1018,30 @@ CmdCellname(w, cmd) TxError("Delete cell command missing cellname\n"); break; + case IDX_DEREFERENCE: + /* Unload the cell definition and re-read with search paths */ + if (locargc == 3) + { + void cmdFlushCell(); + + if (cellname == NULL) + cellDef = EditRootDef; + else + cellDef = DBCellLookDef(cellname); + + /* Reload cell with dereferencing */ + if (cellDef == NULL) + { + TxError("No such cell \"%s\"\n", cellname); + break; + } + cmdFlushCell(cellDef, TRUE); + SelectClear(); + } + else + TxError("Dereference cell command missing cellname\n"); + break; + case IDX_READWRITE: if (cellname == NULL) cellDef = EditRootDef; @@ -994,6 +1191,35 @@ CmdCellname(w, cmd) } break; + case IDX_TIMESTAMP: + if (cellname == NULL) + cellDef = EditRootDef; + else + cellDef = DBCellLookDef(cellname); + if (cellDef == (CellDef *) NULL) + { + TxError("Unknown cell %s\n", cellname); + break; + } + if ((locargc == 3) || (locargc == 2 && cellname == NULL)) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(cellDef->cd_timestamp)); +#else + TxPrintf("Timestamp for cell %s = %d\n", cellname, cellDef->cd_timestamp); +#endif + } + else if (locargc == 4 || (locargc == 3 && cellname == NULL)) + { + int timestamp = atoi(cmd->tx_argv[2 + ((cellname == NULL) ? 0 : 1)]); + if (timestamp != cellDef->cd_timestamp) + { + cellDef->cd_timestamp = timestamp; + cellDef->cd_flags &= ~CDGETNEWSTAMP; + } + } + break; + case IDX_FLAGS: if (cellname == NULL) cellDef = EditRootDef; @@ -1133,6 +1359,7 @@ CmdCif(w, cmd) bool doforall = FALSE; float curscale; int argc = cmd->tx_argc; + int argshift; char **argv = cmd->tx_argv; static char *cmdCifWarnOptions[] = { "default", "none", "align", @@ -1288,10 +1515,10 @@ CmdCif(w, cmd) TxError("Box requested but no cursor box exists\n"); return; } - CIFCoverageLayer(rootDef, &box, argv[2]); + CIFCoverageLayer(rootDef, &box, argv[2], dolist); } else if (argc == 3) - CIFCoverageLayer(rootDef, &rootDef->cd_bbox, argv[2]); + CIFCoverageLayer(rootDef, &rootDef->cd_bbox, argv[2], dolist); else goto wrongNumArgs; @@ -3454,7 +3681,7 @@ CmdDrc(w, cmd) } #ifdef MAGIC_WRAPPER - if (count_total >= 0) + if ((count_total >= 0) || (!dolist)) { if (dolist) Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(count_total)); diff --git a/commands/CmdE.c b/commands/CmdE.c index 683deb3b..cd6265c1 100644 --- a/commands/CmdE.c +++ b/commands/CmdE.c @@ -951,7 +951,7 @@ CmdExtract(w, cmd) "style [stylename] set current extraction parameter style", "unique [option] generate unique names when different nodes\n\ have the same name", - "warn [ [no] option] enable/disable reporting of non-fatal errors", + "warn [ [no] option] enable/disable reporting of non-serious errors", NULL }; diff --git a/commands/CmdFI.c b/commands/CmdFI.c index b3b8b1be..17f30ff9 100644 --- a/commands/CmdFI.c +++ b/commands/CmdFI.c @@ -726,6 +726,45 @@ usage: TxError("Usage: findbox [zoom]\n"); } +/* + * ---------------------------------------------------------------------------- + * + * cmdFindLabelFunc -- + * + * Callback function from CmdFindLabel. Return 1 to stop the search on the + * Nth instance of the label named "label", where N is passed through the + * client data as lsr_occur. + * + * The client data record lsr_rect is left pointing to the label location + * when the Nth label instance is found. + * + * ---------------------------------------------------------------------------- + */ + +typedef struct _labsearchrec +{ + Rect lsr_rect; + int lsr_occur; +} LabSearchRec; + + +int cmdFindLabelFunc(rect, name, label, cdarg) + Rect *rect; + char *name; + Label *label; + LabSearchRec *cdarg; +{ + if (cdarg->lsr_occur == 0) + { + cdarg->lsr_rect = *rect; + return 1; + } + else + cdarg->lsr_occur--; + + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -747,16 +786,6 @@ usage: * ---------------------------------------------------------------------------- */ -int cmdFindLabelFunc(rect, name, label, cdarg) - Rect *rect; - char *name; - Label *label; - Rect *cdarg; -{ - *cdarg = *rect; - return 1; -} - void CmdFindLabel(w, cmd) MagWindow *w; @@ -764,17 +793,30 @@ CmdFindLabel(w, cmd) { CellDef *boxDef; CellUse *labUse; - Rect box, cmdFindLabelRect; + Rect box; char *labname; - int found; + int found, occur, plainargs; bool doglob = FALSE; /* csh-style glob matching (see utils/match.c) */ + LabSearchRec lsr; int dbListLabels(); /* forward declaration */ - if ((cmd->tx_argc == 3) && !strncmp(cmd->tx_argv[1], "-glob", 5)) + plainargs = cmd->tx_argc; + if ((plainargs > 2) && !strncmp(cmd->tx_argv[1], "-glob", 5)) + { + plainargs--; doglob = TRUE; - else if (cmd->tx_argc != 2) + } + if ((plainargs != 2) && (plainargs != 3)) goto usage; + occur = 0; + if (plainargs == 3) + { + char *occurstr = cmd->tx_argv[plainargs - 1]; + if (StrIsInt(occurstr)) + occur = atoi(occurstr); + } + if (w == NULL) { TxError("Point to a window first.\n"); @@ -794,7 +836,7 @@ CmdFindLabel(w, cmd) return; }; - labname = (cmd->tx_argc == 3) ? cmd->tx_argv[2] : cmd->tx_argv[1]; + labname = cmd->tx_argv[1 + (doglob) ? 1 : 0]; labUse = EditCellUse; if (labUse == NULL) labUse = (CellUse *)w->w_surfaceID; @@ -815,15 +857,17 @@ CmdFindLabel(w, cmd) { /* Exact-match label search (corrected by Nishit, 10/14/04) */ + lsr.lsr_occur = occur; + found = DBSrLabelLoc(labUse, labname, cmdFindLabelFunc, - (ClientData) &cmdFindLabelRect); + (ClientData) &lsr); if (found) { - if (cmdFindLabelRect.r_xbot == cmdFindLabelRect.r_xtop) - cmdFindLabelRect.r_xtop++; - if (cmdFindLabelRect.r_ybot == cmdFindLabelRect.r_ytop) - cmdFindLabelRect.r_ytop++; - ToolMoveBox(TOOL_BL,&cmdFindLabelRect.r_ll,FALSE,labUse->cu_def); - ToolMoveCorner(TOOL_TR,&cmdFindLabelRect.r_ur,FALSE,labUse->cu_def); + if (lsr.lsr_rect.r_xbot == lsr.lsr_rect.r_xtop) + lsr.lsr_rect.r_xtop++; + if (lsr.lsr_rect.r_ybot == lsr.lsr_rect.r_ytop) + lsr.lsr_rect.r_ytop++; + ToolMoveBox(TOOL_BL, &lsr.lsr_rect.r_ll, FALSE, labUse->cu_def); + ToolMoveCorner(TOOL_TR, &lsr.lsr_rect.r_ur, FALSE, labUse->cu_def); } else { TxError("Couldn't find label %s\n", labname); } @@ -869,10 +913,12 @@ dbListLabels(scx, label, tpath, cdarg) * Implement the "flush" command. * Throw away all changes made within magic to the specified cell, * and re-read it from disk. If no cell is specified, the default - * is the current edit cell. + * is the current edit cell. If "-dereference" is specified as an + * option, then re-read the cell from the search path instead of + * the file path that has been associated with the cell. * * Usage: - * flush [cellname] + * flush [cellname] [-dereference] * * Results: * None. @@ -893,10 +939,17 @@ CmdFlush(w, cmd) int action; static char *actionNames[] = { "no", "yes", 0 }; char *prompt; + bool dereference = FALSE; + + if (!strncmp(cmd->tx_argv[cmd->tx_argc - 1], "-deref", 6)) + { + dereference = TRUE; + cmd->tx_argc--; + } if (cmd->tx_argc > 2) { - TxError("Usage: flush [cellname]\n"); + TxError("Usage: flush [cellname] [dereference]\n"); return; } @@ -926,7 +979,7 @@ CmdFlush(w, cmd) return; } - cmdFlushCell(def); + cmdFlushCell(def, dereference); SelectClear(); TxPrintf("[Flushed]\n"); } @@ -1565,8 +1618,8 @@ CmdFindNetProc(nodename, use, rect, warn_not_found) /* go to that point (transformed to the top level of the design */ /* hierarchy). */ - /* see extract/extractInt.h for the format of the node, found in */ - /* extMakeNodeNumPrint(), which is a macro, not a subroutine. */ + /* see extract/extBasic.c for the format of the node, found */ + /* in extMakeNodeNumPrint(). */ locvalid = FALSE; if ((xstr = strchr(s, '_')) != NULL) @@ -1816,6 +1869,9 @@ flatCopyAllLabels(scx, lab, tpath, targetUse) char labelname[1024]; char *n, *f, c; + /* Ignore null labels */ + if (*lab->lab_text == '\0') return 0; + def = targetUse->cu_def; if (!GEO_LABEL_IN_AREA(&lab->lab_rect, &(scx->scx_area))) return 0; GeoTransRect(&scx->scx_trans, &lab->lab_rect, &labTargetRect); @@ -1876,7 +1932,7 @@ CmdFlatten(w, cmd) TxCommand *cmd; { int rval, xMask; - bool dolabels, toplabels, invert; + bool dolabels, dobox, toplabels, invert; char *destname; CellDef *newdef; CellUse *newuse; @@ -1887,6 +1943,7 @@ CmdFlatten(w, cmd) xMask = CU_DESCEND_ALL; dolabels = TRUE; toplabels = FALSE; + dobox = FALSE; rval = 0; if (cmd->tx_argc > 2) @@ -1912,6 +1969,9 @@ CmdFlatten(w, cmd) { switch(cmd->tx_argv[i][3]) { + case 'b': + dobox = (invert) ? FALSE : TRUE; + break; case 'l': dolabels = (invert) ? FALSE : TRUE; break; @@ -1926,7 +1986,7 @@ CmdFlatten(w, cmd) break; default: TxError("options are: -nolabels, -nosubcircuits " - "-novendor, -dotoplabels\n"); + "-novendor, -dotoplabels, -dobox\n"); break; } } @@ -1953,7 +2013,6 @@ CmdFlatten(w, cmd) (void) StrDup(&(newuse->cu_id), "Flattened cell"); DBSetTrans(newuse, &GeoIdentityTransform); newuse->cu_expandMask = CU_DESCEND_SPECIAL; - UndoDisable(); flatDestUse = newuse; if (EditCellUse) @@ -1961,9 +2020,28 @@ CmdFlatten(w, cmd) else scx.scx_use = (CellUse *)w->w_surfaceID; - scx.scx_area = scx.scx_use->cu_def->cd_bbox; + if (dobox) + { + CellDef *boxDef; + + if (!ToolGetBox(&boxDef, &scx.scx_area)) + { + TxError("Put the box in a window first.\n"); + return; + } + else if (boxDef != scx.scx_use->cu_def) + { + TxError("The box is not in the edit cell!\n"); + return; + } + } + else + scx.scx_area = scx.scx_use->cu_def->cd_bbox; + scx.scx_trans = GeoIdentityTransform; + UndoDisable(); + DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, xMask, flatDestUse); if (dolabels) FlatCopyAllLabels(&scx, &DBAllTypeBits, xMask, flatDestUse); @@ -1980,5 +2058,3 @@ CmdFlatten(w, cmd) UndoEnable(); } - - diff --git a/commands/CmdLQ.c b/commands/CmdLQ.c index 1c68635b..bab7b99f 100644 --- a/commands/CmdLQ.c +++ b/commands/CmdLQ.c @@ -309,6 +309,10 @@ CmdLabel(w, cmd) CmdLabelProc(p, font, size, rotate, offx, offy, pos, sticky, type); } +#define LOAD_NOWINDOW 0 +#define LOAD_DEREFERENCE 1 +#define LOAD_FORCE 2 +#define LOAD_QUIET 3 /* * ---------------------------------------------------------------------------- @@ -318,7 +322,7 @@ CmdLabel(w, cmd) * Implement the "load" command. * * Usage: - * load [name [scaled n [d]]] [-force] [-nowindow] [-dereference] + * load [name [scaled n [d]]] [-force] [-nowindow] [-dereference] [-quiet] * * If name is supplied, then the window containing the point tool is * remapped so as to edit the cell with the given name. @@ -354,29 +358,52 @@ CmdLoad(w, cmd) { int n = 1; int d = 1; + int option; int locargc = cmd->tx_argc; bool ignoreTech = FALSE; bool noWindow = FALSE; bool dereference = FALSE; + bool beQuiet = FALSE; + bool saveVerbose; int keepGoing(); /* forward declaration */ + extern bool DBVerbose; /* from DBio.c */ + + saveVerbose = DBVerbose; + + static char *cmdLoadOption[] = + { + "-nowindow load file but do not display in the layout window", + "-dereference use search paths and ignore embedded cell paths in file", + "-force load file even if tech in header does not match", + "-quiet no alert if file does not exist", + NULL + }; + + while (cmd->tx_argv[locargc - 1][0] == '-') + { + option = Lookup(cmd->tx_argv[locargc - 1], cmdLoadOption); + switch (option) + { + case LOAD_NOWINDOW: + noWindow = TRUE; + break; + case LOAD_DEREFERENCE: + dereference = TRUE; + break; + case LOAD_FORCE: + ignoreTech = TRUE; + break; + case LOAD_QUIET: + beQuiet = TRUE; + break; + default: + TxError("No such option \"%s\".\n", cmd->tx_argv[locargc - 1]); + } + locargc--; + } if (locargc > 2) { - if (!strncmp(cmd->tx_argv[locargc - 1], "-nowindow", 8)) - { - locargc--; - noWindow = TRUE; - } - if (!strncmp(cmd->tx_argv[locargc - 1], "-deref", 5)) - { - locargc--; - dereference = TRUE; - } - if (!strncmp(cmd->tx_argv[locargc - 1], "-force", 6)) - { - locargc--; - ignoreTech = TRUE; - } if ((locargc >= 4) && !strncmp(cmd->tx_argv[2], "scale", 5) && StrIsInt(cmd->tx_argv[3])) { @@ -397,7 +424,7 @@ CmdLoad(w, cmd) else if (!ignoreTech && !noWindow && !dereference) { TxError("Usage: %s name [scaled n [d]] [-force] " - "[-nowindow] [-dereference]\n", + "[-nowindow] [-dereference] [-quiet]\n", cmd->tx_argv[0]); return; } @@ -422,8 +449,10 @@ CmdLoad(w, cmd) *(cmd->tx_argv[1] + strlen(cmd->tx_argv[1]) - 1) = '\0'; } #endif + DBVerbose = !beQuiet; DBWloadWindow((noWindow == TRUE) ? NULL : w, cmd->tx_argv[1], ignoreTech, FALSE, dereference); + DBVerbose = saveVerbose; if ((n > 1) || (d > 1)) { @@ -456,7 +485,12 @@ CmdLoad(w, cmd) ReduceFraction(&DBLambda[0], &DBLambda[1]); } } - else DBWloadWindow(w, (char *) NULL, TRUE, FALSE, FALSE); + else + { + DBVerbose = !beQuiet; + DBWloadWindow(w, (char *) NULL, TRUE, FALSE, FALSE); + DBVerbose = saveVerbose; + } } /* @@ -1298,7 +1332,7 @@ CmdPort(w, cmd) char **msg; int argstart; int i, refidx, idx, pos, type, option, argc; - unsigned short dirmask; + unsigned int dirmask; bool found; bool nonEdit = FALSE; Label *lab, *sl; diff --git a/commands/CmdRS.c b/commands/CmdRS.c index 95178efa..3adea56f 100644 --- a/commands/CmdRS.c +++ b/commands/CmdRS.c @@ -24,6 +24,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include #include +#include #include "tcltk/tclmagic.h" #include "utils/magic.h" @@ -53,6 +54,61 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ extern void DisplayWindow(); +/* + * ---------------------------------------------------------------------------- + * + * CmdRandom + * + * Generate a random integer or set the random seed. This is mainly + * used for seeding the random number generator for the GDS write + * routine when GDS write is assigning a random prefix to ensure + * uniqueness of names in a GDS library read from a file instead of + * generated from the database. + * + * Results: + * None. + * + * Side effects: + * None. + * + * ---------------------------------------------------------------------------- + */ + +void +CmdRandom(w, cmd) + MagWindow *w; + TxCommand *cmd; +{ + int value; + + if (cmd->tx_argc == 1) + { + /* Return a random number */ + +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(random())); +#else + TxPrintf("%d", random()); +#endif + } + else if ((cmd->tx_argc >= 2) && (!strcmp(cmd->tx_argv[1], "seed"))) + { + if (cmd->tx_argc == 3) + { + value = atoi(cmd->tx_argv[2]); + } + else + { + value = (int)time(NULL); + } + srandom(value); + } + else + { + TxPrintf("usage: random [seed []]\n"); + return; + } +} #if !defined(NO_SIM_MODULE) && defined(RSIM_MODULE) /* diff --git a/commands/CmdSubrs.c b/commands/CmdSubrs.c index 0f3b4ec1..c824c5d1 100644 --- a/commands/CmdSubrs.c +++ b/commands/CmdSubrs.c @@ -285,12 +285,15 @@ CmdInit() */ void -cmdFlushCell(def) +cmdFlushCell(def, force_deref) CellDef *def; + bool force_deref; { CellUse *parentUse; bool dereference; + if (def == NULL) return; + /* Disallow flushing a cell that contains the edit cell as a child */ if (EditCellUse && (EditCellUse->cu_parent == def)) { @@ -300,6 +303,15 @@ cmdFlushCell(def) } UndoFlush(); + + if (force_deref) + { + /* Force dereferencing */ + def->cd_flags |= CDDEREFERENCE; + freeMagic(def->cd_file); + def->cd_file = NULL; + } + DBWAreaChanged(def, &def->cd_bbox, DBW_ALLWINDOWS, (TileTypeBitMask *) NULL); for (parentUse = def->cd_parents; parentUse != NULL; diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index c9b1954a..f2a54196 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -1818,7 +1818,7 @@ cmdWriteallFunc(def, cmd) cmdSaveCell(def, (char *) NULL, FALSE, TRUE); break; case 1: /* Flush */ - cmdFlushCell(def); + cmdFlushCell(def, FALSE); break; case 2: /* Skip */ break; diff --git a/database/DBcellcopy.c b/database/DBcellcopy.c index bf1a26e8..8362240b 100644 --- a/database/DBcellcopy.c +++ b/database/DBcellcopy.c @@ -48,7 +48,7 @@ static PaintResultType (*dbCurPaintTbl)[NT][NT] = DBPaintResultTbl; * such as the design-rule checker that need to use, for example, * DBPaintPlaneMark instead of the standard version. */ -static void (*dbCurPaintPlane)() = DBPaintPlaneWrapper; +static int (*dbCurPaintPlane)() = DBPaintPlaneWrapper; /* Structure passed to DBTreeSrTiles() */ struct copyAllArg @@ -56,6 +56,7 @@ struct copyAllArg TileTypeBitMask *caa_mask; /* Mask of tile types to be copied */ Rect caa_rect; /* Clipping rect in target coords */ CellUse *caa_targetUse; /* Use to which tiles are copied */ + void (*caa_func)(); /* Callback function for off-grid points */ Rect *caa_bbox; /* Bbox of material copied (in * targetUse coords). Used only when * copying cells. @@ -96,7 +97,7 @@ struct copyLabelArg * ---------------------------------------------------------------------------- */ -void +int DBPaintPlaneWrapper(def, pNum, type, area, undo) CellDef *def; int pNum; @@ -106,12 +107,14 @@ DBPaintPlaneWrapper(def, pNum, type, area, undo) { TileType loctype = type & TT_LEFTMASK; Rect expand; + int result; undo->pu_pNum = pNum; - DBNMPaintPlane(def->cd_planes[pNum], type, area, + result = DBNMPaintPlane(def->cd_planes[pNum], type, area, dbCurPaintTbl[pNum][loctype], undo); GEO_EXPAND(area, 1, &expand); DBMergeNMTiles(def->cd_planes[pNum], &expand, undo); + return result; } /* @@ -126,7 +129,7 @@ DBPaintPlaneWrapper(def, pNum, type, area, undo) * ---------------------------------------------------------------------------- */ -void +int DBPaintPlaneMark(def, pNum, type, area, undo) CellDef *def; int pNum; @@ -137,7 +140,7 @@ DBPaintPlaneMark(def, pNum, type, area, undo) TileType loctype = type & TT_LEFTMASK; undo->pu_pNum = pNum; - DBNMPaintPlane0(def->cd_planes[pNum], type, area, + return DBNMPaintPlane0(def->cd_planes[pNum], type, area, dbCurPaintTbl[pNum][loctype], undo, (unsigned char)PAINT_MARK); } @@ -147,7 +150,7 @@ DBPaintPlaneMark(def, pNum, type, area, undo) * ---------------------------------------------------------------------------- */ -void +int DBPaintPlaneXor(def, pNum, type, area, undo) CellDef *def; int pNum; @@ -158,7 +161,7 @@ DBPaintPlaneXor(def, pNum, type, area, undo) TileType loctype = type & TT_LEFTMASK; undo->pu_pNum = pNum; - DBNMPaintPlane0(def->cd_planes[pNum], type, area, + return DBNMPaintPlane0(def->cd_planes[pNum], type, area, dbCurPaintTbl[pNum][loctype], undo, (unsigned char)PAINT_XOR); } @@ -175,7 +178,7 @@ DBPaintPlaneXor(def, pNum, type, area, undo) * ---------------------------------------------------------------------------- */ -void +int DBPaintPlaneActive(def, pNum, type, area, undo) CellDef *def; int pNum; @@ -200,11 +203,13 @@ DBPaintPlaneActive(def, pNum, type, area, undo) DBPaintPlaneWrapper(def, pNum, t | (type & (TT_SIDE | TT_DIRECTION | TT_DIAGONAL)), area, undo); - return; + return 0; } } if (TTMaskHasType(&DBActiveLayerBits, loctype)) - DBPaintPlaneWrapper(def, pNum, type, area, undo); + return DBPaintPlaneWrapper(def, pNum, type, area, undo); + else + return 0; } /* @@ -241,6 +246,7 @@ DBCellCopyManhattanPaint(scx, mask, xMask, targetUse) arg.caa_mask = mask; arg.caa_targetUse = targetUse; + arg.caa_func = NULL; GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &arg.caa_rect); (void) DBTreeSrTiles(scx, mask, xMask, dbCopyManhattanPaint, (ClientData) &arg); @@ -281,6 +287,52 @@ DBCellCopyAllPaint(scx, mask, xMask, targetUse) arg.caa_mask = mask; arg.caa_targetUse = targetUse; + arg.caa_func = NULL; + GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &arg.caa_rect); + + /* Add any stacking types for the search (but not to mask passed as arg!) */ + locMask = *mask; + DBMaskAddStacking(&locMask); + + DBTreeSrTiles(scx, &locMask, xMask, dbCopyAllPaint, (ClientData) &arg); +} + +/* + *----------------------------------------------------------------------------- + * + * DBCellCheckCopyAllPaint -- + * + * Copy paint from the tree rooted at scx->scx_use to the paint planes + * of targetUse, transforming according to the transform in scx. + * Only the types specified by typeMask are copied. + * + * Results: + * None. + * + * Side effects: + * Updates the paint planes in targetUse. + * + *----------------------------------------------------------------------------- + */ + +void +DBCellCheckCopyAllPaint(scx, mask, xMask, targetUse, func) + SearchContext *scx; /* Describes root cell to search, area to + * copy, transform from root cell to coords + * of targetUse. + */ + TileTypeBitMask *mask; /* Types of tiles to be yanked/stuffed */ + int xMask; /* Expansion state mask to be used in search */ + CellUse *targetUse; /* Cell into which material is to be stuffed */ + void (*func)(); /* Function to call on tile split error */ +{ + TileTypeBitMask locMask; + struct copyAllArg arg; + int dbCopyAllPaint(); + + arg.caa_mask = mask; + arg.caa_targetUse = targetUse; + arg.caa_func = func; GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &arg.caa_rect); /* Add any stacking types for the search (but not to mask passed as arg!) */ @@ -441,7 +493,7 @@ DBCellCopyPaint(scx, mask, xMask, targetUse) for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(planeMask, pNum)) { - cxp.tc_plane = pNum; /* not used? */ + cxp.tc_plane = pNum; (void) DBSrPaintArea((Tile *) NULL, scx->scx_use->cu_def->cd_planes[pNum], &scx->scx_area, mask, dbCopyAllPaint, (ClientData) &cxp); @@ -590,6 +642,7 @@ dbCopyAllPaint(tile, cxp) CellDef *def; TileType type = TiGetTypeExact(tile); int pNum = cxp->tc_plane; + int result; TileTypeBitMask *typeMask; /* @@ -752,7 +805,12 @@ topbottom: splitdone: - (*dbCurPaintPlane)(def, pNum, dinfo | type, &targetRect, &ui); + result = (*dbCurPaintPlane)(def, pNum, dinfo | type, &targetRect, &ui); + if ((result != 0) && (arg->caa_func != NULL)) + { + /* result == 1 used exclusively for DRC off-grid error flagging */ + DRCOffGridError(&targetRect); + } return (0); } @@ -1013,11 +1071,11 @@ DBNewPaintTable(newTable))[NT][NT] * ---------------------------------------------------------------------------- */ -VoidProc +IntProc DBNewPaintPlane(newProc) - void (*newProc)(); /* Address of new procedure */ + int (*newProc)(); /* Address of new procedure */ { - void (*oldProc)() = dbCurPaintPlane; + int (*oldProc)() = dbCurPaintPlane; dbCurPaintPlane = newProc; return (oldProc); } diff --git a/database/DBcellsrch.c b/database/DBcellsrch.c index 8740bf09..fb6dc5c2 100644 --- a/database/DBcellsrch.c +++ b/database/DBcellsrch.c @@ -21,6 +21,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #endif /* not lint */ #include +#include #include "utils/magic.h" #include "utils/malloc.h" @@ -767,6 +768,9 @@ cleanup: * remaining elements of the current array are skipped, but the * search is not aborted. * + * NOTE: Unlike DBTreeSrTiles and DBTreeSrLabels, the function is not + * applied to the top level cell, only to descendents. + * * Each element of an array is returned separately. * * Results: @@ -847,9 +851,8 @@ dbTreeCellSrFunc(scx, fp) if ((fp->tf_xmask == CU_DESCEND_NO_LOCK) && (use->cu_flags & CU_LOCKED)) return 2; - else if ((!DBDescendSubcell(use, fp->tf_xmask)) || - (fp->tf_xmask == CU_DESCEND_ALL)) - result = (*fp->tf_func)(scx, fp->tf_arg); + else if (!DBDescendSubcell(use, fp->tf_xmask)) + return (*fp->tf_func)(scx, fp->tf_arg); else { if ((use->cu_def->cd_flags & CDAVAILABLE) == 0) @@ -858,9 +861,15 @@ dbTreeCellSrFunc(scx, fp) if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL)) return 0; } - result = DBCellSrArea(scx, dbTreeCellSrFunc, (ClientData) fp); } - return result; + if (fp->tf_xmask == CU_DESCEND_ALL) + { + result = (*fp->tf_func)(scx, fp->tf_arg); + if (result != 0) return result; + } + + /* Run recursively on children in search area */ + return DBCellSrArea(scx, dbTreeCellSrFunc, (ClientData) fp); } /* @@ -1775,6 +1784,149 @@ DBSrCellUses(cellDef, func, arg) return retval; } +/* Structure used by dbScaleProp() and dbMoveProp() */ +typedef struct _cellpropstruct { + Point cps_point; + CellDef *cps_def; +} CellPropStruct; + +/* + * ---------------------------------------------------------------------------- + * + * dbScaleProp -- + * + * Callback function for dbScaleCell. Finds properties that represent + * internal geometry (FIXED_BBOX and MASKHINTS_*) and scale the values + * by the numerator / denominator values passed as a pointer to a Point + * structure, where p_x is the numerator value and p_y is the denominator + * value. + * + * ---------------------------------------------------------------------------- + */ + +int dbScaleProp(name, value, cps) + char *name; + char *value; + CellPropStruct *cps; +{ + int scalen, scaled; + char *newvalue, *vptr; + Rect r; + + if (!strcmp(name, "FIXED_BBOX")) + { + if (sscanf(value, "%d %d %d %d", &r.r_xbot, &r.r_ybot, + &r.r_xtop, &r.r_ytop) == 4) + { + /* Scale numerator held in point X value, */ + /* scale denominator held in point Y value */ + + scalen = cps->cps_point.p_x; + scaled = cps->cps_point.p_y; + + DBScalePoint(&r.r_ll, scalen, scaled); + DBScalePoint(&r.r_ur, scalen, scaled); + + newvalue = (char *)mallocMagic(40); + sprintf(newvalue, "%d %d %d %d", r.r_xbot, r.r_ybot, + r.r_xtop, r.r_ytop); + DBPropPut(cps->cps_def, name, newvalue); + } + } + else if (!strncmp(name, "MASKHINTS_", 10)) + { + char *vptr, *lastval; + int lastlen; + + newvalue = (char *)NULL; + vptr = value; + while (*vptr != '\0') + { + if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot, + &r.r_xtop, &r.r_ytop) == 4) + { + /* Scale numerator held in point X value, */ + /* scale denominator held in point Y value */ + + scalen = cps->cps_point.p_x; + scaled = cps->cps_point.p_y; + + DBScalePoint(&r.r_ll, scalen, scaled); + DBScalePoint(&r.r_ur, scalen, scaled); + + lastval = newvalue; + lastlen = (lastval) ? strlen(lastval) : 0; + newvalue = mallocMagic(40 + lastlen); + + if (lastval) + strcpy(newvalue, lastval); + else + *newvalue = '\0'; + + sprintf(newvalue + lastlen, "%s%d %d %d %d", (lastval) ? " " : "", + r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop); + if (lastval) freeMagic(lastval); + + /* Parse through the four values and check if there's more */ + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + while (*vptr && !isspace(*vptr)) vptr++; + while (*vptr && isspace(*vptr)) vptr++; + } + else break; + } + if (newvalue) + DBPropPut(cps->cps_def, name, newvalue); + } + return 0; /* Keep enumerating through properties */ +} + +/* + * ---------------------------------------------------------------------------- + * + * dbMoveProp -- + * + * Callback function for ??. Finds properties that represent + * internal geometry (FIXED_BBOX and MASKHINTS_*) and modifies the values + * by the X, Y values passed as a pointer to a Point structure in ClientData. + * + * ---------------------------------------------------------------------------- + */ + +int dbMoveProp(name, value, cps) + char *name; + char *value; + CellPropStruct *cps; +{ + int origx, origy; + char *newvalue; + Rect r; + + if (!strcmp(name, "FIXED_BBOX") || !strncmp(name, "MASKHINTS_", 10)) + { + if (sscanf(value, "%d %d %d %d", &r.r_xbot, &r.r_ybot, + &r.r_xtop, &r.r_ytop) == 4) + { + origx = cps->cps_point.p_x; + origy = cps->cps_point.p_y; + + DBMovePoint(&r.r_ll, origx, origy); + DBMovePoint(&r.r_ur, origx, origy); + + newvalue = (char *)mallocMagic(40); + sprintf(newvalue, "%d %d %d %d", r.r_xbot, r.r_ybot, + r.r_xtop, r.r_ytop); + DBPropPut(cps->cps_def, name, newvalue); + } + } + return 0; /* Keep enumerating through properties */ +} + + /* * ---------------------------------------------------------------------------- * @@ -1799,6 +1951,7 @@ dbScaleCell(cellDef, scalen, scaled) LinkedCellUse *luhead, *lu; Plane *newplane; BPlane *cellPlane, *cellPlaneOrig; + CellPropStruct cps; /* DBCellEnum() attempts to read unavailable celldefs. We don't */ /* want to do that here, so check CDAVAILABLE flag first. */ @@ -1936,6 +2089,18 @@ donecell: } } } + + /* Check all properties for ones with keys beginning with "MASKHINTS_" + * or the key "FIXED_BBOX", and scale them by the same amount as all + * the geometry. + */ + + + cps.cps_point.p_x = scalen; + cps.cps_point.p_y = scaled; + cps.cps_def = cellDef; + DBPropEnum(cellDef, dbScaleProp, &cps); + return 0; } @@ -2023,6 +2188,7 @@ DBMoveCell(cellDef, origx, origy) LinkedCellUse *luhead, *lu; Plane *newplane; BPlane *cellPlane, *cellPlaneOrig; + CellPropStruct cps; /* Unlike dbScaleCell(), this routine is only run on valid edit defs */ @@ -2120,31 +2286,15 @@ donecell: DBMovePoint(&cellDef->cd_extended.r_ll, origx, origy); DBMovePoint(&cellDef->cd_extended.r_ur, origx, origy); - /* If the cell is an abstract view with a fixed bounding box, then */ - /* adjust the bounding box property to match the new scale. */ + /* Check all properties for ones with keys beginning with "MASKHINTS_" + * or the key "FIXED_BBOX", and move them by the same amount as all + * the geometry. + */ - if ((cellDef->cd_flags & CDFIXEDBBOX) != 0) - { - Rect r; - bool found; - char *propval; - - propval = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found); - if (found) - { - if (sscanf(propval, "%d %d %d %d", &r.r_xbot, &r.r_ybot, - &r.r_xtop, &r.r_ytop) == 4) - { - DBMovePoint(&r.r_ll, origx, origy); - DBMovePoint(&r.r_ur, origx, origy); - - propval = (char *)mallocMagic(40); - sprintf(propval, "%d %d %d %d", r.r_xbot, r.r_ybot, - r.r_xtop, r.r_ytop); - DBPropPut(cellDef, "FIXED_BBOX", propval); - } - } - } + cps.cps_point.p_x = origx; + cps.cps_point.p_y = origy; + cps.cps_def = cellDef; + DBPropEnum(cellDef, dbMoveProp, &cps); return 0; } diff --git a/database/DBexpand.c b/database/DBexpand.c index 63d0f7d1..f93aaa67 100644 --- a/database/DBexpand.c +++ b/database/DBexpand.c @@ -275,7 +275,8 @@ dbUnexpandFunc(scx, arg) * the given rectangle. * * Results: - * None. + * If "halt_on_error" is TRUE, then return 1 if any subcell could not + * be read. Otherwise, return 0. * * Side effects: * May make new cells known to the database. Sets the CDAVAILABLE @@ -284,10 +285,11 @@ dbUnexpandFunc(scx, arg) * ---------------------------------------------------------------------------- */ -void -DBCellReadArea(rootUse, rootRect) +int +DBCellReadArea(rootUse, rootRect, halt_on_error) CellUse *rootUse; /* Root cell use from which search begins */ Rect *rootRect; /* Area to be read, in root coordinates */ + bool halt_on_error; /* If TRUE, failure to find a cell causes a halt */ { int dbReadAreaFunc(); SearchContext scontext; @@ -295,30 +297,39 @@ DBCellReadArea(rootUse, rootRect) scontext.scx_use = rootUse; scontext.scx_trans = GeoIdentityTransform; scontext.scx_area = *rootRect; - (void) dbReadAreaFunc(&scontext); + if (dbReadAreaFunc(&scontext, halt_on_error) == 1) + return 1; + + return 0; } int -dbReadAreaFunc(scx) +dbReadAreaFunc(scx, halt_on_error) 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 TURE, failure to find a cell causes a halt */ { CellDef *def = scx->scx_use->cu_def; if ((def->cd_flags & CDAVAILABLE) == 0) { bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; - (void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL); + if (DBCellRead(def, (char *)NULL, TRUE, dereference, NULL) == FALSE) + if (halt_on_error) + return 1; + /* Note: we don't have to invoke DBReComputeBbox here because * if the bbox changed then there was a timestamp mismatch and * the timestamp code will take care of the bounding box later. */ } - (void) DBCellSrArea(scx, dbReadAreaFunc, (ClientData) NULL); + if (DBCellSrArea(scx, dbReadAreaFunc, (ClientData)halt_on_error)) + if (halt_on_error) + 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 @@ -328,5 +339,6 @@ dbReadAreaFunc(scx) if (GEO_SURROUND(&scx->scx_area, &scx->scx_use->cu_def->cd_bbox)) return 2; + return 0; } diff --git a/database/DBio.c b/database/DBio.c index bac43ab1..56874065 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -45,6 +45,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #endif +#include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" @@ -898,7 +899,7 @@ DBReadBackup(name) * * DBCellRead -- * - * This is the wrapper for DBCellReadDef. The routine has been divided into + * This is the wrapper for dbCellReadDef. The routine has been divided into * parts so that a single backup file can be made and recovered, and in * preparation for allowing certain cell definitions to be in-lined into the * output file (such as polygonXXXXX cells generated by the gds read-in). @@ -989,6 +990,11 @@ DBCellRead(cellDef, name, ignoreTech, dereference, errptr) * CDAVAILABLE, with the CDNOTFOUND bit clear, if we * were successful. * + * Notes: + * Global variable DBVerbose determines whether or not error + * messages are generated by this routine. This can be controlled + * by "load -quiet". + * * ---------------------------------------------------------------------------- */ @@ -1061,15 +1067,20 @@ dbReadOpen(cellDef, name, setFileName, errptr) /* somewhere else in the search paths. */ if (pptr != NULL) *pptr = '.'; - TxError("Warning: Parent cell lists instance of \"%s\" at bad file " - "path %s.\n", cellDef->cd_name, cellDef->cd_file); + if (DBVerbose) + TxError("Warning: Parent cell lists instance of \"%s\" at " + "bad file path %s.\n", + cellDef->cd_name, cellDef->cd_file); /* Write the new path to cd_file or else magic will */ /* generate another error later. */ StrDup(&cellDef->cd_file, filename); - TxError("The cell exists in the search paths at %s.\n", filename); - TxError("The discovered version will be used.\n"); + if (DBVerbose) + { + TxError("The cell exists in the search paths at %s.\n", filename); + TxError("The discovered version will be used.\n"); + } } } @@ -1090,17 +1101,24 @@ dbReadOpen(cellDef, name, setFileName, errptr) return ((FILE *) NULL); if (name != (char *) NULL) - TxError("File %s%s couldn't be read\n", name, DBSuffix); + { + if (DBVerbose) + TxError("File %s%s couldn't be read\n", name, DBSuffix); + } else if (cellDef->cd_file != (char *) NULL) - TxError("File %s couldn't be read\n", cellDef->cd_file); + { + if (DBVerbose) + TxError("File %s couldn't be read\n", cellDef->cd_file); + } else { - TxError("Cell %s couldn't be read\n", cellDef->cd_name); + if (DBVerbose) + TxError("Cell %s couldn't be read\n", cellDef->cd_name); realname = (char *) mallocMagic((unsigned) (strlen(cellDef->cd_name) + strlen(DBSuffix) + 1)); (void) sprintf(realname, "%s%s", cellDef->cd_name, DBSuffix); StrDup(&cellDef->cd_file, realname); } - if (errptr) TxError("%s\n", strerror(*errptr)); + if (errptr && DBVerbose) TxError("%s\n", strerror(*errptr)); cellDef->cd_flags |= CDNOTFOUND; return ((FILE *) NULL); @@ -1373,7 +1391,7 @@ badTransform: else if (DBIsAncestor(subCellDef, cellDef)) { /* - * Watchout for attempts to create circular structures. + * Watch out for attempts to create circular structures. * If this happens, disregard the subcell. */ TxPrintf("Subcells are used circularly!\n"); @@ -1382,6 +1400,33 @@ badTransform: goto nextLine; } +#ifdef MAGIC_WRAPPER + /* If path starts with '$' then check for a possible Tcl variable */ + /* replacement. */ + + if (*pathptr == '$') + { + char *varstart, *varend, savechar, *tvar; + + varstart = pathptr + 1; + if (*varstart == '{') varstart++; + varend = varstart + 1; + while (*varend != '\0' && *varend != '}' && *varend != '/' + && *varend != '\n' && *varend != ' ') varend++; + savechar = *varend; + *varend = '\0'; + + tvar = (char *)Tcl_GetVar(magicinterp, varstart, TCL_GLOBAL_ONLY); + *varend = savechar; + if (savechar == '}') varend++; + if (tvar) + { + memmove(pathptr + strlen(tvar), varend, strlen(varend) + 1); + memmove(pathptr, tvar, strlen(tvar)); + } + } +#endif + /* Relative path handling: If path does not have a leading "/" */ /* or "~" and cellDef->cd_file has path components, then the path */ /* should be interpreted relative to the path of the parent cell. */ @@ -2902,7 +2947,8 @@ DBCellWrite(cellDef, fileName) { bool dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; /* Re-aquire the lock on the new file by opening it. */ - DBCellRead(cellDef, NULL, TRUE, dereference, NULL); + if (DBCellRead(cellDef, NULL, TRUE, dereference, NULL) == FALSE) + return FALSE; } #endif @@ -3146,6 +3192,7 @@ dbWriteCellFunc(cellUse, cdarg) struct writeArg *arg = (struct writeArg *) cdarg; Transform *t; Rect *b; + bool subbed = FALSE; char cstring[256], *pathend, *pathstart, *parent; t = &(cellUse->cu_transform); @@ -3197,25 +3244,90 @@ dbWriteCellFunc(cellUse, cdarg) } else { - /* If path starts with home path, then replace with "~" */ - /* to make IP semi-portable between home directories */ - /* with the same file structure. */ +#ifdef MAGIC_WRAPPER + char *tvar; - char *homedir = getenv("HOME"); + /* Check for the leading component of the file path being equal to */ + /* one of several common variable names for the PDK location, and */ + /* if there is a match, then substitute the variable name for the */ + /* matching leading path component. */ - if (!strncmp(cellUse->cu_def->cd_file, homedir, strlen(homedir)) - && (*(cellUse->cu_def->cd_file + strlen(homedir)) == '/')) + if (subbed == FALSE) { - sprintf(cstring, "use %s %c%s ~%s\n", cellUse->cu_def->cd_name, + tvar = (char *)Tcl_GetVar(magicinterp, "PDK_PATH", TCL_GLOBAL_ONLY); + if (tvar) + if (!strncmp(pathstart, tvar, strlen(tvar))) + { + sprintf(cstring, "use %s %c%s $PDK_PATH%s\n", + cellUse->cu_def->cd_name, + (cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ', + cellUse->cu_id, pathstart + strlen(tvar)); + subbed = TRUE; + } + } + if (subbed == FALSE) + { + tvar = (char *)Tcl_GetVar(magicinterp, "PDKPATH", TCL_GLOBAL_ONLY); + if (tvar) + if (!strncmp(pathstart, tvar, strlen(tvar))) + { + sprintf(cstring, "use %s %c%s $PDKPATH%s\n", + cellUse->cu_def->cd_name, + (cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ', + cellUse->cu_id, pathstart + strlen(tvar)); + subbed = TRUE; + } + } + if (subbed == FALSE) + { + tvar = (char *)Tcl_GetVar(magicinterp, "PDK_ROOT", TCL_GLOBAL_ONLY); + if (tvar) + if (!strncmp(pathstart, tvar, strlen(tvar))) + { + sprintf(cstring, "use %s %c%s $PDK_ROOT%s\n", + cellUse->cu_def->cd_name, + (cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ', + cellUse->cu_id, pathstart + strlen(tvar)); + subbed = TRUE; + } + } + if (subbed == FALSE) + { + tvar = (char *)Tcl_GetVar(magicinterp, "PDKROOT", TCL_GLOBAL_ONLY); + if (tvar) + if (!strncmp(pathstart, tvar, strlen(tvar))) + { + sprintf(cstring, "use %s %c%s $PDKROOT%s\n", + cellUse->cu_def->cd_name, + (cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ', + cellUse->cu_id, pathstart + strlen(tvar)); + subbed = TRUE; + } + } +#endif + + if (subbed == FALSE) + { + /* If path starts with home path, then replace with "~" */ + /* to make IP semi-portable between home directories */ + /* with the same file structure. */ + + char *homedir = getenv("HOME"); + + if (!strncmp(cellUse->cu_def->cd_file, homedir, strlen(homedir)) + && (*(cellUse->cu_def->cd_file + strlen(homedir)) == '/')) + { + sprintf(cstring, "use %s %c%s ~%s\n", cellUse->cu_def->cd_name, (cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ', cellUse->cu_id, cellUse->cu_def->cd_file + strlen(homedir)); - } - else - { - sprintf(cstring, "use %s %c%s %s\n", cellUse->cu_def->cd_name, + } + else + { + sprintf(cstring, "use %s %c%s %s\n", cellUse->cu_def->cd_name, (cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ', cellUse->cu_id, pathstart); + } } } FPRINTR(arg->wa_file, cstring); diff --git a/database/DBpaint.c b/database/DBpaint.c index de4333f9..bf91457d 100644 --- a/database/DBpaint.c +++ b/database/DBpaint.c @@ -215,7 +215,7 @@ dbJoinUndo(tile, splitx, undo) * 'undo' can be NULL. * * Results: - * None. + * Always return 0. * * Side effects: * Modifies the database plane that contains the given tile. @@ -236,7 +236,7 @@ dbJoinUndo(tile, splitx, undo) * ---------------------------------------------------------------------------- */ -void +int DBPaintPlane0(plane, area, resultTbl, undo, method) Plane *plane; /* Plane whose paint is to be modified */ Rect *area; /* Area to be changed */ @@ -262,7 +262,7 @@ DBPaintPlane0(plane, area, resultTbl, undo, method) bool haschanged; if (area->r_xtop <= area->r_xbot || area->r_ytop <= area->r_ybot) - return; + return 0; /* * The following is a modified version of the area enumeration @@ -697,6 +697,7 @@ enum2: done2: plane->pl_hint = tile; + return 0; } /* @@ -1442,7 +1443,7 @@ typedef struct * paint quadrangular (clipped triangle) areas. * * Results: - * None. + * 0 on success, 1 on error splitting a non-manhattan tile * * Side Effects: * Plane is painted with a diagonal. The plane may be hacked up @@ -1452,7 +1453,7 @@ typedef struct * ---------------------------------------------------------------------------- */ -void +int DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) Plane *plane; /* Plane whose paint is to be modified */ TileType exacttype; /* diagonal info for tile to be changed */ @@ -1478,6 +1479,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) int xc, yc, width, height; dlong xref, yref; /* xref, yref can easily exceed 32 bits */ int resstate; + int result = 0; if (exacttype & TT_DIAGONAL) { @@ -1532,7 +1534,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) if (resultTbl[oldType] == oldType) { freeMagic((char *) lr); - return; + return 0; } } @@ -1544,7 +1546,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) if (newType == oldType) { freeMagic((char *) lr); - return; + return 0; } /* Watch for the worst-case scenario of attempting to */ @@ -1560,9 +1562,9 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) { if ((width == 1) || (height == 1)) { - DBPaintPlane(plane, &(lr->r_r), resultTbl, undo); + result = DBPaintPlane(plane, &(lr->r_r), resultTbl, undo); freeMagic((char *) lr); - return; + return 1; /* Flag the error by returning 1 */ } /* lr->r_r is drawn & quartered */ @@ -1605,7 +1607,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) if (newType & TT_DIAGONAL) { - DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl, + result = DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl, (PaintUndoInfo *)NULL); tile = plane->pl_hint; GOTOPOINT(tile, &(lr->r_r.r_ll)); @@ -1620,14 +1622,14 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method) { PaintResultType tempTbl; tempTbl = newType; - DBPaintPlane0(plane, &(lr->r_r), &tempTbl, undo, method); + result = DBPaintPlane0(plane, &(lr->r_r), &tempTbl, + undo, method); } else - DBPaintPlane(plane, &(lr->r_r), resultTbl, undo); + result = DBPaintPlane(plane, &(lr->r_r), resultTbl, undo); freeMagic((char *) lr); - /* goto nmmerge; */ - return; + return result; } } @@ -1755,11 +1757,12 @@ paintrect: if (resstate == RES_DIAG) { /* Recursive call to self on sub-area */ - DBNMPaintPlane0(plane, exacttype, &(lr->r_r), resultTbl, undo, method); + result |= DBNMPaintPlane0(plane, exacttype, &(lr->r_r), resultTbl, + undo, method); } else if ((resstate == RES_LEFT && !dinfo.side) || (resstate == RES_RIGHT && dinfo.side)) { - DBPaintPlane(plane, &(lr->r_r), resultTbl, undo); + result |= DBPaintPlane(plane, &(lr->r_r), resultTbl, undo); } /* else: Rectangle does not contain type and should be ignored. */ nextrect: @@ -1774,8 +1777,10 @@ nextrect: } } else - DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ? + result = DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ? method : PAINT_NORMAL); + + return result; } /* @@ -2547,7 +2552,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client) * ---------------------------------------------------------------------------- */ -void +int DBPaintPlaneVert(plane, area, resultTbl, undo) Plane *plane; /* Plane whose paint is to be modified */ Rect *area; /* Area to be changed */ diff --git a/database/DBprop.c b/database/DBprop.c index 7a72d3e7..2c267f52 100644 --- a/database/DBprop.c +++ b/database/DBprop.c @@ -34,7 +34,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ /* ---------------------------------------------------------------------------- * - *DBPropPut -- + * DBPropPut -- * * Put a property onto a celldef. * @@ -57,8 +57,15 @@ DBPropPut(cellDef, name, value) HashEntry *entry; char *oldvalue; - /* Honor the NOEDIT flag */ - if (cellDef->cd_flags & CDNOEDIT) return; + /* Honor the NOEDIT flag. Note that the caller always assumes that */ + /* the value would be saved in the hash table, so if it is not */ + /* being used, then it must be freed here. */ + + if (cellDef->cd_flags & CDNOEDIT) + { + freeMagic((char *)value); + return; + } if (cellDef->cd_props == (ClientData) NULL) { diff --git a/database/DBtech.c b/database/DBtech.c index 430ccf93..19ccded6 100644 --- a/database/DBtech.c +++ b/database/DBtech.c @@ -204,9 +204,57 @@ DBTechSetVersion(sectionName, argc, argv) } return TRUE; } + if (strcmp(argv[0], "requires") == 0) + { + /* Version requirement check. If the techfile has "requires" followed + * by a magic version number in the form [magic-].., + * then the version of magic is checked against this, and the tech + * loading will fail if there is a version incompatibility. + */ + + int major, minor, rev; + int rmajor, rminor, rrev; + bool goodversion = FALSE; + char *vstring; + + vstring = argv[1]; + while ((*vstring != '\0') && !isdigit(*vstring)) vstring++; + + major = minor = rev = 0; + rmajor = rminor = rrev = 0; + + if (sscanf(vstring, "%d.%d.%d", &rmajor, &rminor, &rrev) == 0) + { + TechError("Badly formed magic version string, should be major.minor.rev\n"); + return FALSE; + } + sscanf(MagicVersion, "%d.%d", &major, &minor); + sscanf(MagicRevision, "%d", &rev); + if (major > rmajor) + goodversion = TRUE; + else if (major == rmajor) + { + if (minor > rminor) + goodversion = TRUE; + else if (minor == rminor) + { + if (rev >= rrev) + goodversion = TRUE; + } + } + if (goodversion == FALSE) + { + TechError("Error: Magic version %d.%d.%d is required by this " + "techfile, but this version of magic is %d.%d.%d.\n", + rmajor, rminor, rrev, major, minor, rev); + return FALSE; + } + return TRUE; + } usage: - TechError("Badly formed version line\nUsage: {version text}|{description text}\n"); + TechError("Badly formed version line\n" + "Usage: {version text}|{description text}|{requires text}\n"); return FALSE; } diff --git a/database/database.h.in b/database/database.h.in index 9069cc8d..18ed836d 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -265,42 +265,46 @@ typedef struct label * Label flags bit fields */ -#define PORT_NUM_MASK 0x0fff /* Mask of port number (up to 4096) */ +#define PORT_NUM_MASK 0x003fff /* Mask of port number (up to 16384) */ -#define PORT_DIR_MASK 0xf000 /* Mask of all port directions */ -#define PORT_DIR_NORTH 0x1000 /* Port allows connection to north */ -#define PORT_DIR_EAST 0x2000 /* Port allows connection to east */ -#define PORT_DIR_SOUTH 0x4000 /* Port allows connection to south */ -#define PORT_DIR_WEST 0x8000 /* Port allows connection to west */ +#define PORT_DIR_MASK 0x03c000 /* Mask of all port directions */ +#define PORT_DIR_NORTH 0x004000 /* Port allows connection to north */ +#define PORT_DIR_EAST 0x008000 /* Port allows connection to east */ +#define PORT_DIR_SOUTH 0x010000 /* Port allows connection to south */ +#define PORT_DIR_WEST 0x020000 /* Port allows connection to west */ -#define PORT_CLASS_MASK 0x70000 /* Mask of all port classes */ -#define PORT_CLASS_DEFAULT 0x00000 /* Port takes default class */ -#define PORT_CLASS_INPUT 0x10000 /* Port is a digital input */ -#define PORT_CLASS_OUTPUT 0x20000 /* Port is a digital output */ -#define PORT_CLASS_TRISTATE 0x30000 /* Port is a tri-state output */ -#define PORT_CLASS_BIDIRECTIONAL 0x40000 /* Port is analog or digital */ - /* bidirectional */ -#define PORT_CLASS_FEEDTHROUGH 0x50000 /* Port touches no active */ - /* devices */ +#define PORT_CLASS_MASK 0x1c0000 /* Mask of all port classes */ +#define PORT_CLASS_DEFAULT 0x000000 /* Port takes default class */ +#define PORT_CLASS_INPUT 0x040000 /* Port is a digital input */ +#define PORT_CLASS_OUTPUT 0x080000 /* Port is a digital output */ +#define PORT_CLASS_TRISTATE 0x0c0000 /* Port is a tri-state output */ +#define PORT_CLASS_BIDIRECTIONAL 0x100000 /* Port is analog or digital */ + /* bidirectional */ +#define PORT_CLASS_FEEDTHROUGH 0x140000 /* Port touches no active */ + /* devices */ -#define PORT_USE_MASK 0x0700000 /* Mask of all port uses */ -#define PORT_USE_DEFAULT 0x0000000 /* Port takes default use */ -#define PORT_USE_SIGNAL 0x0100000 /* Port is a digital signal */ -#define PORT_USE_ANALOG 0x0200000 /* Port is an analog signal */ -#define PORT_USE_POWER 0x0300000 /* Port is a power rail */ -#define PORT_USE_GROUND 0x0400000 /* Port is a ground rail */ -#define PORT_USE_CLOCK 0x0500000 /* Port is a digital clock */ - /* signal */ -#define PORT_SHAPE_MASK 0x1800000 /* Mask of all port shapes */ -#define PORT_SHAPE_DEFAULT 0x0000000 /* Port takes default shape */ -#define PORT_SHAPE_ABUT 0x0800000 /* Port is an abutment shape */ -#define PORT_SHAPE_RING 0x1000000 /* Port is a ring shape */ -#define PORT_SHAPE_THRU 0x1800000 /* Port is a feedthrough shape */ -#define PORT_VISITED 0x2000000 /* Bit for checking if a port */ +#define PORT_USE_MASK 0x03c00000 /* Mask of all port uses */ +#define PORT_USE_DEFAULT 0x00000000 /* Port takes default use */ +#define PORT_USE_SIGNAL 0x00400000 /* Port is a digital signal */ +#define PORT_USE_ANALOG 0x00800000 /* Port is an analog signal */ +#define PORT_USE_POWER 0x00c00000 /* Port is a power rail */ +#define PORT_USE_GROUND 0x01000000 /* Port is a ground rail */ +#define PORT_USE_CLOCK 0x01400000 /* Port is a digital clock */ +#define PORT_USE_RESET 0x01800000 /* Port is a digital reset */ +#define PORT_USE_SCAN 0x01c00000 /* Port is a digital scan */ +#define PORT_USE_TIEOFF 0x02000000 /* Port is a tie-off */ + +#define PORT_SHAPE_MASK 0x0c000000 /* Mask of all port shapes */ +#define PORT_SHAPE_DEFAULT 0x00000000 /* Port takes default shape */ +#define PORT_SHAPE_ABUT 0x04000000 /* Port is an abutment shape */ +#define PORT_SHAPE_RING 0x08000000 /* Port is a ring shape */ +#define PORT_SHAPE_THRU 0x0c000000 /* Port is a feedthrough shape */ + +#define PORT_VISITED 0x10000000 /* Bit for checking if a port */ /* has been previously visited. */ -#define LABEL_STICKY 0x4000000 /* Label does not change layers */ -#define LABEL_GENERATE 0x8000000 /* Auto-generated label */ +#define LABEL_STICKY 0x20000000 /* Label does not change layers */ +#define LABEL_GENERATE 0x40000000 /* Auto-generated label */ /* * Macros for dealing with label rectangles. @@ -652,7 +656,7 @@ typedef struct treeFilter #define TF_LABEL_ATTACH_CORNER 0x3C /* Mask of the four types above */ /* To do: Make the tpath entries dynamically allocated */ -#define FLATTERMSIZE 1024 /* Used for generating flattened labels */ +#define FLATTERMSIZE 4096 /* Used for generating flattened labels */ /* -------------- Undo information passed to DBPaintPlane ------------- */ @@ -692,13 +696,13 @@ typedef struct extern void DBPaint(); extern void DBErase(); extern int DBSrPaintArea(); -extern void DBPaintPlane0(); -extern void DBPaintPlaneActive(); -extern void DBPaintPlaneWrapper(); -extern void DBPaintPlaneMark(); -extern void DBPaintPlaneXor(); -extern void DBPaintPlaneByProc(); -extern void DBPaintPlaneMergeOnce(); +extern int DBPaintPlane0(); +extern int DBPaintPlaneActive(); +extern int DBPaintPlaneWrapper(); +extern int DBPaintPlaneMark(); +extern int DBPaintPlaneXor(); +extern int DBPaintPlaneByProc(); +extern int DBPaintPlaneMergeOnce(); extern void DBPaintMask(); extern void DBEraseMask(); extern void DBClearPaintPlane(); @@ -708,7 +712,7 @@ extern void DBUnlockContact(); #define DBPaintPlane(a, b, c, d) DBPaintPlane0(a, b, c, d, PAINT_NORMAL) #define DBMergeNMTiles(a, b, c) DBMergeNMTiles0(a, b, c, FALSE) -extern void DBNMPaintPlane0(); +extern int DBNMPaintPlane0(); #define DBNMPaintPlane(a, b, c, d, e) DBNMPaintPlane0(a, b, c, d, e, PAINT_NORMAL) /* I/O */ @@ -716,7 +720,7 @@ extern bool DBCellRead(); extern bool DBTestOpen(); extern char *DBGetTech(); extern bool DBCellWrite(); -extern void DBCellReadArea(); +extern int DBCellReadArea(); extern void DBFileRecovery(); extern bool DBWriteBackup(); extern bool DBReadBackup(); @@ -812,6 +816,7 @@ extern char *DBPrintUseId(); /* Massive copying */ extern void DBCellCopyPaint(); extern void DBCellCopyAllPaint(); +extern void DBCellCheckCopyAllPaint(); extern void DBCellCopyLabels(); extern void DBCellCopyAllLabels(); extern void DBCellCopyCells(); @@ -841,8 +846,8 @@ extern void DBEnumerateTypes(); extern Plane *DBNewPlane(); extern PaintResultType (*DBNewPaintTable())[TT_MAXTYPES][TT_MAXTYPES]; -typedef void (*VoidProc)(); -VoidProc DBNewPaintPlane(); +typedef int (*IntProc)(); +IntProc DBNewPaintPlane(); /* Diagnostic */ extern void DBTechPrintTypes(); diff --git a/dbwind/DBWcommands.c b/dbwind/DBWcommands.c index 9b1d423d..1392f5e4 100644 --- a/dbwind/DBWcommands.c +++ b/dbwind/DBWcommands.c @@ -49,7 +49,7 @@ extern void CmdGetcell(), CmdGrid(), CmdIdentify(); extern void CmdLabel(), CmdLoad(); extern void CmdMove(), CmdNetlist(), CmdOrient(), CmdPaint(), CmdPath(); extern void CmdPlow(), CmdPolygon(), CmdPort(), CmdProperty(); -extern void CmdSave(), CmdScaleGrid(), CmdSee(); +extern void CmdRandom(), CmdSave(), CmdScaleGrid(), CmdSee(); extern void CmdSelect(), CmdSetLabel(), CmdSideways(); extern void CmdShell(), CmdSnap(); extern void CmdStretch(), CmdStraighten(); @@ -407,6 +407,9 @@ DBWInitCommands() WindAddCommand(DBWclientID, "rotate [+/-][deg] rotate selection and box (counter)clockwise", CmdClockwise, FALSE); /* "rotate" is alias for "clockwise" */ + WindAddCommand(DBWclientID, + "random [seed [value]] generate random number or set random seed", + CmdRandom, FALSE); WindAddCommand(DBWclientID, "save [filename] save edit cell on disk", CmdSave, FALSE); diff --git a/drc/DRCbasic.c b/drc/DRCbasic.c index cb1b31d8..9f4aaf41 100644 --- a/drc/DRCbasic.c +++ b/drc/DRCbasic.c @@ -620,6 +620,16 @@ drcTile (tile, arg) drcCheckRectSize(tile, arg, cptr); continue; } + /* Off-grid checks apply only to edge */ + if (cptr->drcc_flags & DRC_OFFGRID) + { + errRect.r_ytop = edgeTop; + errRect.r_ybot = edgeBot; + errRect.r_xtop = errRect.r_xbot = edgeX; + arg->dCD_cptr = cptr; + drcCheckOffGrid(&errRect, arg, cptr); + continue; + } result = 0; arg->dCD_radial = 0; @@ -983,13 +993,22 @@ checkbottom: } continue; } - else if (cptr->drcc_flags & (DRC_AREA | DRC_RECTSIZE - | DRC_MAXWIDTH)) + else if (cptr->drcc_flags & (DRC_AREA | DRC_RECTSIZE | DRC_MAXWIDTH)) { /* only have to do these checks in one direction */ if (trigpending) cptr = cptr->drcc_next; continue; } + /* Off-grid checks apply only to edge */ + if (cptr->drcc_flags & DRC_OFFGRID) + { + errRect.r_xtop = edgeRight; + errRect.r_xbot = edgeLeft; + errRect.r_ytop = errRect.r_ybot = edgeY; + arg->dCD_cptr = cptr; + drcCheckOffGrid(&errRect, arg, cptr); + continue; + } result = 0; arg->dCD_radial = 0; diff --git a/drc/DRCcontin.c b/drc/DRCcontin.c index 5d9a527f..f1e18d95 100644 --- a/drc/DRCcontin.c +++ b/drc/DRCcontin.c @@ -197,12 +197,7 @@ DRCCheckThis (celldef, operation, area) * of CellDefs waiting for DRC */ - /* Ignore internal GDS cells. */ - /* Note that this rescinds the former behavior of ignoring DRC on */ - /* vendor and read-only cells. Such cells will be flattened in */ - /* interaction areas and show errors anyway, so not showing errors */ - /* in the cell is just confusing. */ - + /* Ignore internal cells. */ if (celldef->cd_flags & CDINTERNAL) return; /* Insert celldef into list of Defs waiting to be checked, unless */ diff --git a/drc/DRCextend.c b/drc/DRCextend.c index 530bc47c..c05515b3 100644 --- a/drc/DRCextend.c +++ b/drc/DRCextend.c @@ -70,6 +70,50 @@ drcCheckAngles(tile, arg, cptr) } } +/* + *------------------------------------------------------------------------- + * + * drcCheckOffGrid- checks to see that an edge is on the specified + * grid pitch. + * + * Results: none + * + * Side Effects: may cause errors to be painted. + * + *------------------------------------------------------------------------- + */ + +void +drcCheckOffGrid(edgeRect, arg, cptr) + Rect *edgeRect; + struct drcClientData *arg; + DRCCookie *cptr; +{ + Rect rect; + int gtest; + + if (cptr->drcc_dist <= 1) return; /* No error by definition */ + + rect = *edgeRect; + GeoClip(&rect, arg->dCD_clip); + + /* Expand rect to nearest pitch */ + gtest = (rect.r_xbot / cptr->drcc_dist) * cptr->drcc_dist; + if (gtest < rect.r_xbot) rect.r_xbot = gtest; + gtest = (rect.r_xtop / cptr->drcc_dist) * cptr->drcc_dist; + if (gtest > rect.r_xtop) rect.r_xtop = gtest; + gtest = (rect.r_ybot / cptr->drcc_dist) * cptr->drcc_dist; + if (gtest < rect.r_ybot) rect.r_ybot = gtest; + gtest = (rect.r_ytop / cptr->drcc_dist) * cptr->drcc_dist; + if (gtest > rect.r_ytop) rect.r_ytop = gtest; + + if (!GEO_RECTNULL(&rect)) { + (*(arg->dCD_function)) (arg->dCD_celldef, &rect, + arg->dCD_cptr, arg->dCD_clientData); + (*(arg->dCD_errors))++; + } +} + /* *------------------------------------------------------------------------- * @@ -144,10 +188,6 @@ drcCheckArea(starttile,arg,cptr) if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); - /*** - DBWAreaChanged(arg->dCD_celldef,&rect, DBW_ALLWINDOWS, - &DBAllButSpaceBits); - ***/ (*(arg->dCD_errors))++; } } diff --git a/drc/DRCmain.c b/drc/DRCmain.c index b57093df..6fa55e7c 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -664,7 +664,11 @@ DRCCheck(use, area) SearchContext scx; extern int drcCheckFunc(); /* Forward reference. */ - DBCellReadArea(use, area); + if (DBCellReadArea(use, area, TRUE)) + { + TxError("Failure to read in entire subtree of cell.\n"); + return; + } scx.scx_use = use; scx.scx_x = use->cu_xlo; @@ -702,8 +706,8 @@ drcCheckFunc(scx, cdarg) DRCCheckThis(def, TT_CHECKPAINT, (Rect *) NULL); - /* New behavior: Don't search children, instead propagate errors up. */ - /* (void) DBCellSrArea(scx, drcCheckFunc, (ClientData) NULL); */ + /* Search children */ + (void) DBCellSrArea(scx, drcCheckFunc, (ClientData) NULL); /* 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 fa461378..053d77e6 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -74,7 +74,22 @@ static DRCCookie drcInSubCookie = { (DRCCookie *) NULL }; +/* The following DRC cookie is used when flattening non-Manhattan + * shapes results in a non-integer coordinate. Because the non- + * integer coordinate cannot be represented in magic, the position + * is flagged as a DRC error. + */ + +static DRCCookie drcOffGridCookie = { + 0, 0, 0, 0, + { 0 }, { 0 }, + 0, 0, 0, + DRC_OFFGRID_TAG, + (DRCCookie *) NULL +}; + extern int DRCErrorType; +extern CellDef *DRCErrorDef; /* * ---------------------------------------------------------------------------- @@ -604,6 +619,37 @@ drcExactOverlapTile(tile, cxp) return 0; } +/* + * ---------------------------------------------------------------------------- + * + * DRCOffGridError --- + * + * Function to call when a call to DBCellCheckCopyAllPaint() flags an error + * indicating that a subcell overlap of non-Manhattan geometry resolves to + * an off-grid intersection point. Note that this is different from the + * DRC off-grid check, which checks for geometry that does not match the + * manufacturing grid pitch. This checks for the case of geometry that + * is finer than the underlying database grid, which can only happen for + * two non-Manhattan shapes interacting between two different cells, and + * can only be caught during the process of flattening the cell contents. + * + * Results: + * None. + * + * Side effects: + * Creates a DRC error or prints the DRC error message, depending on + * the value of drcSubFunc. + * + * ---------------------------------------------------------------------------- + */ + +void +DRCOffGridError(rect) + Rect *rect; /* Area of error */ +{ + (*drcSubFunc)(DRCErrorDef, rect, &drcOffGridCookie, drcSubClientData); +} + /* * ---------------------------------------------------------------------------- * @@ -809,7 +855,8 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); - (void) DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, DRCuse); + (void) DBCellCheckCopyAllPaint(&scx, &DBAllButSpaceBits, 0, + DRCuse, func); (void) DBNewPaintTable(savedPaintTable); (void) DBNewPaintPlane(savedPaintPlane); diff --git a/drc/DRCtech.c b/drc/DRCtech.c index 6f477424..9aa1792b 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -73,7 +73,7 @@ static int DRCtag = 0; int drcWidth(), drcSpacing(), drcEdge(), drcNoOverlap(); int drcExactOverlap(), drcExtend(); int drcSurround(), drcRectOnly(), drcOverhang(); -int drcStepSize(), drcOption(); +int drcStepSize(), drcOption(), drcOffGrid(); int drcMaxwidth(), drcArea(), drcRectangle(), drcAngles(); int drcCifSetStyle(), drcCifWidth(), drcCifSpacing(); int drcCifMaxwidth(), drcCifArea(); @@ -587,6 +587,11 @@ DRCTechStyleInit() /* (see DRCsubcell.c). */ drcWhyCreate("See error definition in the subcell"); + /* Fifth DRC entry is associated with the statically-allocated */ + /* drcOffGridCookie and has a tag of DRC_OFFGRID_TAG = 5 */ + /* (see DRCsubcell.c). */ + drcWhyCreate("This position does not align with the manufacturing grid"); + DRCTechHalo = 0; /* Put a dummy rule at the beginning of the rules table for each entry */ @@ -922,7 +927,8 @@ drcCifAssign(cookie, dist, next, mask, corner, tag, cdist, flags, planeto, plane int dist, cdist; TileTypeBitMask *mask, *corner; int tag; - int flags, planeto, planefrom; + unsigned short flags; + int planeto, planefrom; { (cookie)->drcc_dist = dist; (cookie)->drcc_next = next; @@ -946,7 +952,8 @@ drcAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefro int dist, cdist; TileTypeBitMask *mask, *corner; int why; - int flags, planeto, planefrom; + unsigned short flags; + int planeto, planefrom; { /* Diagnostic */ if (planeto >= DBNumPlanes) @@ -1040,6 +1047,8 @@ DRCTechAddRule(sectionName, argc, argv) "layers1 width layers2 separation adjacency why", "area", 5, 5, drcArea, "layers area horizon why", + "off_grid", 4, 4, drcOffGrid, + "layers pitch why", "maxwidth", 4, 5, drcMaxwidth, "layers maxwidth bends why", "cifstyle", 2, 2, drcCifSetStyle, @@ -1434,6 +1443,85 @@ drcArea(argc, argv) return (horizon); } +/* + * ---------------------------------------------------------------------------- + * + * drcOffGrid -- + * + * Process an off-grid rule. + * This is of the form: + * + * off_grid layers pitch why + * + * e.g, + * + * off_grid m1 5 "metal shapes must be on %d grid" + * + * "pitch" is the grid pitch that shapes must be aligned to. + * + * Results: + * Returns pitch (the halo for detecting off-grid errors). + * + * Side effects: + * Updates the DRC technology variables. + * + * ---------------------------------------------------------------------------- + */ + +int +drcOffGrid(argc, argv) + int argc; + char *argv[]; +{ + char *layers = argv[1]; + int pitch = atoi(argv[2]); + int why = drcWhyCreate(argv[3]); + TileTypeBitMask set, setC; + DRCCookie *dp, *dpnew; + TileType i, j; + PlaneMask pset; + int plane; + + DBTechNoisyNameMask(layers, &set); + TTMaskCom2(&setC, &set); + + for (i = 0; i < DBNumTypes; i++) + { + for (j = 0; j < DBNumTypes; j++) + { + if (i == j) continue; + /* + * Must have types in 'set' for at least 'distance' + * to the right of any edge between a type in '~set' + * and a type in 'set'. + */ + if (pset = (DBTypesOnSamePlane(i, j))) + { + if (TTMaskHasType(&setC, i) && TTMaskHasType(&set, j)) + { + plane = LowestMaskBit(pset); + + /* find bucket preceding the new one we wish to insert */ + dp = drcFindBucket(i, j, pitch); + dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie)); + drcAssign(dpnew, pitch, dp->drcc_next, &set, &set, why, + 0, DRC_OFFGRID|DRC_FORWARD, plane, plane); + dp->drcc_next = dpnew; + + /* opposite edge also needs to be checked */ + dp = drcFindBucket(j, i, pitch); + dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie)); + drcAssign(dpnew, pitch, dp->drcc_next, &set, &set, why, + 0, DRC_OFFGRID|DRC_REVERSE, plane, plane); + dp->drcc_next = dpnew; + + } + } + } + } + return (pitch); +} + /* * ---------------------------------------------------------------------------- * diff --git a/drc/drc.h b/drc/drc.h index d1638931..41547c00 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -48,6 +48,7 @@ typedef struct drccookie #define DRC_OVERLAP_TAG 2 #define DRC_SUBCELL_OVERLAP_TAG 3 #define DRC_IN_SUBCELL_TAG 4 +#define DRC_OFFGRID_TAG 5 /* *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. */ @@ -63,20 +64,22 @@ typedef struct drccookie * edge processing. */ -#define DRC_FORWARD 0x00 -#define DRC_REVERSE 0x01 -#define DRC_BOTHCORNERS 0x02 -#define DRC_TRIGGER 0x04 -#define DRC_BENDS 0x08 -#define DRC_OUTSIDE 0x08 // Note: Shared with DRC_BENDS -#define DRC_AREA 0x10 -#define DRC_MAXWIDTH 0x20 -#define DRC_RECTSIZE 0x40 -#define DRC_ANGLES 0x80 -#define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE|DRC_ANGLES) +#define DRC_FORWARD 0x000 +#define DRC_REVERSE 0x001 +#define DRC_BOTHCORNERS 0x002 +#define DRC_TRIGGER 0x004 +#define DRC_BENDS 0x008 +#define DRC_OUTSIDE 0x010 +#define DRC_AREA 0x020 +#define DRC_OFFGRID 0x040 +#define DRC_MAXWIDTH 0x080 +#define DRC_RECTSIZE 0x100 +#define DRC_ANGLES 0x200 +#define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE\ + |DRC_ANGLES|DRC_OFFGRID) /* More flags for indicating what the rule type represents */ -#define DRC_CIFRULE 0x100 +#define DRC_CIFRULE 0x400 #define DRC_PENDING 0 #define DRC_UNPROCESSED CLIENTDEFAULT @@ -165,7 +168,7 @@ typedef struct drcstyle int DRCScaleFactorD; /* Multiply dist by this to get magic units */ int DRCTechHalo; /* largest action distance of design rules */ int DRCStepSize; /* chunk size for decomposing large areas */ - char DRCFlags; /* Option flags */ + unsigned short DRCFlags; /* Option flags */ char **DRCWhyList; /* Indexed list of "why" text strings */ int DRCWhySize; /* Length of DRCWhyList */ PaintResultType DRCPaintTable[NP][NT][NT]; @@ -271,6 +274,7 @@ extern int DRCFind(); extern void DRCCatchUp(); extern bool DRCFindInteractions(); extern int DRCBasicCheck(); +extern void DRCOffGridError(); extern void DRCPrintStyle(); extern void DRCSetStyle(); diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 3f366cec..e6ba9381 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -350,6 +350,13 @@ esOutputHierResistor(hc, dev, scale, term1, term2, has_model, l, w, dscale) /* term1=gate term2=source by the above code. */ /* extracted units are Ohms; output is in Ohms */ + if ((term1->dterm_node == NULL) || (term2->dterm_node == NULL)) + { + TxError("Error: Resistor %s missing terminal node!\n", + EFDevTypes[dev->dev_type]); + return; + } + spcdevOutNode(hc->hc_hierName, term1->dterm_node->efnode_name->efnn_hier, "res_top", esSpiceF); spcdevOutNode(hc->hc_hierName, term2->dterm_node->efnode_name->efnn_hier, @@ -405,6 +412,7 @@ subcktHierVisit(use, hierName, is_top) EFNode *snode; EFNodeName *nodeName; bool hasports = FALSE; + bool isStub; /* Avoid generating records for circuits that have no ports. */ /* These are already absorbed into the parent. All other */ @@ -431,6 +439,13 @@ subcktHierVisit(use, hierName, is_top) break; } + /* Same considerations as at line 1831 for determining if the cell */ + /* has been folded into the parent and should not be output. */ + + isStub = ((def->def_flags & DEF_ABSTRACT) && esDoBlackBox) ? TRUE : FALSE; + if ((!is_top) && (def->def_flags & DEF_NODEVICES) && (!isStub)) + return 0; + if (hasports || is_top) return subcktVisit(use, hierName, is_top); else if (def->def_flags & DEF_NODEVICES) @@ -1557,6 +1572,7 @@ devDistJunctHierVisit(hc, dev, scale) * for each connection to it. Note that this generates an arbitrary * port order for each cell. To have a specific port order, it is * necessary to generate ports for each cell. + * * ---------------------------------------------------------------------------- */ @@ -1570,6 +1586,7 @@ esMakePorts(hc, cdata) Use *use; HashEntry *he; EFNodeName *nn; + char *name, *portname, *tptr, *aptr, *locname; int j; diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index e863597b..5f1b81bc 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -1635,6 +1635,11 @@ subcktUndef(use, hierName, is_top) * subcircuit, and implicit substrate connections should not be * output. * + * NOTE: The cookie-cutter method for extraction can result in multiple + * connections to the same port if the net spans multiple extraction regions. + * Because of this, it is necessary to make sure that the same port name is + * not output twice. + * * ---------------------------------------------------------------------------- */ @@ -1646,13 +1651,16 @@ topVisit(def, doStub) EFNode *snode, *basenode; EFNodeName *sname, *nodeName; HashSearch hs; - HashEntry *he; + HashEntry *he, *hep; + HashTable portNameTable; int portorder, portmax, tchars; DevParam *plist, *pptr; char *instname; char *subcktname; char *pname; + HashInit(&portNameTable, 32, HT_STRINGKEYS); + /* SPICE subcircuit names must begin with A-Z. This will also be */ /* enforced when writing X subcircuit calls. */ subcktname = def->def_name; @@ -1698,19 +1706,25 @@ topVisit(def, doStub) if (snode->efnode_flags & EF_PORT) { pname = nodeSpiceName(snode->efnode_name->efnn_hier, &basenode); - if (basenode->efnode_name->efnn_port < 0) + if (HashLookOnly(&portNameTable, pname) == NULL) { - if (tchars > 80) + hep = HashFind(&portNameTable, pname); + if (basenode->efnode_name->efnn_port < 0) { - /* Line continuation */ - fprintf(esSpiceF, "\n+"); - tchars = 1; + if (tchars > 80) + { + /* Line continuation */ + fprintf(esSpiceF, "\n+"); + tchars = 1; + } + fprintf(esSpiceF, " %s", pname); + tchars += strlen(pname) + 1; + basenode->efnode_name->efnn_port = portorder++; } - fprintf(esSpiceF, " %s", pname); - tchars += strlen(pname) + 1; - basenode->efnode_name->efnn_port = portorder++; + snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port; + HashSetValue(hep, + (ClientData)(pointertype)snode->efnode_name->efnn_port); } - snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port; } } } @@ -1757,8 +1771,24 @@ topVisit(def, doStub) } else pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL); - fprintf(esSpiceF, " %s", pname); - tchars += strlen(pname) + 1; + + if (HashLookOnly(&portNameTable, pname) == NULL) + { + hep = HashFind(&portNameTable, pname); + HashSetValue(hep, + (ClientData)(pointertype)nodeName->efnn_port); + fprintf(esSpiceF, " %s", pname); + tchars += strlen(pname) + 1; + } + else + { + // Node that was unassigned has been found to be + // a repeat (see NOTE at top), so make sure its + // port number is set correctly. + + hep = HashFind(&portNameTable, pname); + nodeName->efnn_port = (int)(pointertype)HashGetValue(hep); + } break; } else if (portidx < 0) @@ -1779,6 +1809,7 @@ topVisit(def, doStub) portorder++; } } + HashKill(&portNameTable); /* Add all implicitly-defined local substrate node names */ diff --git a/extflat/EFhier.c b/extflat/EFhier.c index 53015361..b9b74b42 100644 --- a/extflat/EFhier.c +++ b/extflat/EFhier.c @@ -397,6 +397,7 @@ efHierDevKilled(hc, dev, prefix) for (n = 0; n < dev->dev_nterm; n++) { + if (dev->dev_terms[n].dterm_node == NULL) continue; suffix = dev->dev_terms[n].dterm_node->efnode_name->efnn_hier; he = HashLookOnly(&efNodeHashTable, (char *)suffix); if (he && (nn = (EFNodeName *) HashGetValue(he)) diff --git a/extflat/EFint.h b/extflat/EFint.h index e43aa507..0ce71180 100644 --- a/extflat/EFint.h +++ b/extflat/EFint.h @@ -286,6 +286,7 @@ extern Def *EFRootDef(); /* HierName manipulation */ extern HierName *efHNFromUse(); extern char *efHNToStrFunc(); +extern bool EFHNBest(); /* Functions for hashing of HierNames */ extern int efHNCompare(); diff --git a/extflat/EFvisit.c b/extflat/EFvisit.c index ef980491..6e6571a7 100644 --- a/extflat/EFvisit.c +++ b/extflat/EFvisit.c @@ -66,7 +66,7 @@ bool efDevKilled(); * (*subProc)(use, hierName, is_top) * Use *use; * HierName *hierName; - * Boolean is_top; + * bool is_top; * { * } * diff --git a/extract/ExtArray.c b/extract/ExtArray.c index 7122e1eb..605a6451 100644 --- a/extract/ExtArray.c +++ b/extract/ExtArray.c @@ -606,7 +606,12 @@ extArrayInterFunc(use, trans, x, y, ha) extHierConnections(ha, extArrayPrimary, oneFlat); /* Process substrate connection */ - extHierSubstrate(ha, use, x, y); + if (use->cu_xlo == use->cu_xhi) + extHierSubstrate(ha, use, -1, y); + else if (use->cu_ylo == use->cu_yhi) + extHierSubstrate(ha, use, x, -1); + else + extHierSubstrate(ha, use, x, y); ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL; if (ExtOptions & EXT_DOADJUST) diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index 0dd5cde2..184d1be5 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -67,7 +67,8 @@ char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres", * used to compute the resistance of each node. Each is * indexed by sheet resistivity class. */ -int extResistPerim[NT], extResistArea[NT]; +int extResistPerim[NT]; +dlong extResistArea[NT]; /* * The following structure is used in extracting transistors. @@ -575,7 +576,8 @@ void extSetResist(reg) NodeRegion *reg; { - int n, perim, area; + int n, perim; + dlong area; float s, fperim, v; for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) @@ -704,7 +706,7 @@ extOutputNodes(nodeList, outFile) /* Output its area and perimeter for each resistivity class */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) - fprintf(outFile, " %d %d", reg->nreg_pa[n].pa_area, + fprintf(outFile, " %"DLONG_PREFIX"d %d", reg->nreg_pa[n].pa_area, reg->nreg_pa[n].pa_perim); (void) putc('\n', outFile); @@ -738,6 +740,139 @@ extOutputNodes(nodeList, outFile) } } +/* + * --------------------------------------------------------------------- + * + * extSubsName -- + * + * Return the name of the substrate node, if the node belongs to + * the substrate region and a global substrate node name has been + * specified by the tech file. If the substrate node name is a + * Tcl variable name, then perform the variable substitution. + * + * Results: + * Pointer to a character string. + * + * Side Effects: + * None. + * + * --------------------------------------------------------------------- + */ + +char * +extSubsName(node) + LabRegion *node; +{ + char *subsName; + + /* If the techfile specifies a global name for the substrate, use */ + /* that in preference to the default "p_x_y#" name. Use this name */ + /* only to substitute for nodes with tiles at -(infinity). */ + + if (ExtCurStyle->exts_globSubstrateName != NULL) + { + if (node->lreg_ll.p_x <= (MINFINITY + 3)) + { + if (ExtCurStyle->exts_globSubstrateName[0] == '$' && + ExtCurStyle->exts_globSubstrateName[1] != '$') + { + // If subsName is a Tcl variable (begins with "$"), make the + // variable substitution, if one exists. Ignore double-$. + // If the variable is undefined in the interpreter, then + // strip the "$" from the front as this is not legal in most + // netlist formats. + + char *varsub = (char *)Tcl_GetVar(magicinterp, + &ExtCurStyle->exts_globSubstrateName[1], + TCL_GLOBAL_ONLY); + return (varsub != NULL) ? varsub : ExtCurStyle->exts_globSubstrateName + + 1; + } + else + return ExtCurStyle->exts_globSubstrateName; + } + else return NULL; + } + return NULL; +} + +/* + * ---------------------------------------------------------------------------- + * + * extMakeNodeNumPrint -- + * + * Construct a node name from the plane number "plane" and lower left Point + * "coord", and place it in the string "buf" (which must be large enough). + * + * Results: + * None. + * + * Side Effects: + * Fills in string "buf". + * + * ---------------------------------------------------------------------------- + */ + +void +extMakeNodeNumPrint(buf, lreg) + char *buf; + LabRegion *lreg; +{ + int plane = lreg->lreg_pnum; + Point *p = &lreg->lreg_ll; + char *subsName; + + subsName = extSubsName(lreg); + if (subsName != NULL) + strcpy(buf, subsName); + else + sprintf(buf, "%s_%s%d_%s%d#", + DBPlaneShortName(plane), + (p->p_x < 0) ? "n": "", abs(p->p_x), + (p->p_y < 0) ? "n": "", abs(p->p_y)); +} + +/* + * ---------------------------------------------------------------------------- + * + * extNodeName -- + * + * Given a pointer to a LabRegion, return a pointer to a string + * that can be printed as the name of the node. If the LabRegion + * has a list of attached labels, use one of the labels; otherwise, + * use its node number. + * + * Results: + * Returns a pointer to a string. If the node had a label, this + * is a pointer to the lab_text field of the first label on the + * label list for the node; otherwise, it is a pointer to a static + * buffer into which we have printed the node number. + * + * Side effects: + * May overwrite the static buffer used to hold the printable + * version of a node number. + * + * ---------------------------------------------------------------------------- + */ + +char * +extNodeName(node) + LabRegion *node; +{ + static char namebuf[256]; /* Big enough to hold a generated nodename */ + LabelList *ll; + + if (node == (LabRegion *) NULL || SigInterruptPending) + return ("(none)"); + + for (ll = node->lreg_labels; ll; ll = ll->ll_next) + if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) + return (ll->ll_label->lab_text); + + extMakeNodeNumPrint(namebuf, node); + return (namebuf); +} + /* * ---------------------------------------------------------------------------- * @@ -805,8 +940,7 @@ extFindDuplicateLabels(def, nreg) { r.r_ll = r.r_ur = ll2->ll_label->lab_rect.r_ll; r.r_xbot--, r.r_ybot--, r.r_xtop++, r.r_ytop++; - extMakeNodeNumPrint(name, - np2->nreg_pnum, np2->nreg_ll); + extMakeNodeNumPrint(name, np2); (void) sprintf(message, badmesg, text, name); DBWFeedbackAdd(&r, message, def, 1, STYLE_PALEHIGHLIGHTS); @@ -825,69 +959,6 @@ extFindDuplicateLabels(def, nreg) HashKill(&labelHash); } -/* - * ---------------------------------------------------------------------------- - * - * extNodeName -- - * - * Given a pointer to a LabRegion, return a pointer to a string - * that can be printed as the name of the node. If the LabRegion - * has a list of attached labels, use one of the labels; otherwise, - * use its node number. - * - * Results: - * Returns a pointer to a string. If the node had a label, this - * is a pointer to the lab_text field of the first label on the - * label list for the node; otherwise, it is a pointer to a static - * buffer into which we have printed the node number. - * - * Side effects: - * May overwrite the static buffer used to hold the printable - * version of a node number. - * - * ---------------------------------------------------------------------------- - */ - -char * -extNodeName(node) - LabRegion *node; -{ - static char namebuf[256]; /* Big enough to hold a generated nodename */ - LabelList *ll; - - if (node == (LabRegion *) NULL || SigInterruptPending) - return ("(none)"); - - for (ll = node->lreg_labels; ll; ll = ll->ll_next) - if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) - return (ll->ll_label->lab_text); - - /* If the techfile specifies a global name for the substrate, use */ - /* that in preference to the default "p_x_y#" name. */ - - if (((NodeRegion *)node == glob_subsnode) || ((NodeRegion *)node == temp_subsnode)) - { - if (ExtCurStyle->exts_globSubstrateName != NULL) - { - if (ExtCurStyle->exts_globSubstrateName[0] == '$' && - ExtCurStyle->exts_globSubstrateName[1] != '$') - { - // If subsName is a Tcl variable (begins with "$"), make the - // variable substitution, if one exists. Ignore double-$. - - char *varsub = (char *)Tcl_GetVar(magicinterp, - &ExtCurStyle->exts_globSubstrateName[1], - TCL_GLOBAL_ONLY); - return (varsub != NULL) ? varsub : ExtCurStyle->exts_globSubstrateName; - } - else - return ExtCurStyle->exts_globSubstrateName; - } - } - extMakeNodeNumPrint(namebuf, node->lreg_pnum, node->lreg_ll); - return (namebuf); -} - /* * --------------------------------------------------------------------- * @@ -1730,10 +1801,6 @@ extOutputDevices(def, transList, outFile) if (TTMaskIsZero(tmask)) { if (termcount < nsd) { ExtDevice *devcheck; - /* See if there is another matching device record with */ - /* a different number of terminals, and try again. */ - devcheck = extDevFindMatch(devptr, t); - if (devcheck != NULL) devptr = devcheck; /* Not finding another device record just means that */ /* terminals are tied together on the same net, such as */ @@ -1741,11 +1808,37 @@ extOutputDevices(def, transList, outFile) } break; /* End of SD terminals */ } - else if (!TTMaskIntersect(tmask, &DBPlaneTypes[reg->treg_pnum])) + else if (!TTMaskIntersect(tmask, &DBPlaneTypes[reg->treg_pnum]) + || (TTMaskHasType(tmask, TT_SPACE))) { node = NULL; + + /* First try to find a region under the device */ extTransFindSubs(reg->treg_tile, t, tmask, def, &node, NULL); - if (node == NULL) { + + if ((node == NULL) && (TTMaskHasType(tmask, TT_SPACE))) { + /* Device node is possibly the substrate. But: Note */ + /* that TT_SPACE in the mask covers all planes, and it */ + /* is not possible to specify TT_SPACE in a single */ + /* plane. So it is necessary to check for any */ + /* shielding types that block the substrate. */ + + if (!TTMaskIsZero(&ExtCurStyle->exts_globSubstrateShieldTypes)) + { + extTransFindSubs(reg->treg_tile, t, + &ExtCurStyle->exts_globSubstrateShieldTypes, + def, &node, NULL); + } + if ((glob_subsnode == NULL) || (node != NULL)) { + /* See if there is another matching device record */ + /* with a different terminal type, and try again. */ + devptr = extDevFindMatch(devptr, t); + break; + } + else if ((node == NULL) && (glob_subsnode != NULL)) + node = glob_subsnode; + } + else if (node == NULL) { /* See if there is another matching device record */ /* with a different terminal type, and try again. */ devptr = extDevFindMatch(devptr, t); @@ -1754,17 +1847,6 @@ extOutputDevices(def, transList, outFile) extTransRec.tr_devmatch |= (MATCH_TERM << termcount); extTransRec.tr_termnode[termcount] = node; } - else if (TTMaskHasType(tmask, TT_SPACE)) { - /* Device node is specified as being the substrate */ - if (glob_subsnode == NULL) { - /* See if there is another matching device record */ - /* with a different terminal type, and try again. */ - devptr = extDevFindMatch(devptr, t); - break; - } - extTransRec.tr_devmatch |= (MATCH_TERM << termcount); - extTransRec.tr_termnode[termcount] = glob_subsnode; - } else { /* Determine if there is another matching device record */ /* that has fewer required terminals. */ @@ -3093,8 +3175,9 @@ extSpecialPerimFunc(bp, sense) break; if (thisterm >= extTransRec.tr_nterm) { - if (toutside == TT_SPACE) - TxError("Internal Error in Transistor Perimeter Boundary Search!\n"); + /* This is not necessarily an error; e.g., happens for */ + /* a device like a diode with TT_SPACE in the source/ */ + /* drain list. */ return 1; } } @@ -3759,7 +3842,8 @@ extNodeAreaFunc(tile, arg) Tile *tile; FindRegion *arg; { - int tilePlaneNum, pNum, len, area, resistClass, n, nclasses; + int tilePlaneNum, pNum, len, resistClass, n, nclasses; + dlong area; PlaneMask pMask; CapValue capval; TileTypeBitMask *mask, *resMask; @@ -3855,9 +3939,9 @@ extNodeAreaFunc(tile, arg) { TITORECT(tile, &r); GEOCLIP(&r, extNodeClipArea); - area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); + area = (dlong)(r.r_xtop - r.r_xbot) * (dlong)(r.r_ytop - r.r_ybot); } - else area = TILEAREA(tile); + else area = (dlong)(TOP(tile) - BOTTOM(tile)) * (dlong)(RIGHT(tile) - LEFT(tile)); if (IsSplit(tile)) area /= 2; /* Split tiles are 1/2 area! */ diff --git a/extract/ExtHard.c b/extract/ExtHard.c index 7d733caa..1cd48c57 100644 --- a/extract/ExtHard.c +++ b/extract/ExtHard.c @@ -406,22 +406,7 @@ extHardGenerateLabel(scx, reg, arg) Rect r; Point p; - // Modification 9/9/2014 by Tim: - // Convert the treg_ll value up to top-level coordinates. - // Otherwise you end up with a node that is apparently in - // "canonical coordinates", but if you try to find the - // location of the node using the name, you'll end up in - // a random place. It also allows the low-probability - // but possible conflict between this node and another with - // the same name in the parent cell. - // - // Reverted 10/30/2014: Apparently this causes worse - // problems. - // - // GeoTransPoint(&scx->scx_trans, ®->treg_ll, &r.r_ll); - // extMakeNodeNumPrint(gen, reg->treg_pnum, r.r_ll); - - extMakeNodeNumPrint(gen, reg->treg_pnum, reg->treg_ll); + extMakeNodeNumPrint(gen, (LabRegion *)reg); prefixlen = tpath->tp_next - tpath->tp_first; len = strlen(gen) + prefixlen; diff --git a/extract/ExtMain.c b/extract/ExtMain.c index 664435a8..d3b0c4f5 100644 --- a/extract/ExtMain.c +++ b/extract/ExtMain.c @@ -51,7 +51,7 @@ extern FILE *extFileOpen(); /* * See extract.h for the bit flags that may be set in the following. * If any are set, the corresponding warnings get generated, leaving - * feedback messages. If this word is zero, only fatal errors are + * feedback messages. If this word is zero, only errors are * reported. */ int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS; @@ -179,7 +179,11 @@ ExtAll(rootUse) CellUse *rootUse; { /* Make sure the entire subtree is read in */ - DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); + if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + { + TxError("Failure to read entire subtree of cell.\n"); + return; + } /* Fix up bounding boxes if they've changed */ DBFixMismatch(); @@ -264,7 +268,11 @@ ExtUnique(rootUse, option) int nwarn; /* Make sure the entire subtree is read in */ - DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); + if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + { + TxError("Failure to read entire subtree of cell.\n"); + return; + } /* Fix up bounding boxes if they've changed */ DBFixMismatch(); @@ -526,7 +534,11 @@ ExtIncremental(rootUse) CellUse *rootUse; { /* Make sure the entire subtree is read in */ - DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); + if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + { + TxError("Failure to read entire subtree of cell.\n"); + return; + } /* Fix up bounding boxes if they've changed */ DBFixMismatch(); @@ -663,7 +675,7 @@ extExtractStack(stack, doExtract, rootDef) else { if (fatal > 0) - TxError("Total of %d fatal error%s.\n", + TxError("Total of %d error%s (check feedback entries).\n", fatal, fatal != 1 ? "s" : ""); if (warnings > 0) TxError("Total of %d warning%s.\n", diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 4f6bdb59..7445ddb4 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -2202,10 +2202,13 @@ ExtTechLine(sectionName, argc, argv) termtypes[1] = DBZeroTypeBits; /* Make it symmetric */ else if (!TTMaskIsZero(&termtypes[2])) { + class = DEV_ASYMMETRIC; TechError("Device mosfet %s has overlapping drain" " and source types!\n", transName); /* Should this device be disabled? */ } + else + class = DEV_ASYMMETRIC; termtypes[2] = DBZeroTypeBits; if (strcmp(argv[6], "None")) DBTechNoisyNameMask(argv[6], &subsTypes); /* substrate */ @@ -2213,7 +2216,6 @@ ExtTechLine(sectionName, argc, argv) if (argc > 8) gscap = aToCap(argv[8]); if (argc > 9) gccap = aToCap(argv[9]); nterm = 2; - class = DEV_ASYMMETRIC; } else { diff --git a/extract/ExtTimes.c b/extract/ExtTimes.c index 262b2bfe..c13c5f59 100644 --- a/extract/ExtTimes.c +++ b/extract/ExtTimes.c @@ -169,7 +169,11 @@ ExtTimes(rootUse, f) HashEntry *he; /* Make sure this cell is read in */ - DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); + if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + { + TxError("Failure to read entire subtree of cell.\n"); + return; + } /* Initialize cumulative statistics */ extCumInit(&cumFetsPerSecPaint); @@ -1020,7 +1024,11 @@ ExtInterCount(rootUse, halo, f) double inter; /* Make sure this cell is read in */ - DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); + if (DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox, TRUE)) + { + TxError("Failure to read entire subtree of cell.\n"); + return; + } /* Initialize cumulative statistics */ extCumInit(&cumPercentInteraction); diff --git a/extract/ExtUnique.c b/extract/ExtUnique.c index accb53fa..30776c9c 100644 --- a/extract/ExtUnique.c +++ b/extract/ExtUnique.c @@ -177,6 +177,7 @@ extMakeUnique(def, ll, lreg, lregList, labelHash, option) int nsuffix, nwarn; Label saveLab, *lab; Rect r; + int flags; /* * Make a pass through all labels for all nodes. @@ -207,7 +208,7 @@ extMakeUnique(def, ll, lreg, lregList, labelHash, option) nwarn++; r.r_ll = r.r_ur = ll2->ll_label->lab_rect.r_ll; GEO_EXPAND(&r, 1, &r); - extMakeNodeNumPrint(name, lp2->lreg_pnum, lp2->lreg_ll); + extMakeNodeNumPrint(name, lp2); (void) sprintf(message, badmesg, text, name); DBWFeedbackAdd(&r, message, def, 1, STYLE_MEDIUMHIGHLIGHTS); } @@ -258,13 +259,32 @@ makeUnique: nsuffix++; } + /* If the label is a port, then the port needs a unique ID */ + /* for the unique name. */ + + flags = ll2->ll_label->lab_flags; + if (flags & PORT_DIR_MASK) { + int idx; + int portno = -1; + /* Find the last port index used in the cell def */ + for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next) + { + idx = lab->lab_flags & PORT_NUM_MASK; + if (idx > portno) portno = idx; + } + portno++; + flags &= ~PORT_NUM_MASK; + flags |= portno; + } + lab = ll2->ll_label; saveLab = *lab; + DBRemoveLabel(def, lab); (void) DBPutFontLabel(def, &saveLab.lab_rect, saveLab.lab_font, saveLab.lab_size, saveLab.lab_rotate, &saveLab.lab_offset, saveLab.lab_just, name2, - saveLab.lab_type, saveLab.lab_flags); + saveLab.lab_type, flags); ll2->ll_label = (Label *) NULL; } diff --git a/extract/extractInt.h b/extract/extractInt.h index ea139e54..82d18d51 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -182,7 +182,7 @@ typedef struct lreg typedef struct { int pa_perim; - int pa_area; + dlong pa_area; } PerimArea; typedef struct nreg @@ -239,28 +239,6 @@ typedef struct { CapValue subcap_adjust; } SubCapAdjust; -/* - * The following constructs a node name from the plane number 'n' - * and lower left Point l, and places it in the string 's' (which must - * be large enough). - */ -#define extMakeNodeNumPrint(buf, plane, coord) \ - (void) sprintf((buf), "%s_%s%d_%s%d#", DBPlaneShortName(plane), \ - ((coord).p_x < 0) ? "n": "", abs((coord).p_x), \ - ((coord).p_y < 0) ? "n": "", abs((coord).p_y)) - -/* Old way: cryptic numbers, but a bit shorter - * - * #define extMakeNodeNumPrint(s, n, l) \ - * (void) sprintf((s), "%d_%d_%d#", (n), extCoord((l).p_x), extCoord((l).p_y)) - * - * The following is used to map the full coordinate space into - * the positive integers, for constructing internally generated - * node names. - * - * #define extCoord(x) (((x) < 0) ? (1 - ((x) << 1)) : ((x) << 1)) - */ - /* * Argument passed to filter functions for finding regions. */ @@ -1076,6 +1054,7 @@ extern NodeRegion *extFindNodes(); extern ExtTree *extHierNewOne(); extern int extNbrPushFunc(); extern TileType extGetDevType(); +extern void extMakeNodeNumPrint(); /* --------------------- Miscellaneous globals ------------------------ */ diff --git a/garouter/gaTest.c b/garouter/gaTest.c index b48c78d5..2e9cf05d 100644 --- a/garouter/gaTest.c +++ b/garouter/gaTest.c @@ -164,7 +164,7 @@ GAGenChans(chanType, area, f) Rect *area; FILE *f; { - extern void DBPaintPlane0(), DBPaintPlaneVert(); + extern int DBPaintPlane0(), DBPaintPlaneVert(); int gaSplitFunc(), gaSplitOut(); static CellDef *genDef = (CellDef *) NULL; static CellUse *genUse = (CellUse *) NULL; @@ -201,7 +201,7 @@ GAGenChans(chanType, area, f) } /* Make sure everything in 'area' is read */ - (void) DBCellReadArea(EditCellUse, area); + (void) DBCellReadArea(EditCellUse, area, FALSE); DBFixMismatch(); /* Start with a clean slate */ diff --git a/graphics/grNull.c b/graphics/grNull.c index 6451a4e7..b6bcec46 100644 --- a/graphics/grNull.c +++ b/graphics/grNull.c @@ -281,5 +281,8 @@ nullSetDisplay(dispType, outFileName, mouseFileName) GrScreenRect.r_xtop = 511; GrScreenRect.r_ytop = 483; + /* Set GrDisplayStatus to force graphics updates to be suspended */ + GrDisplayStatus = DISPLAY_SUSPEND; + return TRUE; } diff --git a/graphics/grTk1.c b/graphics/grTk1.c index 19093847..5521cc82 100644 --- a/graphics/grTk1.c +++ b/graphics/grTk1.c @@ -527,6 +527,7 @@ GrTkInit(dispType) TxPrintf("None of TrueColor 15, 16 or 24, or PseudoColor 8 found. " "Cannot initialize DISPLAY %s\n", getenv("DISPLAY")); XFree(grvisual_get); + GrClosePtr = NULL; MainExit(1); } else diff --git a/lef/defRead.c b/lef/defRead.c index 9d41dc00..9156e0e7 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -683,7 +683,7 @@ DefReadNets(f, rootDef, sname, oscale, special, dolabels, total) NULL }; - defLayerMap = defMakeInverseLayerMap(); + defLayerMap = defMakeInverseLayerMap(LAYER_MAP_VIAS); while ((token = LefNextToken(f, TRUE)) != NULL) { @@ -942,6 +942,7 @@ DefReadPins(f, rootDef, sname, oscale, total) int keyword, subkey, values, flags; int processed = 0; int pinDir = PORT_CLASS_DEFAULT; + int pinUse = PORT_USE_DEFAULT; int pinNum = 0; TileType curlayer = -1; Rect *currect, topRect; @@ -978,6 +979,19 @@ DefReadPins(f, rootDef, sname, oscale, total) NULL }; + static char *pin_uses[] = { + "DEFAULT", + "SIGNAL", + "POWER", + "GROUND", + "CLOCK", + "RESET", + "ANALOG", + "SCAN", + "TIEOFF", + NULL + }; + static int lef_class_to_bitmask[] = { PORT_CLASS_DEFAULT, PORT_CLASS_INPUT, @@ -987,6 +1001,20 @@ DefReadPins(f, rootDef, sname, oscale, total) PORT_CLASS_FEEDTHROUGH }; + static int lef_use_to_bitmask[] = { + PORT_USE_DEFAULT, + PORT_USE_SIGNAL, + PORT_USE_POWER, + PORT_USE_GROUND, + PORT_USE_CLOCK, + PORT_USE_RESET, + PORT_USE_ANALOG, + PORT_USE_SCAN, + PORT_USE_TIEOFF + }; + + flags = 0; + while ((token = LefNextToken(f, TRUE)) != NULL) { keyword = Lookup(token, pin_keys); @@ -1058,6 +1086,13 @@ DefReadPins(f, rootDef, sname, oscale, total) hasports = TRUE; break; case DEF_PINS_PROP_USE: + token = LefNextToken(f, TRUE); + subkey = Lookup(token, pin_uses); + if (subkey < 0) + LefError(DEF_ERROR, "Unknown pin use \"%s\"\n", token); + else + pinUse = lef_use_to_bitmask[subkey]; + break; case DEF_PINS_PROP_NET: /* Get the net name, but ignore it */ token = LefNextToken(f, TRUE); @@ -1066,7 +1101,7 @@ DefReadPins(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_classes); if (subkey < 0) - LefError(DEF_ERROR, "Unknown pin class\n"); + LefError(DEF_ERROR, "Unknown pin class \"%s\"\n", token); else pinDir = lef_class_to_bitmask[subkey]; break; @@ -1086,7 +1121,7 @@ DefReadPins(f, rootDef, sname, oscale, total) GeoTransRect(&t, currect, &topRect); DBPaint(rootDef, &topRect, curlayer); DBPutLabel(rootDef, &topRect, -1, pinname, curlayer, - pinNum | pinDir | flags); + pinNum | pinDir | pinUse | flags); pending = FALSE; pinNum++; } @@ -1109,7 +1144,7 @@ DefReadPins(f, rootDef, sname, oscale, total) GeoTransRect(&t, currect, &topRect); DBPaint(rootDef, &topRect, curlayer); DBPutLabel(rootDef, &topRect, -1, pinname, curlayer, - pinNum | pinDir | flags); + pinNum | pinDir | pinUse | flags); pinNum++; } break; @@ -1666,7 +1701,7 @@ enum def_sections {DEF_VERSION = 0, DEF_NAMESCASESENSITIVE, DEF_HISTORY, DEF_DIEAREA, DEF_COMPONENTS, DEF_VIAS, DEF_PINS, DEF_PINPROPERTIES, DEF_SPECIALNETS, DEF_NETS, DEF_IOTIMINGS, DEF_SCANCHAINS, - DEF_CONSTRAINTS, DEF_GROUPS, DEF_EXTENSION, + DEF_CONSTRAINTS, DEF_GROUPS, DEF_EXTENSION, DEF_BLOCKAGES, DEF_END}; void @@ -1708,6 +1743,7 @@ DefRead(inName, dolabels) "CONSTRAINTS", "GROUPS", "BEGINEXT", + "BLOCKAGES", "END", NULL }; @@ -1873,6 +1909,9 @@ DefRead(inName, dolabels) case DEF_EXTENSION: LefSkipSection(f, sections[DEF_EXTENSION]); break; + case DEF_BLOCKAGES: + LefSkipSection(f, sections[DEF_BLOCKAGES]); + break; case DEF_END: if (!LefParseEndStatement(token, "DESIGN")) { diff --git a/lef/defWrite.c b/lef/defWrite.c index a3702703..e9dbae77 100644 --- a/lef/defWrite.c +++ b/lef/defWrite.c @@ -1143,7 +1143,8 @@ defNetGeometryFunc(tile, plane, defdata) /* residue of the contact as the route layer */ /* type. */ - rName = defGetType((rtype == TT_SPACE) ? r2type : rtype, NULL); + rName = defGetType((rtype == TT_SPACE) ? r2type : rtype, NULL, + LAYER_MAP_VIAS); /* The first layer in a record may not be a via name */ @@ -1534,9 +1535,10 @@ defCountViaFunc(tile, cviadata) */ char * -defGetType(ttype, lefptr) +defGetType(ttype, lefptr, do_vias) TileType ttype; lefLayer **lefptr; + bool do_vias; { HashSearch hs; HashEntry *he; @@ -1552,6 +1554,10 @@ defGetType(ttype, lefptr) while (he = HashNext(&LefInfo, &hs)) { lefl = (lefLayer *)HashGetValue(he); + if (lefl && (do_vias == FALSE) && (contact == CLASS_VIA) && + (lefl->info.via.lr != NULL)) + continue; /* Skip VIA definitions if do_vias is FALSE */ + if (lefl && ((contact == lefl->lefClass) || ((contact == CLASS_ROUTE) && (lefl->lefClass == CLASS_MASTER)))) if ((lefl->type == ttype) || (lefl->obsType == ttype)) @@ -1870,7 +1876,8 @@ defComponentFunc(cellUse, defdata) */ LefMapping * -defMakeInverseLayerMap() +defMakeInverseLayerMap(do_vias) + bool do_vias; { LefMapping *lefMagicToLefLayer; lefLayer *lefl; @@ -1882,7 +1889,7 @@ defMakeInverseLayerMap() memset(lefMagicToLefLayer, 0, sizeof(LefMapping) * TT_TECHDEPBASE); for (i = TT_TECHDEPBASE; i < DBNumTypes; i++) { - lefname = defGetType(i, &lefl); + lefname = defGetType(i, &lefl, do_vias); lefMagicToLefLayer[i].lefName = lefname; lefMagicToLefLayer[i].lefInfo = lefl; } @@ -1969,7 +1976,7 @@ DefWriteCell(def, outName, allSpecial, units) defWriteHeader(def, f, scale, units); - lefMagicToLefLayer = defMakeInverseLayerMap(); + lefMagicToLefLayer = defMakeInverseLayerMap(LAYER_MAP_VIAS); /* Vias---magic contact areas are reported as vias. */ total = defCountVias(def, lefMagicToLefLayer, scale); diff --git a/lef/lefCmd.c b/lef/lefCmd.c index 32b9e881..6646d402 100644 --- a/lef/lefCmd.c +++ b/lef/lefCmd.c @@ -113,7 +113,7 @@ CmdLef(w, cmd) { "read [filename] read a LEF file filename[.lef]\n" " read [filename] -import read a LEF file; import cells from .mag files\n" - " read [filename] -annotate read a LEF file for cell annotation only." + " read [filename] -annotate read a LEF file for cell annotation only.", "write [filename] [-tech] write LEF for current cell\n" " write [filename] -hide hide all details other than ports\n" " write [filename] -hide hide details in area set back distance ", @@ -129,7 +129,7 @@ CmdLef(w, cmd) static char *cmdDefOption[] = { "read [filename] read a DEF file filename[.def]", - "write [cell] [-allspecial] write DEF for current or indicated cell\n", + "write [cell] [-allspecial] write DEF for current or indicated cell\n" "write -labels label every net in NETS with the net name", "writeall (use \"flatten -nosubckt\" + \"def" " write\" instead)", diff --git a/lef/lefInt.h b/lef/lefInt.h index 9c31dd80..3b270630 100644 --- a/lef/lefInt.h +++ b/lef/lefInt.h @@ -35,6 +35,10 @@ typedef struct #define DO_SPECIAL 1 #define ALL_SPECIAL 2 /* treat all nets as SPECIALNETS */ +/* Used with defMakeInverseLayerMap() */ +#define LAYER_MAP_NO_VIAS FALSE +#define LAYER_MAP_VIAS TRUE + /* For a linked list of rectangular areas, use the LinkedRect structure */ /* defined in utils/geometry.h. */ diff --git a/lef/lefRead.c b/lef/lefRead.c index b35ab5a5..307de1a4 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1385,6 +1385,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) int pinUse = PORT_USE_DEFAULT; int pinShape = PORT_SHAPE_DEFAULT; Label *firstlab; + bool firstport = TRUE; static char *pin_keys[] = { "DIRECTION", @@ -1636,13 +1637,14 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) if (needRect) { - if (lab == NULL) + if ((lab == NULL) && (firstport == TRUE)) DBEraseLabelsByContent(lefMacro, NULL, -1, testpin); LefReadPort(lefMacro, f, testpin, pinNum, pinDir, pinUse, pinShape, oscale, lab); } else LefSkipSection(f, NULL); + firstport = FALSE; } else LefReadPort(lefMacro, f, testpin, pinNum, pinDir, pinUse, diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 6803f087..17a3ac17 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -1171,7 +1171,7 @@ lefWriteMacro(def, f, scale, setback, toplayer, domaster) lc.file = f; lc.oscale = scale; - lc.lefMagicMap = defMakeInverseLayerMap(); + lc.lefMagicMap = defMakeInverseLayerMap(LAYER_MAP_NO_VIAS); lc.lastType = TT_SPACE; lc.lefFlat = lefFlatDef; @@ -1674,7 +1674,7 @@ lefWriteMacro(def, f, scale, setback, toplayer, domaster) freeMagic(thislll); } - if (setback > 0) + if (setback >= 0) { /* For -hide with setback, yank everything in the area outside */ /* the setback. */ @@ -1982,7 +1982,11 @@ LefWriteAll(rootUse, writeTopCell, lefTech, lefHide, lefTopLayer, lefDoMaster, r rootdef = rootUse->cu_def; /* Make sure the entire subtree is read in */ - DBCellReadArea(rootUse, &rootdef->cd_bbox); + if (DBCellReadArea(rootUse, &rootdef->cd_bbox, TRUE)) + { + TxError("Could not read entire subtree of the cell.\n"); + return; + } /* Fix up bounding boxes if they've changed */ DBFixMismatch(); diff --git a/magic/proto.magicrc.in b/magic/proto.magicrc.in index cb2b0921..1636df63 100644 --- a/magic/proto.magicrc.in +++ b/magic/proto.magicrc.in @@ -167,6 +167,8 @@ macro XK_KP_Prior "move ne 1" # Scroll wheel bindings macro XK_Pointer_Button4 "scroll u .05 w" macro XK_Pointer_Button5 "scroll d .05 w" +macro Shift_XK_Pointer_Button4 "scroll l .05 w" +macro Shift_XK_Pointer_Button5 "scroll r .05 w" # Quick macro function keys for scmos tech (X11 versions only) macro XK_F1 "paint ndiff" macro XK_F2 "paint pdiff" diff --git a/plow/PlowRandom.c b/plow/PlowRandom.c index ccf2922d..b0e2db20 100644 --- a/plow/PlowRandom.c +++ b/plow/PlowRandom.c @@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include +#include #include #include #include diff --git a/scmos/Makefile b/scmos/Makefile index dc30a1e8..93be8659 100644 --- a/scmos/Makefile +++ b/scmos/Makefile @@ -24,7 +24,7 @@ FILES = mos.7bit.dstyle mos.7bit.std.cmap \ mos.7bit.mraster_dstyle mos.7bit.mraster.cmap \ mos.OpenGL.dstyle mos.OpenGL.std.cmap TECHFILES = minimum.tech gdsquery.tech scmos.tech scmos-tm.tech \ - scmos-sub.tech scmosWR.tech + scmos-sub.tech scmosWR.tech nmos.tech CIFin = cif_template/objs/CIFin CIFout = cif_template/objs/CIFout @@ -87,6 +87,9 @@ minimum.tech: minimum.tech.in gdsquery.tech: gdsquery.tech.in $(SC_PP) gdsquery.tech.in > gdsquery.tech +nmos.tech: nmos.tech.in + $(CP) nmos.tech.in nmos.tech + $(CIFin): $(CIFout): $(ICIFin): diff --git a/scmos/nmos.tech.in b/scmos/nmos.tech.in new file mode 100644 index 00000000..00e1cadc --- /dev/null +++ b/scmos/nmos.tech.in @@ -0,0 +1,473 @@ +# +# nmos.tech -- +# +# Defines the MOSIS 4.0 micron NMOS technology for Magic. Some +# of the characteristics of this technology are: +# +# 1. 1 level of metal. +# 2. Buried contacts. +# 3. No butting contacts. +# +# Copyright (C) 1985 Regents of the University of California +# All rights reserved. +# +# sccsid @(#)nmos.tech 3.73 MAGIC (Berkeley) 11/22/85 +# + +tech + format 35 + nmos +end + +version + version 0 + description "MOSIS 4.0 micron NMOS" + requires magic-8.3.0 +end + +planes + active,diff,poly_diff + metal +end + +types + active polysilicon,poly,red + active diffusion,diff,green + metal metal,blue + active poly_metal_contact,pmc + active diff_metal_contact,dmc + active enhancement_fet,efet + active depletion_fet,dfet + active depletion_capacitor,dcap + active buried_contact,bc + metal glass_contact,glass +end + +styles + styletype mos + + polysilicon 1 + diffusion 2 + metal 20 + enhancement_fet 6 + enhancement_fet 7 + depletion_fet 6 + depletion_fet 10 + depletion_capacitor 6 + depletion_capacitor 11 + buried_contact 6 + buried_contact 33 + poly_metal_contact 1 + poly_metal_contact 20 + poly_metal_contact 32 + diff_metal_contact 2 + diff_metal_contact 20 + diff_metal_contact 32 + glass_contact 20 + glass_contact 34 + + error_s 42 + error_p 42 + error_ps 42 + + # Hint layers + magnet 39 + fence 38 + rotate 37 +end + +contact + pmc poly metal + dmc diff metal +end + +aliases + + allDiff diff,dmc,bc,efet,dfet,dcap + allPoly poly,pmc,bc,efet,dfet,dcap + tran efet,dfet + allMetal metal,pmc,dmc,glass + spP (space,poly,pmc)/a + sdD (space,diff,dmc)/a + notDmc space,metal,pmc,glass + notPmc space,metal,dmc,glass + allButFet (space,diff,poly,dmc,pmc,bc)/a + allpdTypes (space,diff,poly,dmc,pmc,bc,dfet,dcap,efet)/a + +end + +compose +# The following rule allows transistors to be built up of poly and diff */ + compose efet poly diff + +# The following rules allow poly or diff to be erased from fets or bcs */ + decompose dfet poly diff + decompose dcap poly diff + decompose bc poly diff + +# The following lets us erase metal from a glass_contact to get space */ + erase glass metal space +end + +# +# Electrical connectivity. Each tile in the group on the left +# is considered to be connected to each tile in the group on +# the right. Tiles within the groups are not necessarily +# connected to each other. +# + +connect + poly pmc,efet,dfet,dcap,bc + diff bc,dmc + efet pmc,dmc,bc,dfet,dcap + dfet pmc,dmc,bc,dcap + dcap pmc,dmc,bc + pmc dmc,bc + dmc bc + metal glass,pmc,dmc + glass pmc,dmc +end + +# Information used to generate CIF files. The only tricky business +# is to merge necks between adjacent implants or buried windows. +# The grow-shrink does this. Also, note that labels on Magic layers +# get attached to the first CIF layer containing that Magic layer +# in an "or" or "bloat-or" statement. This makes order important +# (for example, we want transistor labels to attach to the poly gate). +# + +cifoutput +style lambda=2 + scalefactor 200 100 + layer NP poly,pmc,efet,dfet,dcap,bc + labels poly,efet,dfet,dcap,bc + calma 1 1 + layer ND diff,dmc,efet,dfet,dcap,bc + labels diff + calma 2 1 + layer NM metal,pmc,dmc,glass + labels metal,pmc,dmc,glass + calma 3 1 + layer NI + bloat-or dfet,dcap * 200 diff,bc 400 + grow 100 + shrink 100 + calma 4 1 + layer NC dmc + squares 400 + calma 5 1 + layer NC pmc + squares 400 + calma 6 1 + layer NG glass + calma 7 1 + layer NB + bloat-or bc * 200 diff,dmc 400 dfet 0 + grow 100 + shrink 100 + calma 8 1 +end + +# Information on how to read CIF files. Read in all the CIF layers, +# then perform geometric operations to get the Magic layers. The +# order in which the Magic layers are generated is important! +# + +cifinput +style lambda=2 + scalefactor 200 + layer poly NP + labels NP + layer diff ND + labels ND + layer metal NM + labels NM + layer efet NP + and ND + layer dfet NI + and NP + and ND + layer pmc NC + grow 200 + and NM + and NP + layer dmc NC + grow 200 + and NM + and ND + # Buried contacts must be generated after transistors, since they + # override transistors. + # + layer bc NB + and NP + and ND + layer glass NG +end + +mzrouter + style irouter + layer metal 32 32 256 1 + layer poly 64 64 256 1 + contact pmc metal poly 1024 +end + +# +# DRC information +# Width, spacing and edge rules are "compiled" into rules table entries. +# +# width: types in the mask, taken collectively, must have the given width +# +# spacing: types in mask1 must be separated by distance from types in mask2 +# +# edge: explict entries for the rules table -- +# LHS RHS distance types allowed on RHS corner mask reason +# +# All combinations of single elements of the LHS and RHS masks +# are used to form a rule. +# + +drc +width allDiff 2 "Diffusion width must be at least 2" +width dmc 4 "Metal_diff contact width must be at least 4" +width allPoly 2 "Polysilicon width must be at least 2" +width pmc 4 "Metal_poly contact width must be at least 4" +width bc 2 "Buried contact width must be at least 2" +width efet 2 "Enhancement FET width must be at least 2" +width dfet 2 "Depletion FET width must be at least 2" +width dcap 2 "Depletion capacitor width must be at least 2" +width allMetal 3 "Metal width must be at least 3" + +spacing allDiff allDiff 3 touching_ok \ + "Diff-diff separation must be at least 3" +spacing allPoly allPoly 2 touching_ok \ + "Poly-poly separation must be at least 2" +spacing tran pmc,dmc 1 touching_illegal \ + "Transistor-contact separation must be at least 1" +spacing efet dfet,dcap 3 touching_illegal \ + "Enhancement-depletion transistor separation must be at least 3" +spacing allMetal allMetal 3 touching_ok \ + "Metal-metal separation must be at least 3" + # + # Diff and poly cannot be adjacent, except at corners where + # the intermediate material is "bc", "efet", "dfet", or "dcap". + # Thus, there is no need for rules with RHS equal to "Bef". + # But corner extension applies if the intermediate material is "s". + # For this reason, the first edge rule CANNOT be rewritten as + # "edge diff pP 1 0 pP 1". + # +edge diff spP 1 (space)/a spP 1 \ + "Diff-poly separation must be at least 1" +edge poly sdD 1 (space)/a sdD 1 \ + "Diff-poly separation must be at least 1" + # + # Allow dmc and pmc to be adjacent since they are electrically shorted. + # +edge dmc (space,poly)/a 1 (space)/a (space,poly)/a 1 \ + "Diff-poly separation must be at least 1" +edge pmc (space,diff)/a 1 (space)/a (space,diff)/a 1 \ + "Diff-poly separation must be at least 1" + + # + # Don't let pmc and dmc have convex shapes, since this may interfere + # with the via-generation process. The corner check in the rules + # below does this. Also don't let contacts overlap between cells + # unless they do so exactly. + # + +edge4way dmc notDmc 1 notDmc notDmc,dmc 1 \ + "Diffusion-metal contacts must be rectangular" +edge4way pmc notPmc 1 notPmc notPmc,pmc 1 \ + "Poly-metal contacts must be rectangular" +exact_overlap pmc,dmc + # + # Transistors cannot touch space, except in corners. + # The corner mask is set to 0 to prevent checking there. + # +edge tran (space)/a 1 0 0 0 \ + "Transistor overhang is missing" +edge (space)/a tran 1 0 0 0 \ + "Transistor overhang is missing" + # + # Buried contacts must be 3 lambda from efets in all cases, + # and 4 lambda in some. Depends on the orientation of the + # buried contact implant. The 4x3 corner checks ON BOTH + # SIDES solve the problem. Buried contacts may abut + # depletion transistors, but only if the transistors are + # fairly long (otherwise, a misalignment in the buried + # window mask may make a huge difference in the transistor's + # effective length). + # +spacing bc efet 3 touching_illegal \ + "Buried contact-transistor separation must be at least 3" +spacing bc dfet 3 touching_ok \ + "Buried contact-transistor separation must be at least 3" +edge4way bc diff,dmc 4 allButFet allpdTypes 3 \ + "Buried contact-transistor separation must be at least 4 on diff side" +edge4way bc dfet 4 dfet 0 0 \ + "Transistors next to buried contacts must be at least 4 long" + + # + # WARNING: The above rules don't take care of poly approaching + # the buried contact on the diffusion side. Unfortunately, the + # only fix is a rule that is ridiculously conservative. So + # for now, buyer beware! + # + + # + # 3 by 2 shape of buried contact next to dfet. + # No corner check. + # +edge4way dfet bc 3 bc 0 0 \ + "Buried contact next to depletion transistor must be at least 3x2" + # + # Poly and diffusion must overhang transistors by 2. + # + # Corner checks are necessary for L or S shaped transistors. + # + # Don't worry about dfet -- buried_contact boundaries here. + # +edge4way tran poly 2 poly,pmc poly 2 \ + "Polysilicon must overhang transistor by at least 2" +edge4way tran diff 2 diff,dmc diff 2 \ + "Diffusion must overhang transistor by at least 2" + + # Cannot change transistors as a result of cell overlaps */ +no_overlap efet,dfet efet,dfet +end + +# +# Parameters for circuit extraction. +# A type may appear both as a node and as a transistor. When it +# appears as a node, we are describing the gate, and when it appears +# as a transistor, we are describing the channel. +# + +extract + style default + # scale factor: output units (centimicrons) per lambda */ + lambda 200 + + # chunk size for hierarchical extraction, in lambda */ + step 100 + + planeorder active 0 + planeorder metal 1 + + # sheet resistivity milli-ohms per square */ + resist diff,dmc/poly 10000 + resist poly,pmc/poly,efet,dfet,bc 30000 + resist metal,glass 30 + + # area capacitance atto-farads/lambda**2 */ + areacap poly,efet,dfet 200 + areacap metal,glass 120 + areacap diff 400 + areacap bc 600 + areacap dmc/poly 520 + areacap pmc/poly 320 + + # sidewall capacitance atto-farads/lambda */ + perimc diff,dmc/poly,bc space,dfet,efet 200 + + # transistors terms #terms name substr gs-cap gc-cap */ + fet efet diff 2 efet GND! 0 0 + fet dfet diff,bc 2 dfet GND! 0 0 + fet dcap diff,bc 1 dcap GND! 0 0 +# End of style "default" */ +end + +# Information for the wiring interface */ +wiring + contact pmc 4 metal 0 poly 0 + contact dmc 4 metal 0 diff 0 + contact bc 2 poly 0 diff 0 +end + +# Information to control the router */ +router + layer1 metal 3 metal,pmc/metal,dmc/metal,glass 3 + layer2 poly 2 poly,efet,dfet,dcap,pmc,bc 2 diff,dmc 1 + contacts pmc 4 + gridspacing 7 +end + +# Information for plowing */ +plowing + fixed efet,dfet,dcap,bc,glass + covered efet,dfet,dcap,bc + drag efet,dfet,dcap,bc +end + +plot + style versatec + + # Same as Gremlin stipple 9: */ + dfet,dcap \ + 07c0 0f80 1f00 3e00 \ + 7c00 f800 f001 e003 \ + c007 800f 001f 003e \ + 00c7 00f8 01f0 03e0 + + # Same as Gremlin stipple 10: */ + efet,dcap \ + 1f00 0f80 07c0 03e0 \ + 01f0 00f8 007c 003e \ + 001f 800f c007 e003 \ + f001 f800 7c00 3e00 + + # Same as Gremlin stipple 11: */ + bc \ + c3c3 c3c3 0000 0000 \ + 0000 0000 c3c3 c3c3 \ + c3c3 c3c3 0000 0000 \ + 0000 0000 c3c3 c3c3 + + # Same as Gremlin stipple 12: */ + glass \ + 0040 0080 0100 0200 \ + 0400 0800 1000 2000 \ + 4000 8000 0001 0002 \ + 0004 0008 0010 0020 + + # Same as Gremlin stipple 17: */ + diff,dmc/active,efet,dfet,dcap,bc \ + 0000 4242 6666 0000 \ + 0000 2424 6666 0000 \ + 0000 4242 6666 0000 \ + 0000 2424 6666 0000 + + # Same as Gremlin stipple 19: */ + poly,pmc/active,efet,dfet,dcap,bc \ + 0808 0400 0202 0101 \ + 8080 4000 2020 1010 \ + 0808 0004 0202 0101 \ + 8080 0040 2020 1010 + + # Same as Gremlin stipple 22: */ + metal,dmc/metal,pmc/metal,glass \ + 8080 0000 0000 0000 \ + 0808 0000 0000 0000 \ + 8080 0000 0000 0000 \ + 0808 0000 0000 0000 + + # Same as Gremlin stipple 23: */ + glass \ + 0000 0000 1c1c 3e3e \ + 3636 3e3e 1c1c 0000 \ + 0000 0000 1c1c 3e3e \ + 3636 3e3e 1c1c 0000 + + pmc,dmc X + bc B + + style gremlin + dfet,dcap 9 + efet,dcap 10 + bc 11 + glass 12 + diff,dmc/active,efet,dfet,dcap,bc 17 + poly,pmc/active,efet,dfet,dcap,bc 19 + metal,dmc,pmc,glass 22 + pmc,dmc X + bc B +end diff --git a/scripts/config.guess b/scripts/config.guess old mode 100755 new mode 100644 index dc84c68e..7f748177 --- a/scripts/config.guess +++ b/scripts/config.guess @@ -1,14 +1,12 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -# Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. -timestamp='2009-11-20' +timestamp='2020-12-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -17,35 +15,31 @@ timestamp='2009-11-20' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). # -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . -me=`echo "$0" | sed -e 's,.*/,,'` + +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -56,8 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -91,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -103,48 +94,92 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown +UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown +UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown +UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + EOF + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -154,21 +189,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)) + case "$UNAME_MACHINE_ARCH" in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + earmv*) + arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') + endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -180,7 +226,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release @@ -188,105 +241,125 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "$machine-${os}${release}${abi-}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + *:OS108:*:*) + echo "$UNAME_MACHINE"-unknown-os108_"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Twizzler:*:*) + echo "$UNAME_MACHINE"-unknown-twizzler + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; + echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -295,12 +368,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo s390-ibm-zvmoe exit ;; *:OS400:*:*) - echo powerpc-ibm-os400 + echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) + arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) @@ -308,7 +381,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then + if test "$( (/bin/universe) 2>/dev/null)" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd @@ -321,69 +394,69 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in + case $(/usr/bin/uname -p) in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" + set_cc_for_build + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case "$(/usr/bin/arch -k)" in Series*|S4*) - UNAME_RELEASE=`uname -v` + UNAME_RELEASE=$(uname -v) ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in + UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "$(/bin/arch)" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -394,44 +467,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -440,23 +513,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && + SYSTEM_NAME=$("$dummy" "$dummyarg") && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -480,21 +553,21 @@ EOF echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=$(/usr/bin/uname -p) + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi - exit ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; @@ -509,26 +582,26 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/oslevel ; then + IBM_REV=$(/usr/bin/oslevel) else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -539,7 +612,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") then echo "$SYSTEM_NAME" else @@ -551,28 +624,29 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[456]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + *:AIX:*:[4567]) + IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/lslpp ; then + IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -587,67 +661,67 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + if test -x /usr/bin/getconf; then + sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) + sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if test "$HP_ARCH" = hppa2.0w then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -658,23 +732,23 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -699,11 +773,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -712,17 +786,17 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + if test -x /usr/sbin/sysversion ; then + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -730,135 +804,140 @@ EOF exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=$(uname -p) + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf + fi exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=$(/usr/bin/uname -p) + case "$UNAME_PROCESSOR" in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -866,115 +945,184 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac + esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo cris-axis-linux-gnu + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo frv-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -983,56 +1131,56 @@ EOF echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 @@ -1040,20 +1188,20 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp - exit ;; + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1062,9 +1210,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1082,41 +1230,41 @@ EOF 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1126,16 +1274,16 @@ EOF exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1147,25 +1295,25 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + if test -d /usr/nec; then + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1178,63 +1326,101 @@ EOF BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + UNAME_PROCESSOR=$(uname -p) case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=$(uname -p) + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1243,18 +1429,19 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + # shellcheck disable=SC2154 + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1275,14 +1462,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + UNAME_MACHINE=$( (uname -p) 2>/dev/null) + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1291,24 +1478,39 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" exit ;; esac -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < "$dummy.c" < -# include +#include +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif #endif main () { @@ -1321,28 +1523,20 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else @@ -1376,39 +1570,54 @@ main () #endif #if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); + struct utsname un; + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif #endif #if defined (alliant) && defined (i860) @@ -1419,82 +1628,73 @@ main () } EOF -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } +echo "$0: unable to guess system type" >&2 -# Convex versions that predate uname can use getsysinfo(1) +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +year=$(echo $timestamp | sed 's,-.*,,') +# shellcheck disable=SC2003 +if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then + cat >&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` +uname -m = $( (uname -m) 2>/dev/null || echo unknown) +uname -r = $( (uname -r) 2>/dev/null || echo unknown) +uname -s = $( (uname -s) 2>/dev/null || echo unknown) +uname -v = $( (uname -v) 2>/dev/null || echo unknown) -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) +/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +hostinfo = $( (hostinfo) 2>/dev/null) +/bin/universe = $( (/bin/universe) 2>/dev/null) +/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) +/bin/arch = $( (/bin/arch) 2>/dev/null) +/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) +/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/scripts/config.sub b/scripts/config.sub old mode 100755 new mode 100644 index 12ebc787..90bb8aed --- a/scripts/config.sub +++ b/scripts/config.sub @@ -1,33 +1,29 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. +# Copyright 1992-2020 Free Software Foundation, Inc. -timestamp='2001-08-13' +timestamp='2020-12-22' -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - +# along with this program; if not, see . +# # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + # Please send patches to . # @@ -36,6 +32,9 @@ timestamp='2001-08-13' # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. @@ -51,15 +50,14 @@ timestamp='2001-08-13' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -69,8 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. +Copyright 1992-2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -82,23 +79,23 @@ Try \`$me --help' for more information." while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; + echo "$timestamp" ; exit ;; --version | -v ) - echo "$version" ; exit 0 ;; + echo "$version" ; exit ;; --help | --h* | -h ) - echo "$usage"; exit 0 ;; + echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 - exit 0;; + echo "$1" + exit ;; * ) break ;; @@ -113,911 +110,1169 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -scout) + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dsp16xx \ - | fr30 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el | mips64vr4300 \ - | mips64vr4300el | mips64vr5000 | mips64vr5000el \ - | mipsbe | mipsel | mipsle | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ns16k | ns32k \ - | openrisc \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | s390 | s390x \ - | sh | sh[34] | sh[34]eb | shbe | shle \ - | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 \ - | we32k \ - | x86 | xscale \ - | z8k) - basic_machine=$basic_machine-unknown + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none + op50n) + cpu=hppa1.1 + vendor=oki ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=$(echo "$1" | sed -e 's/86.*/86/') + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=$(echo "$basic_machine" | sed 's/-.*//') + ;; + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 + cpu=$basic_machine + vendor=pc ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alphapca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armv*-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ - | clipper-* | cray2-* | cydra-* \ - | d10v-* | d30v-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | m32r-* \ - | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipsel-* \ - | mipsle-* | mipstx39-* | mipstx39el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | s390-* | s390x-* \ - | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \ - | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ - | v850-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \ - | ymp-* \ - | z8k-*) + # These rules are duplicated from below for sake of the special case above; + # i.e. things that normalized to x86 arches should also default to "pc" + pc98) + cpu=i386 + vendor=pc ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd + x64 | amd64) + cpu=x86_64 + vendor=pc ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + # Recognize the basic CPU types without company name. + *) + cpu=$basic_machine + vendor=unknown ;; - 3b*) - basic_machine=we32k-att +esac + +unset -v basic_machine + +# Decode basic machines in the full and proper CPU-Company form. +case $cpu-$vendor in + # Here we handle the default manufacturer of certain CPU types in canonical form. It is in + # some cases the only manufacturer, in others, it is the most popular. + craynv-unknown) + vendor=cray + basic_os=${basic_os:-unicosmp} ;; - a29khif) - basic_machine=a29k-amd - os=-udi + c90-unknown | c90-cray) + vendor=cray + basic_os=${Basic_os:-unicos} ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout + fx80-unknown) + vendor=alliant ;; - alliant | fx80) - basic_machine=fx80-alliant + romp-unknown) + vendor=ibm ;; - altos | altos3068) - basic_machine=m68k-altos + mmix-unknown) + vendor=knuth ;; - am29k) - basic_machine=a29k-none - os=-bsd + microblaze-unknown | microblazeel-unknown) + vendor=xilinx ;; - amdahl) - basic_machine=580-amdahl - os=-sysv + rs6000-unknown) + vendor=ibm ;; - amiga | amiga-*) - basic_machine=m68k-unknown + vax-unknown) + vendor=dec ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos + pdp11-unknown) + vendor=dec ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 + we32k-unknown) + vendor=att ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv + cydra-unknown) + vendor=cydrome ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd + i370-ibm*) + vendor=ibm ;; - aux) - basic_machine=m68k-apple - os=-aux + orion-unknown) + vendor=highlevel ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | ymp) - basic_machine=ymp-cray - os=-unicos - ;; - cray2) - basic_machine=cray2-cray - os=-unicos - ;; - [cjt]90) - basic_machine=${basic_machine}-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mipsel*-linux*) - basic_machine=mipsel-unknown - os=-linux-gnu - ;; - mips*-linux*) - basic_machine=mips-unknown - os=-linux-gnu - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=t3e-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; - xmp) - basic_machine=xmp-cray - os=-unicos - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none + xps-unknown | xps100-unknown) + cpu=xps100 + vendor=honeywell ;; -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond + # Here we normalize CPU types with a missing or matching vendor + dpx20-unknown | dpx20-bull) + cpu=rs6000 + vendor=bull + basic_os=${basic_os:-bosx} ;; - op50n) - basic_machine=hppa1.1-oki + + # Here we normalize CPU types irrespective of the vendor + amd64-*) + cpu=x86_64 ;; - op60c) - basic_machine=hppa1.1-oki + blackfin-*) + cpu=bfin + basic_os=linux ;; - mips) - if [ x$os = x-linux-gnu ]; then - basic_machine=mips-unknown - else - basic_machine=mips-mips - fi + c54x-*) + cpu=tic54x ;; - romp) - basic_machine=romp-ibm + c55x-*) + cpu=tic55x ;; - rs6000) - basic_machine=rs6000-ibm + c6x-*) + cpu=tic6x ;; - vax) - basic_machine=vax-dec + e500v[12]-*) + cpu=powerpc + basic_os=${basic_os}"spe" ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown + mips3*-*) + cpu=mips64 ;; - pdp11) - basic_machine=pdp11-dec + ms1-*) + cpu=mt ;; - we32k) - basic_machine=we32k-att + m68knommu-*) + cpu=m68k + basic_os=linux ;; - sh3 | sh4 | sh3eb | sh4eb) - basic_machine=sh-unknown + m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) + cpu=s12z ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun + openrisc-*) + cpu=or32 ;; - cydra) - basic_machine=cydra-cydrome + parisc-*) + cpu=hppa + basic_os=linux ;; - orion) - basic_machine=orion-highlevel + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + cpu=i586 ;; - orion105) - basic_machine=clipper-highlevel + pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*) + cpu=i686 ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + cpu=i686 ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple + pentium4-*) + cpu=i786 ;; - c4x*) - basic_machine=c4x-none - os=-coff + pc98-*) + cpu=i386 ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. + ppc-* | ppcbe-*) + cpu=powerpc ;; + ppcle-* | powerpclittle-*) + cpu=powerpcle + ;; + ppc64-*) + cpu=powerpc64 + ;; + ppc64le-* | powerpc64little-*) + cpu=powerpc64le + ;; + sb1-*) + cpu=mipsisa64sb1 + ;; + sb1el-*) + cpu=mipsisa64sb1el + ;; + sh5e[lb]-*) + cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/') + ;; + spur-*) + cpu=spur + ;; + strongarm-* | thumb-*) + cpu=arm + ;; + tx39-*) + cpu=mipstx39 + ;; + tx39el-*) + cpu=mipstx39el + ;; + x64-*) + cpu=x86_64 + ;; + xscale-* | xscalee[bl]-*) + cpu=$(echo "$cpu" | sed 's/^xscale/arm/') + ;; + arm64-*) + cpu=aarch64 + ;; + + # Recognize the canonical CPU Types that limit and/or modify the + # company names they are paired with. + cr16-*) + basic_os=${basic_os:-elf} + ;; + crisv32-* | etraxfs*-*) + cpu=crisv32 + vendor=axis + ;; + cris-* | etrax*-*) + cpu=cris + vendor=axis + ;; + crx-*) + basic_os=${basic_os:-elf} + ;; + neo-tandem) + cpu=neo + vendor=tandem + ;; + nse-tandem) + cpu=nse + vendor=tandem + ;; + nsr-tandem) + cpu=nsr + vendor=tandem + ;; + nsv-tandem) + cpu=nsv + vendor=tandem + ;; + nsx-tandem) + cpu=nsx + vendor=tandem + ;; + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony + ;; + tile*-*) + basic_os=${basic_os:-linux-gnu} + ;; + *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1025,158 +1280,213 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if test x$basic_os != x then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') + ;; + os2-emx) + kernel=os2 + os=$(echo $basic_os | sed -e 's|os2-emx|emx|') + ;; + nto-qnx*) + kernel=nto + os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1189,221 +1499,356 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in + score-*) + os=elf + ;; + spu-*) + os=elf + ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; + c4x-* | tic4x-*) + os=coff + ;; + c8051-*) + os=elf + ;; + clipper-intergraph) + os=clix + ;; + hexagon-*) + os=elf + ;; + tic54x-*) + os=coff + ;; + tic55x-*) + os=coff + ;; + tic6x-*) + os=coff + ;; + # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; - pdp11-*) - os=-none + pdp11-*) + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout + ;; + mep-*) + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf + ;; + or32-*) + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 + ;; + pru-*) + os=elf ;; *-be) - os=-beos + os=beos ;; *-ibm) - os=-aix + os=aix + ;; + *-knuth) + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs + os=luna ;; *-next) - os=-nextstep3 + os=nextstep ;; - *-gould) - os=-sysv + *-sequent) + os=ptx ;; - *-highlevel) - os=-bsd + *-crds) + os=unos + ;; + *-ns) + os=genix + ;; + i370-*) + os=mvs + ;; + *-gould) + os=sysv + ;; + *-highlevel) + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; - *-sgi) - os=-irix + *-sgi) + os=irix ;; - *-siemens) - os=-sysv4 + *-siemens) + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-abi", so those need to count as OSes. + musl* | newlib* | uclibc*) + ;; + # Likewise for "kernel-libc" + eabi | eabihf | gnueabi | gnueabihf) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) vendor=ibm ;; - -ptx*) + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) vendor=sequent ;; - -vxsim* | -vxworks*) + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os -exit 0 +echo "$cpu-$vendor-${kernel:+$kernel-}$os" +exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/scripts/configure b/scripts/configure index a2d9cb28..5b4fc516 100755 --- a/scripts/configure +++ b/scripts/configure @@ -626,8 +626,6 @@ INSTALL_TARGET ALL_TARGET OA_LIBS OA -MAGIC_REVISION -MAGIC_VERSION MSED MCPP LD_RUN_PATH @@ -2597,17 +2595,6 @@ test -n "$target_alias" && PACKAGE=magic -MAGIC_VERSION=`cat ../VERSION | cut -d. -f1-2` -MAGIC_REVISION=`cat ../VERSION | cut -d. -f3` -cat >>confdefs.h <<_ACEOF -#define MAGIC_VERSION "${MAGIC_VERSION}" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define MAGIC_REVISION "${MAGIC_REVISION}" -_ACEOF - - ALL_TARGET="standard" INSTALL_TARGET="install-magic" @@ -8227,9 +8214,6 @@ fi - - - diff --git a/scripts/configure.in b/scripts/configure.in index 8a00ba27..c21f79b0 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -11,11 +11,6 @@ AC_CANONICAL_SYSTEM dnl pass the version string on the the makefiles PACKAGE=magic -MAGIC_VERSION=`cat ../VERSION | cut -d. -f1-2` -MAGIC_REVISION=`cat ../VERSION | cut -d. -f3` -AC_DEFINE_UNQUOTED(MAGIC_VERSION, "${MAGIC_VERSION}") -AC_DEFINE_UNQUOTED(MAGIC_REVISION, "${MAGIC_REVISION}") - dnl Override default target when compiling under TCL ALL_TARGET="standard" INSTALL_TARGET="install-magic" @@ -407,6 +402,8 @@ AC_ARG_WITH(tcllibs, [ --with-tcllibs=DIR Find Tcl library in DIR], magic_with_tcl_libraries=$withval) AC_ARG_WITH(tklibs, [ --with-tklibs=DIR Find Tk library in DIR], magic_with_tk_libraries=$withval) +AC_ARG_WITH(wish, [ --with-wish=EXE Use wish binary at EXE], + magic_with_wish_binary=$withval) # ----------------------------------------------------------------------- # Find the Tcl build configuration file "tclConfig.sh" @@ -709,33 +706,37 @@ if test $usingTcl ; then # Find the version of "wish" that corresponds to TCL_EXEC_PREFIX # We really ought to run "ldd" to confirm that the linked libraries match. - AC_MSG_CHECKING([for wish executable]) - for dir in \ - ${TK_EXEC_PREFIX}/bin \ - ${TK_EXEC_PREFIX} - do - for wishexe in \ - wish-X11 \ - wish \ - wish${TK_VERSION} \ - wish.exe \ - wish${TK_VERSION}.exe + if text "x${magic_with_wish_binary}" = "x" ; then + AC_MSG_CHECKING([for wish executable]) + for dir in \ + ${TK_EXEC_PREFIX}/bin \ + ${TK_EXEC_PREFIX} do - if test -r "$dir/$wishexe" ; then - WISH_EXE=$dir/$wishexe + for wishexe in \ + wish-X11 \ + wish \ + wish${TK_VERSION} \ + wish.exe \ + wish${TK_VERSION}.exe + do + if test -r "$dir/$wishexe" ; then + WISH_EXE=$dir/$wishexe + break + fi + done + if test "x${WISH_EXE}" != "x" ; then break fi done - if test "x${WISH_EXE}" != "x" ; then - break + if test "x${WISH_EXE}" = "x" ; then + echo "Warning: Can't find executable for \"wish\". You may have to" + echo "manually set the value for WISH_EXE in the magic startup script." + AC_MSG_RESULT(no) + else + AC_MSG_RESULT([${WISH_EXE}]) fi - done - if test "x${WISH_EXE}" = "x" ; then - echo "Warning: Can't find executable for \"wish\". You may have to" - echo "manually set the value for WISH_EXE in the magic startup script." - AC_MSG_RESULT(no) else - AC_MSG_RESULT([${WISH_EXE}]) + WISH_EXE=${magic_with_wish_binary} fi # Find the version of "tclsh" that corresponds to TCL_EXEC_PREFIX @@ -1800,9 +1801,6 @@ AC_SUBST(LD_RUN_PATH) AC_SUBST(MCPP) AC_SUBST(MSED) -AC_SUBST(MAGIC_VERSION) -AC_SUBST(MAGIC_REVISION) - AC_SUBST(OA) AC_SUBST(OA_LIBS) diff --git a/scripts/defs.mak.in b/scripts/defs.mak.in index 45d65f53..77dfddca 100755 --- a/scripts/defs.mak.in +++ b/scripts/defs.mak.in @@ -68,15 +68,15 @@ LIB_SPECS = @LIB_SPECS@ LIB_SPECS_NOSTUB = @LIB_SPECS_NOSTUB@ WISH_EXE = @WISH_EXE@ TCL_LIB_DIR = @TCL_LIB_DIR@ -MAGIC_VERSION = @MAGIC_VERSION@ -MAGIC_REVISION = @MAGIC_REVISION@ +MAGIC_VERSION = `cat ../VERSION | cut -d. -f1-2` +MAGIC_REVISION = `cat ../VERSION | cut -d. -f3` CC = @CC@ CPP = @CPP@ CXX = @CXX@ CPPFLAGS = -I. -I${MAGICDIR} @CPPFLAGS@ -DFLAGS = @extra_defs@ @stub_defs@ @DEFS@ -DGCORE=\"@GCORE@\" +DFLAGS = @extra_defs@ @stub_defs@ @DEFS@ -DMAGIC_VERSION=\"${MAGIC_VERSION}\" -DMAGIC_REVISION=\"${MAGIC_REVISION}\" -DGCORE=\"@GCORE@\" DFLAGS += -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG DFLAGS_NOSTUB = @extra_defs@ @DEFS@ -DGCORE=\"@GCORE@\" DFLAGS_NOSTUB += -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG diff --git a/tcltk/Makefile b/tcltk/Makefile index 5f2305d5..97f214ad 100644 --- a/tcltk/Makefile +++ b/tcltk/Makefile @@ -5,6 +5,7 @@ MODULE = tcltk MAGICDIR = .. SRCS = tclmagic.c +OBJS = $(subst .c,.o,${SRCS}) include ${MAGICDIR}/defs.mak @@ -58,11 +59,10 @@ magicdnull: magicdnull.c ${MAGICDIR}/defs.mak -o magicdnull ${LD_RUN_PATH} ${LIB_SPECS_NOSTUB} ${LIBS} \ ${GR_LIBS} -magic.tcl: magic.tcl.in ${MAGICDIR}/defs.mak - sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ - -e /MAGIC_VERSION/s%MAGIC_VERSION%${MAGIC_VERSION}%g \ +magic.tcl: magic.tcl.in ${MAGICDIR}/defs.mak ${MAGICDIR}/VERSION + sed -e /MAGIC_VERSION/s%MAGIC_VERSION%${MAGIC_VERSION}%g \ -e /MAGIC_REVISION/s%MAGIC_REVISION%${MAGIC_REVISION}%g \ - -e /SHDLIB_EXT/s%SHDLIB_EXT%${SHDLIB_EXT}%g magic.tcl.in > magic.tcl + magic.tcl.in > magic.tcl magic.sh: magic.sh.in ${MAGICDIR}/defs.mak sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ @@ -70,10 +70,12 @@ magic.sh: magic.sh.in ${MAGICDIR}/defs.mak -e /WISH_EXE/s%WISH_EXE%${WISH_EXE}%g magic.sh.in > magic.sh ext2spice.sh: ext2spice.sh.in ${MAGICDIR}/defs.mak - sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g ext2spice.sh.in > ext2spice.sh + sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ + ext2spice.sh.in > ext2spice.sh ext2sim.sh: ext2sim.sh.in ${MAGICDIR}/defs.mak - sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g ext2sim.sh.in > ext2sim.sh + sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ + ext2sim.sh.in > ext2sim.sh $(DESTDIR)${INSTALL_TCLDIR}/%: % ${RM} $(DESTDIR)${INSTALL_TCLDIR}/$* @@ -94,4 +96,7 @@ $(DESTDIR)${INSTALL_BINDIR}/ext2sim.sh: ext2sim.sh ${CP} ext2sim.sh $(DESTDIR)${INSTALL_BINDIR}/ext2sim (cd $(DESTDIR)${INSTALL_BINDIR}; chmod 0755 ext2sim) +# An additional dependency on the VERSION file +${OBJS}: ${MAGICDIR}/VERSION + include ${MAGICDIR}/rules.mak diff --git a/tcltk/ext2sim.sh.in b/tcltk/ext2sim.sh.in index 548657ae..d0740098 100755 --- a/tcltk/ext2sim.sh.in +++ b/tcltk/ext2sim.sh.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Standalone script for ext2sim, for Tcl-based magic 8.0 # @@ -14,8 +14,12 @@ for i in $@; do *) esargs="$esargs $i" ;; esac done +TCL_MAG_DIR=${CAD_ROOT}/magic/tcl +if [ "${TCL_MAG_DIR}" = "/magic/tcl" ]; then + TCL_MAG_DIR=TCL_DIR +fi # -eval TCL_DIR/magicdnull -dnull -noconsole -nowrapper $mgargs <= 8.6} { - load -lazy TCL_DIR/tclmagicSHDLIB_EXT + load -lazy [file join $MAGIC_TCL_DIR tclmagic[info sharedlibextension]] } else { - load TCL_DIR/tclmagicSHDLIB_EXT + load [file join $MAGIC_TCL_DIR tclmagic[info sharedlibextension]] } # It is important to make sure no magic commands overlap with Tcl built-in @@ -30,8 +31,8 @@ proc pushnamespace { name } { foreach v $y { regsub -all {\*} $v {\\*} i set x [namespace tail $i] - if {[lsearch $z $x] < 0} { - namespace import $i + if {[lsearch $z $x] < 0} { + namespace import $i } } } @@ -124,7 +125,7 @@ proc xcircuit { args } { # execute script in the scope of magic, because its variable space is # not modularized. set argv $args - set argc [llength $args] + set argc [llength $args] uplevel #0 source $xcircscript } } @@ -143,7 +144,7 @@ proc netgen { args } { puts stderr "\"source /netgen.tcl\"." } else { set argv $args - set argc [llength $args] + set argc [llength $args] uplevel #0 source $netgenscript } } @@ -151,7 +152,7 @@ proc netgen { args } { # Add the "echo" command proc echo {args} { - puts stdout $args + puts stdout $args } # Parse argument list for "-c[onsole]" and "-now[rapper]". diff --git a/tcltk/tclmagic.c b/tcltk/tclmagic.c index f039b875..974f94b2 100644 --- a/tcltk/tclmagic.c +++ b/tcltk/tclmagic.c @@ -1191,7 +1191,7 @@ int Tclmagic_Init(interp) Tcl_Interp *interp; { - char *cadroot; + const char *cadroot; /* Sanity check! */ if (interp == NULL) return TCL_ERROR; @@ -1221,12 +1221,18 @@ Tclmagic_Init(interp) Tcl_Eval(interp, "lappend auto_path " TCL_DIR ); - /* Set $CAD_ROOT as a Tcl variable */ + /* Get $CAD_ROOT from a Tcl variable, if it exists, and if not, then */ + /* set CAD_ROOT from the environment variable of the same name, if */ + /* it exists, and finally fall back on the CAD_DIR set at compile */ + /* time. */ - cadroot = getenv("CAD_ROOT"); - if (cadroot == NULL) cadroot = CAD_DIR; - - Tcl_SetVar(interp, "CAD_ROOT", cadroot, TCL_GLOBAL_ONLY); + cadroot = Tcl_GetVar(interp, "CAD_ROOT", TCL_GLOBAL_ONLY); + if (cadroot == NULL) + { + cadroot = (const char *)getenv("CAD_ROOT"); + if (cadroot == NULL) cadroot = CAD_DIR; + Tcl_SetVar(interp, "CAD_ROOT", cadroot, TCL_GLOBAL_ONLY); + } Tcl_PkgProvide(interp, "Tclmagic", MAGIC_VERSION); return TCL_OK; diff --git a/utils/path.c b/utils/path.c index cce6896f..d63659c4 100644 --- a/utils/path.c +++ b/utils/path.c @@ -119,7 +119,7 @@ PaExpand(psource, pdest, size) { char *ps, *pd; struct passwd *passwd, *getpwnam(); - char expandName[100], *string, *newEntry; + char expandName[512], *string, *newEntry; HashEntry *h; int i, length; @@ -135,7 +135,7 @@ PaExpand(psource, pdest, size) *pd = *++ps; if (isspace(*pd) || (*pd=='\0') || (*pd=='/') || (*pd==':')) break; - if (i < 99) pd++; + if (i < 511) pd++; } *pd = '\0'; @@ -196,7 +196,7 @@ PaExpand(psource, pdest, size) *pd = *++ps; if (isspace(*pd) || (*pd=='\0') || (*pd=='/') || (*pd==':')) break; - if (i < 99) pd++; + if ((i < 511) && (*pd != '{') && (*pd != '}')) pd++; } saveChar = *pd; *pd = '\0'; @@ -226,7 +226,11 @@ PaExpand(psource, pdest, size) if (string == NULL) { /* Check for CAD_ROOT = CAD_DIR, the only internal variable */ - /* recognized (this is passed down from the Makefile) */ + /* recognized (this is passed down from the Makefile). */ + /* Note that in the MAGIC_WRAPPER version, CAD_ROOT was set */ + /* as a Tcl variable in tcltk/tclmagic.c, such that if */ + /* expandName == "CAD_ROOT", then string should not be NULL */ + /* here. */ if (!strcmp(expandName, "CAD_ROOT")) string = CAD_DIR; diff --git a/utils/tech.c b/utils/tech.c index e64caacf..6b58cd51 100644 --- a/utils/tech.c +++ b/utils/tech.c @@ -272,9 +272,12 @@ changePlanesFunc(cellDef, arg) /* Old planes to be subtracted */ for (pNum = DBNumPlanes; pNum < oldnumplanes; pNum++) { - DBFreePaintPlane(cellDef->cd_planes[pNum]); - TiFreePlane(cellDef->cd_planes[pNum]); - cellDef->cd_planes[pNum] = (Plane *) NULL; + if (cellDef->cd_planes[pNum] != NULL) + { + DBFreePaintPlane(cellDef->cd_planes[pNum]); + TiFreePlane(cellDef->cd_planes[pNum]); + cellDef->cd_planes[pNum] = (Plane *) NULL; + } } } return 0;