diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index e69bb386..8ddb065f 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -282,7 +282,7 @@ calmaParseStructure(filename) { static int structs[] = { CALMA_STRCLASS, CALMA_STRTYPE, -1 }; int nbytes, rtype, nsrefs, osrefs, npaths; - char *strname = NULL, newname[CALMANAMELENGTH*2]; + char *strname = NULL; HashEntry *he; int suffix; int mfactor; @@ -327,15 +327,21 @@ calmaParseStructure(filename) } else { + char *newname; + CalmaReadError("Cell \"%s\" was already defined in this file.\n", strname); + newname = (char *)mallocMagic(strlen(strname) + 20); for (suffix = 1; HashGetValue(he) != NULL; suffix++) { (void) sprintf(newname, "%s_%d", strname, suffix); he = HashFind(&calmaDefInitHash, newname); } CalmaReadError("Giving this cell a new name: %s\n", newname); - strncpy(strname, newname, CALMANAMELENGTH*2); + freeMagic(strname); + strname = mallocMagic(strlen(newname) + 1); + strcpy(strname, newname); + freeMagic(newname); } } cifReadCellDef = calmaFindCell(strname, &was_called); diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 0480238f..d3320376 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -372,7 +372,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) char *filename; { int nbytes, rtype; - char *strname = NULL, *newnameptr, newname[CALMANAMELENGTH*2]; + char *strname = NULL, *newnameptr; HashEntry *he, *he2; CellDef *edef; char *prefix = NULL; @@ -1024,7 +1024,7 @@ calmaOutFunc(def, f, cliprect) ((lab->lab_flags & PORT_NUM_MASK) == i)) { calmaWriteLabelFunc(lab, type, f); - break; + /* break; */ /* Do not limit to unique labels! */ } } } @@ -1316,7 +1316,7 @@ calmaOutStructName(type, def, f) CellDef *def; FILE *f; { - char defname[CALMANAMELENGTH+1]; + char *defname; unsigned char c; char *cp; int calmanum; @@ -1341,10 +1341,11 @@ calmaOutStructName(type, def, f) } /* We really should ensure that the new name is unique. . . */ } - if (cp <= def->cd_name + CALMANAMELENGTH) + if ((!(CIFCurStyle->cs_flags & CWF_STRING_LIMIT)) || + (cp <= def->cd_name + CALMANAMELENGTH)) { /* Yes, it's legal: use it */ - (void) strcpy(defname, def->cd_name); + defname = StrDup(NULL, def->cd_name); } else { @@ -1352,12 +1353,14 @@ calmaOutStructName(type, def, f) bad: calmanum = (int) def->cd_client; if (calmanum < 0) calmanum = -calmanum; + defname = (char *)mallocMagic(32); (void) sprintf(defname, "XXXXX%d", calmanum); TxError("Warning: string in output unprintable; changed to \'%s\'\n", defname); } calmaOutStringRecord(type, defname, f); + freeMagic(defname); } /* Added by NP 8/21/2004 */ @@ -2734,7 +2737,7 @@ calmaOutDate(t, f) void calmaOutStringRecord(type, str, f) int type; /* Type of this record (data type is ASCII string) */ - char *str; /* String to be output (<= CALMANAMELENGTH chars) */ + char *str; /* String to be output */ FILE *f; /* Stream file */ { int len; @@ -2759,9 +2762,16 @@ calmaOutStringRecord(type, str, f) * last CALMANAMELENGTH characters (since cell names are more * likely to be unique in the last characters than in the first * characters). + * + * NOTE: GDS format has not used CALMANAMELENGTH restrictions + * for ages. Since this is a 2-byte record, then is it not + * worth checking the 65536 - 4 character limit. The CALMANAMELENGTH + * restriction must be enabled in the cifoutput flags. */ + + if (len & 01) len++; - if (len > CALMANAMELENGTH) + if ((CIFCurStyle->cs_flags & CWF_STRING_LIMIT) && (len > CALMANAMELENGTH)) { TxError("Warning: Cellname %s truncated ", str); TxError("to %s (GDS format limit)\n", str + len - CALMANAMELENGTH); diff --git a/cif/CIFint.h b/cif/CIFint.h index 79564a34..a3a59788 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -297,6 +297,7 @@ typedef struct cifstyle #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_STRING_LIMIT 0x40 /* Use older Calma format character limit */ /* procedures */ diff --git a/cif/CIFtech.c b/cif/CIFtech.c index 9639ea00..9f2f457b 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -994,6 +994,8 @@ CIFTechLine(sectionName, argc, argv) CIFCurStyle->cs_flags |= CWF_SEE_VENDOR; else if (strcmp(argv[i], "no-errors") == 0) CIFCurStyle->cs_flags |= CWF_NO_ERRORS; + else if (strcmp(argv[i], "string-limit") == 0) + CIFCurStyle->cs_flags |= CWF_STRING_LIMIT; } return TRUE; } diff --git a/lef/lefCmd.c b/lef/lefCmd.c index 546988db..0322467a 100644 --- a/lef/lefCmd.c +++ b/lef/lefCmd.c @@ -87,6 +87,11 @@ CmdLef(w, cmd) * the macro other than pin area * immediately surrounding labels. */ + bool recurse = FALSE; /* If TRUE, recurse on all subcells + * during "writeall". By default, + * only the immediate children of the + * top level cell are output. + */ static char *cmdLefOption[] = { @@ -95,7 +100,8 @@ CmdLef(w, cmd) "write [filename] [-tech] write LEF for current cell\n" " write [filename] -hide hide all details other than ports", "writeall write all cells including the top-level cell\n" - " writeall -notop write all subcells of the top-level cell", + " writeall -notop write all children of the top-level cell\n" + " writeall -all recurse on all subcells of the top-level cell", "help print this help information", NULL }; @@ -184,11 +190,13 @@ CmdLef(w, cmd) lefTopCell = FALSE; else if (!strncmp(cmd->tx_argv[i], "-tech", 5)) lefTech = TRUE; + else if (!strncmp(cmd->tx_argv[i], "-all", 4)) + recurse = TRUE; else goto wrongNumArgs; } else goto wrongNumArgs; } - LefWriteAll(selectedUse, lefTopCell, lefTech); + LefWriteAll(selectedUse, lefTopCell, lefTech, recurse); } break; case LEF_WRITE: diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 8c3f7530..2984a2fb 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -1133,10 +1133,11 @@ lefWriteMacro(def, f, scale, hide) */ void -LefWriteAll(rootUse, writeTopCell, lefTech) +LefWriteAll(rootUse, writeTopCell, lefTech, recurse) CellUse *rootUse; bool writeTopCell; bool lefTech; + bool recurse; { CellDef *def, *rootdef; FILE *f; @@ -1155,8 +1156,12 @@ LefWriteAll(rootUse, writeTopCell, lefTech) (void) DBCellSrDefs(0, lefDefInitFunc, (ClientData) 0); /* Recursively visit all defs in the tree and push on stack */ + /* If "recurse" is false, then only the children of the root use */ + /* are pushed (this is the default behavior). */ lefDefStack = StackNew(100); - (void) lefDefPushFunc(rootUse); + if (writeTopCell) + lefDefPushFunc(rootUse, (bool *)NULL); + DBCellEnum(rootUse->cu_def, lefDefPushFunc, (ClientData)&recurse); /* Open the file for output */ @@ -1185,8 +1190,7 @@ LefWriteAll(rootUse, writeTopCell, lefTech) { def->cd_client = (ClientData) 0; if (!SigInterruptPending) - if ((writeTopCell == TRUE) || (def != rootdef)) - lefWriteMacro(def, f, scale); + lefWriteMacro(def, f, scale); } /* End the LEF file */ @@ -1217,8 +1221,9 @@ lefDefInitFunc(def) */ int -lefDefPushFunc(use) +lefDefPushFunc(use, recurse) CellUse *use; + bool *recurse; { CellDef *def = use->cu_def; @@ -1227,7 +1232,8 @@ lefDefPushFunc(use) def->cd_client = (ClientData) 1; StackPush((ClientData) def, lefDefStack); - (void) DBCellEnum(def, lefDefPushFunc, (ClientData) 0); + if (recurse && (*recurse)) + (void) DBCellEnum(def, lefDefPushFunc, (ClientData)recurse); return (0); }