From e55c1ecbdae1d0545a684d33a97f35ab6881f6d9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 17 Jun 2021 12:40:21 -0400 Subject: [PATCH] Corrected issues with GDS write that come from two features recently introduced: The use of substitutions for PDKPATH and home directory in path names for GDS files referenced in abstract views, and the "gds addendum" option. Both were interfering with magic's handling of writing GDS files from abstract layout views. --- VERSION | 2 +- calma/CalmaWrite.c | 112 ++++++++++++++++++++++++++++++++++++------ database/DBcellname.c | 5 +- 3 files changed, 100 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 8975ef2d..281008b3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.179 +8.3.180 diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index de67873b..5e895d95 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c #include #include #include +#include /* for htons() */ #ifdef SYSV #include #else @@ -146,6 +147,7 @@ int calmaPaintLayerType; */ HashTable calmaLibHash; HashTable calmaPrefixHash; +HashTable calmaUndefHash; /* Imports */ extern time_t time(); @@ -285,6 +287,8 @@ CalmaWrite(rootDef, f) int oldCount = DBWFeedbackCount, problems; bool good; CellUse dummy; + HashEntry *he; + HashSearch hs; /* * Do not attempt to write anything if a CIF/GDS output style @@ -298,6 +302,7 @@ CalmaWrite(rootDef, f) HashInit(&calmaLibHash, 32, 0); HashInit(&calmaPrefixHash, 32, 0); + HashInit(&calmaUndefHash, 32, 0); /* * Make sure that the entire hierarchy rooted at rootDef is @@ -355,6 +360,22 @@ CalmaWrite(rootDef, f) HashFreeKill(&calmaLibHash); HashKill(&calmaPrefixHash); + + /* + * Check for any cells that were instanced in the output definition + * (by dumping a GDS file from a read-only view) but were never + * defined (because the dumped GDS contained undefined references). + */ + HashStartSearch(&hs); + while ((he = HashNext(&calmaUndefHash, &hs)) != NULL) + { + char *refname = (char *)HashGetValue(he); + if (refname && (refname[0] == '0')) + TxError("Error: Cell %s is not defined in the output file!\n", + refname + 1); + } + + HashFreeKill(&calmaUndefHash); return (good); } @@ -409,14 +430,47 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) calmaOutDate(def->cd_timestamp, outf); calmaOutDate(time((time_t *) 0), outf); - /* Find the structure's unique prefix, in case structure calls subcells */ - /* that are not yet defined. */ + /* Do a quick check of the calmaUndefHash table to see if this cell */ + /* was previously used in a GDS file that does not define it (a GDS */ + /* addendum library). */ - he2 = HashFind(&calmaLibHash, filename); - if (he2 == NULL) - TxError("Fatal error: Library %s not recorded!\n", filename); + he = HashLookOnly(&calmaUndefHash, strname); + if (he != NULL) + { + HashSearch hs; + char *undefname = (char *)HashGetValue(he); + + HashStartSearch(&hs); + while ((he2 = HashNext(&calmaLibHash, &hs)) != NULL) + { + prefix = (char *)HashGetValue(he2); + if (!strncmp(prefix, undefname + 1, strlen(prefix))) + break; + } + if (he2 == NULL) + { + prefix = (char *)NULL; + TxError("Error: Unreferenced cell %s prefix is unrecorded!\n", + undefname); + } + else + { + /* Remove this entry from the hash table */ + freeMagic(undefname); + HashRemove(&calmaUndefHash, strname); + } + } else - prefix = (char *)HashGetValue(he2); + { + /* Find the structure's unique prefix, in case structure calls */ + /* subcells that are not yet defined. */ + + he2 = HashFind(&calmaLibHash, filename); + if (he2 == NULL) + TxError("Fatal error: Library %s not recorded!\n", filename); + else + prefix = (char *)HashGetValue(he2); + } /* Prefix structure name with def name, and output new structure name */ he = HashFind(calmaDefHash, strname); @@ -456,16 +510,20 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) if (edef != NULL) { bool isAbstract, isReadOnly; - char *chklibname, *dotptr; + char *chklibname, *filenamesubbed = NULL; /* Is view abstract? */ DBPropGet(edef, "LEFview", &isAbstract); chklibname = (char *)DBPropGet(edef, "GDS_FILE", &isReadOnly); - dotptr = strrchr(filename, '.'); - if (dotptr) *dotptr = '\0'; - /* Is the library name the same as the filename (less extension)? */ - if (isAbstract && isReadOnly && !strcmp(filename, chklibname)) + if (isAbstract && isReadOnly) + { + filenamesubbed = StrDup(NULL, filename); + DBPathSubstitute(filename, filenamesubbed, edef); + } + + /* Is the library name the same as the filename? */ + if (isAbstract && isReadOnly && !strcmp(filenamesubbed, chklibname)) { /* Same library, so keep the cellname and mark the cell */ /* as having been written to GDS. */ @@ -487,7 +545,7 @@ calmaDumpStructure(def, outf, calmaDefHash, filename) HashSetValue(he, (char *)newnameptr); } } - if (dotptr) *dotptr = '.'; + if (filenamesubbed) freeMagic(filenamesubbed); } else { @@ -614,11 +672,12 @@ calmaFullDump(def, fi, outf, filename) char *filename; { int version, rval; - char *libname = NULL, uniqlibname[4]; + char *libname = NULL, *testlib, uniqlibname[4]; char *sptr, *viewopts; bool isAbstract; HashTable calmaDefHash; - HashEntry *he; + HashSearch hs; + HashEntry *he, *he2; static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS, CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE, @@ -645,6 +704,11 @@ calmaFullDump(def, fi, outf, filename) // Record the GDS library so it will not be processed again. he = HashFind(&calmaLibHash, filename); + if ((char *)HashGetValue(he) != NULL) + { + TxPrintf("Library %s has already been processed\n", libname); + return; + } /* If property LEFview is defined as "no_prefix" instead of "TRUE", * then do not create a unique prefix for subcells. This is generally @@ -672,8 +736,6 @@ calmaFullDump(def, fi, outf, filename) */ while (TRUE) { - HashEntry *he2; - rval = random() % 26; rval = 'A' + rval; uniqlibname[0] = (char)(rval & 127); @@ -700,6 +762,24 @@ calmaFullDump(def, fi, outf, filename) calmaSkipExact(CALMA_ENDLIB); done: + + /* Check that all references were resolved. If not, then it is + * probably because a library was an "addendum"-type library + * referencing things in other libraries. Move those cell + * references to the calmaUndefHash before killing calmaDefHash. + */ + + HashStartSearch(&hs); + while ((he = HashNext(&calmaDefHash, &hs)) != NULL) + { + char *refname = (char *)HashGetValue(he); + if (refname[0] == '0') + { + he2 = HashFind(&calmaUndefHash, (char *)he->h_key.h_name); + HashSetValue(he2, StrDup(NULL, refname)); + } + } + HashFreeKill(&calmaDefHash); if (libname != NULL) freeMagic(libname); return; diff --git a/database/DBcellname.c b/database/DBcellname.c index e6ee0b14..a0dd4d80 100644 --- a/database/DBcellname.c +++ b/database/DBcellname.c @@ -1612,8 +1612,9 @@ DBCellLookDef(cellName) { HashEntry *entry; - entry = HashFind(&dbCellDefTable, cellName); - return ((CellDef *) HashGetValue(entry)); + entry = HashLookOnly(&dbCellDefTable, cellName); + if (entry == (HashEntry *)NULL) return (CellDef *)NULL; + return (CellDef *)HashGetValue(entry); }