diff --git a/VERSION b/VERSION index c07565a2..adb8ff8e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.101 +8.3.102 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 8a6a6c5d..bc3cb7be 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -291,6 +291,7 @@ calmaParseStructure(filename) 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 */ @@ -359,9 +360,6 @@ calmaParseStructure(filename) 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; @@ -410,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) && (nsrefs == 0)) + { + 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; /* @@ -418,8 +445,8 @@ 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. */ @@ -617,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 diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index ab5457a3..847485fb 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. diff --git a/calma/calma.h b/calma/calma.h index bf411cfa..0762f81a 100644 --- a/calma/calma.h +++ b/calma/calma.h @@ -37,6 +37,7 @@ extern bool CalmaMergeTiles; extern bool CalmaFlattenArrays; extern bool CalmaNoDRCCheck; extern bool CalmaFlattenUses; +extern char **CalmaFlattenUsesByName; extern bool CalmaReadOnly; extern bool CalmaContactArrays; extern bool CalmaPostOrder; diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 3d6d5815..32c9d821 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -94,20 +94,21 @@ 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_NO_STAMP 11 -#define CALMA_NO_DUP 12 -#define CALMA_READ 13 -#define CALMA_READONLY 14 -#define CALMA_RESCALE 15 -#define CALMA_WARNING 16 -#define CALMA_WRITE 17 -#define CALMA_POLYS 18 -#define CALMA_PATHS 19 +#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_WARN_HELP CIF_WARN_END /* undefined by CIF module */ @@ -136,6 +137,7 @@ 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", @@ -350,6 +352,102 @@ CmdCalma(w, cmd) 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: if (cmd->tx_argc == 2) {