From fe8e2299202298b95f708a38cc35fbab00169b6d Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 21 Mar 2020 10:16:33 -0400 Subject: [PATCH 1/4] Corrected the DEF read routine's ROWCOL parsing. It was not treated as an optional argument (which it is), and so defaults were not applied, potentially leading to the wrong number of rows/columns in a generated via if ROWCOL is not present in the DEF file. --- database/DBio.c | 11 +++++------ lef/defRead.c | 3 +++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/database/DBio.c b/database/DBio.c index 77c6ed5b..3bb2afd5 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -1054,23 +1054,22 @@ dbReadOpen(cellDef, name, setFileName, errptr) if (f != NULL) { - if (pptr != NULL) *pptr = '.'; - /* NOTE: May not want to present this as an error, as */ /* it is a common technique to read files from, say, a */ /* LEF file but not save them locally, and then expect */ /* that the layout views will be picked up from */ /* 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); - TxError("The cell exists in the search paths at %s.\n", filename); - TxError("The discovered version will be used.\n"); /* Write the new path to cd_file or else magic will */ /* generate another error later. */ - cellDef->cd_file = 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"); } } @@ -2732,7 +2731,7 @@ DBCellWrite(cellDef, fileName) /* surprises can occur after saving a file as a different */ /* filename. */ - cellDef->cd_file = StrDup(&cellDef->cd_file, realname); + cellDef->cd_file = StrDup(&cellDef->cd_file, fileName); } else if (cellDef->cd_file) { diff --git a/lef/defRead.c b/lef/defRead.c index a62a5099..3b91e14a 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -1220,6 +1220,9 @@ DefReadVias(f, sname, oscale, total) LefEstimate(processed++, total, "vias"); + /* If not otherwise specified, rows and columns default to 1 */ + rows = cols = 1; + /* Get via name */ token = LefNextToken(f, TRUE); if (sscanf(token, "%2047s", vianame) != 1) From 276bf1d78a0edfe5f56cd4d02639201b5e73e3da Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 21 Mar 2020 12:40:35 -0400 Subject: [PATCH 2/4] Corrected a bad error from a few commits ago, probably 198, which can deallocate the cell name and causes all sorts of unexpected and unwanted behavior. --- VERSION | 2 +- calma/CalmaRdcl.c | 2 +- calma/CalmaWrite.c | 2 +- cif/CIFhier.c | 4 ++-- cif/CIFrdcl.c | 2 +- commands/CmdCD.c | 21 +++++++++------------ commands/CmdFI.c | 2 +- commands/CmdSubrs.c | 2 +- database/DBcellname.c | 18 +++++++++--------- database/DBio.c | 4 ++-- dbwind/DBWprocs.c | 6 +++--- drc/DRCcontin.c | 2 +- lef/defRead.c | 2 +- lef/lefRead.c | 2 +- lef/lefWrite.c | 4 ++-- netmenu/NMshowcell.c | 2 +- resis/ResMain.c | 2 +- router/rtrDcmpose.c | 2 +- select/selCreate.c | 4 ++-- 19 files changed, 41 insertions(+), 44 deletions(-) diff --git a/VERSION b/VERSION index ff0ca913..315e3031 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.2.199 +8.2.200 diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index ccbbfb5d..789c7b08 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -1048,7 +1048,7 @@ calmaFindCell(name, was_called) def = DBCellLookDef(name); if (def == NULL) { - def = DBCellNewDef(name, (char *) NULL); + def = DBCellNewDef(name); /* * Tricky point: call DBReComputeBbox here to make SURE diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index a628730f..b610f6bc 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -1416,7 +1416,7 @@ calmaGetContactCell(type, lookOnly) def = DBCellLookDef(contactCellName); if ((def == (CellDef *) NULL) && (lookOnly == FALSE)) { - def = DBCellNewDef(contactCellName, (char *) NULL); + def = DBCellNewDef(contactCellName); def->cd_flags &= ~(CDMODIFIED|CDGETNEWSTAMP); def->cd_flags |= CDAVAILABLE; } diff --git a/cif/CIFhier.c b/cif/CIFhier.c index 21be45e4..f52a80f6 100644 --- a/cif/CIFhier.c +++ b/cif/CIFhier.c @@ -112,7 +112,7 @@ CIFInitCells() CIFTotalDef = DBCellLookDef("__CIF__"); if (CIFTotalDef == (CellDef *) NULL) { - CIFTotalDef = DBCellNewDef ("__CIF__",(char *) NULL); + CIFTotalDef = DBCellNewDef("__CIF__"); ASSERT(CIFTotalDef != (CellDef *) NULL, "cifMakeCell"); DBCellSetAvail(CIFTotalDef); CIFTotalDef->cd_flags |= CDINTERNAL; @@ -124,7 +124,7 @@ CIFInitCells() CIFComponentDef = DBCellLookDef("__CIF2__"); if (CIFComponentDef == (CellDef *) NULL) { - CIFComponentDef = DBCellNewDef ("__CIF2__",(char *) NULL); + CIFComponentDef = DBCellNewDef("__CIF2__"); ASSERT(CIFComponentDef != (CellDef *) NULL, "cifMakeCell"); DBCellSetAvail(CIFComponentDef); CIFComponentDef->cd_flags |= CDINTERNAL; diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index a35797d3..7edc8845 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -273,7 +273,7 @@ cifFindCell(cifNum) def = DBCellLookDef(name); if (def == NULL) { - def = DBCellNewDef(name, (char *) NULL); + def = DBCellNewDef(name); /* Tricky point: call DBReComputeBbox here to make SURE * that the cell has a valid bounding box. Otherwise, diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 86a258c5..31dab6cf 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -896,14 +896,12 @@ CmdCellname(w, cmd) { char *fullpath; fullpath = (char *)mallocMagic(strlen(filepath) + - strlen(cellDef->cd_name) + 6); - sprintf(fullpath, "%s/%s.mag", filepath, cellDef->cd_name); + strlen(cellDef->cd_name) + 2); + sprintf(fullpath, "%s/%s", filepath, cellDef->cd_name); if (cellDef->cd_file != NULL) - { freeMagic(cellDef->cd_file); - cellDef->cd_file = NULL; - } + cellDef->cd_file = fullpath; } } @@ -945,7 +943,7 @@ CmdCellname(w, cmd) newDef = DBCellLookDef(cellname); if (newDef == (CellDef *) NULL) { - newDef = DBCellNewDef(cellname, (char *) NULL); + newDef = DBCellNewDef(cellname); DBCellSetAvail(newDef); } break; @@ -1442,7 +1440,7 @@ CmdCif(w, cmd) paintDef = DBCellLookDef(argv[4]); if (paintDef == (CellDef *)NULL) { - paintDef = DBCellNewDef(argv[4], (char *)NULL); + paintDef = DBCellNewDef(argv[4]); DBCellSetAvail(paintDef); } } @@ -3699,8 +3697,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) if ((cellnameptr = strrchr(cmd->tx_argv[1], '/')) != NULL) { cellnameptr++; - /* Allocate extra space for cellname in case it needs an extension */ - fullpathname = (char *)mallocMagic(strlen(cmd->tx_argv[1]) + 10); + fullpathname = (char *)mallocMagic(strlen(cmd->tx_argv[1]) + 2); strcpy(fullpathname, cmd->tx_argv[1]); } else @@ -3723,7 +3720,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) def = DBCellLookDef(cellnameptr); if (def == (CellDef *) NULL) - def = DBCellNewDef(cellnameptr, (char *) NULL); + def = DBCellNewDef(cellnameptr); if (fullpathname != NULL) { @@ -3749,7 +3746,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) uniqchar++; } TxError("Renaming cell to \"%s\" to avoid conflict.", newcellname); - def = DBCellNewDef(cellnameptr, (char *)NULL); + def = DBCellNewDef(cellnameptr); def->cd_file = StrDup(&def->cd_file, fullpathname); freeMagic(newcellname); } @@ -3777,7 +3774,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) dummy->cu_expandMask = CU_DESCEND_SPECIAL; if (DBIsAncestor(def, EditCellUse->cu_def)) { - TxError("The edit cell is already a desecendant of \"%s\",\n", + TxError("The edit cell is already a descendant of \"%s\",\n", cmd->tx_argv[1]); TxError(" which means that you're trying to create a circular\n"); TxError(" structure. This isn't legal.\n"); diff --git a/commands/CmdFI.c b/commands/CmdFI.c index f50e600e..d1337f3a 100644 --- a/commands/CmdFI.c +++ b/commands/CmdFI.c @@ -1943,7 +1943,7 @@ CmdFlatten(w, cmd) TxError("%s already exists\n",destname); return; } - newdef = DBCellNewDef(destname, (char *) NULL); + newdef = DBCellNewDef(destname); ASSERT(newdef, "CmdFlatten"); DBCellSetAvail(newdef); newuse = DBCellNewUse(newdef, (char *) NULL); diff --git a/commands/CmdSubrs.c b/commands/CmdSubrs.c index 663f917c..4b659f5f 100644 --- a/commands/CmdSubrs.c +++ b/commands/CmdSubrs.c @@ -665,7 +665,7 @@ cmdSaveCell(cellDef, newName, noninteractive, tryRename) } cleanup: - if (fileName != newName) + if ((fileName != newName) && (fileName != cellDef->cd_name)) freeMagic(fileName); return; } diff --git a/database/DBcellname.c b/database/DBcellname.c index 70977881..e403278b 100644 --- a/database/DBcellname.c +++ b/database/DBcellname.c @@ -1245,14 +1245,12 @@ DBCellLookDef(cellName) */ CellDef * -DBCellNewDef(cellName, cellFileName) +DBCellNewDef(cellName) char *cellName; /* Name by which the cell is known */ - char *cellFileName; /* Name of disk file in which the cell - * should be kept when written out. - */ { CellDef *cellDef; HashEntry *entry; + char *dotptr; if (cellName == (char *) NULL) cellName = UNNAMED; @@ -1264,10 +1262,12 @@ DBCellNewDef(cellName, cellFileName) cellDef = DBCellDefAlloc(); HashSetValue(entry, (ClientData) cellDef); cellDef->cd_name = StrDup((char **) NULL, cellName); - if (cellFileName == (char *) NULL) - cellDef->cd_file = cellFileName; - else - cellDef->cd_file = StrDup((char **) NULL, cellFileName); + + /* Strip any .mag extension off of the cell name */ + dotptr = strrchr(cellDef->cd_name, '.'); + if (dotptr && !strcmp(dotptr, ".mag")) *dotptr = '\0'; + + cellDef->cd_file = NULL; return (cellDef); } @@ -2081,7 +2081,7 @@ DBNewYank(yname, pyuse, pydef) *pydef = DBCellLookDef(yname); if (*pydef == (CellDef *) NULL) { - *pydef = DBCellNewDef (yname,(char *) NULL); + *pydef = DBCellNewDef(yname); ASSERT(*pydef != (CellDef *) NULL, "DBNewYank"); DBCellSetAvail(*pydef); (*pydef)->cd_flags |= CDINTERNAL; diff --git a/database/DBio.c b/database/DBio.c index 3bb2afd5..2a556a34 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -859,7 +859,7 @@ DBReadBackup(name) cellDef = DBCellLookDef(rootname); if (cellDef == (CellDef *)NULL) - cellDef = DBCellNewDef(rootname, (char *)NULL); + cellDef = DBCellNewDef(rootname); cellDef->cd_flags &= ~CDNOTFOUND; cellDef->cd_flags |= CDAVAILABLE; @@ -1352,7 +1352,7 @@ badTransform: subCellDef = DBCellLookDef(cellname); if (subCellDef == (CellDef *) NULL) { - subCellDef = DBCellNewDef(cellname, (char *)NULL); + subCellDef = DBCellNewDef(cellname); subCellDef->cd_timestamp = childStamp; /* Make sure rectangle is non-degenerate */ diff --git a/dbwind/DBWprocs.c b/dbwind/DBWprocs.c index 2bf4fca1..b5dca997 100644 --- a/dbwind/DBWprocs.c +++ b/dbwind/DBWprocs.c @@ -328,7 +328,7 @@ DBWloadWindow(window, name, ignoreTech, expand, dereference) newEditDef = DBCellLookDef(UNNAMED); if (newEditDef == (CellDef *) NULL) { - newEditDef = DBCellNewDef(UNNAMED, (char *) NULL); + newEditDef = DBCellNewDef(UNNAMED); DBCellSetAvail(newEditDef); } } @@ -397,7 +397,7 @@ DBWloadWindow(window, name, ignoreTech, expand, dereference) } } if (newEditDef == (CellDef *) NULL) - newEditDef = DBCellNewDef(rootname, (char *) NULL); + newEditDef = DBCellNewDef(rootname); if (dereference) newEditDef->cd_flags |= CDDEREFERENCE; @@ -431,7 +431,7 @@ DBWloadWindow(window, name, ignoreTech, expand, dereference) newEditDef = DBCellLookDef(UNNAMED); if (newEditDef == (CellDef *) NULL) { - newEditDef = DBCellNewDef(UNNAMED, (char *) NULL); + newEditDef = DBCellNewDef(UNNAMED); DBCellSetAvail(newEditDef); } } diff --git a/drc/DRCcontin.c b/drc/DRCcontin.c index 2af43e8d..3555a043 100644 --- a/drc/DRCcontin.c +++ b/drc/DRCcontin.c @@ -345,7 +345,7 @@ DRCInit() DRCdef = DBCellLookDef(DRCYANK); if (DRCdef == (CellDef *) NULL) { - DRCdef = DBCellNewDef (DRCYANK,(char *) NULL); + DRCdef = DBCellNewDef(DRCYANK); ASSERT(DRCdef != (CellDef *) NULL, "DRCInit"); DBCellSetAvail(DRCdef); DRCdef->cd_flags |= CDINTERNAL; diff --git a/lef/defRead.c b/lef/defRead.c index 3b91e14a..8dfe94a4 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -1541,7 +1541,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) /* Before giving up, assume that this cell has a */ /* magic .mag layout file. */ - defMacro = DBCellNewDef(token, (char *)NULL); + defMacro = DBCellNewDef(token); defMacro->cd_flags &= ~CDNOTFOUND; dereference = (defMacro->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; if (!DBCellRead(defMacro, (char *)NULL, TRUE, dereference, NULL)) diff --git a/lef/lefRead.c b/lef/lefRead.c index cbe484ec..ed4433d2 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -572,7 +572,7 @@ lefFindCell(name) def = DBCellLookDef(name); if (def == NULL) { - def = DBCellNewDef(name, (char *)NULL); + def = DBCellNewDef(name); DBReComputeBbox(def); } HashSetValue(h, def); diff --git a/lef/lefWrite.c b/lef/lefWrite.c index ad1cab85..4391d727 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -675,7 +675,7 @@ lefWriteMacro(def, f, scale, hide) lefFlatDef = DBCellLookDef("__lefFlat__"); if (lefFlatDef == (CellDef *)NULL) - lefFlatDef = DBCellNewDef("__lefFlat__", (char *)NULL); + lefFlatDef = DBCellNewDef("__lefFlat__"); DBCellSetAvail(lefFlatDef); lefFlatDef->cd_flags |= CDINTERNAL; @@ -828,7 +828,7 @@ lefWriteMacro(def, f, scale, hide) lc.lefYank = DBCellLookDef("__lefYank__"); if (lc.lefYank == (CellDef *)NULL) - lc.lefYank = DBCellNewDef("__lefYank__", (char *)NULL); + lc.lefYank = DBCellNewDef("__lefYank__"); DBCellSetAvail(lc.lefYank); lc.lefYank->cd_flags |= CDINTERNAL; diff --git a/netmenu/NMshowcell.c b/netmenu/NMshowcell.c index b44b200c..7434edcd 100644 --- a/netmenu/NMshowcell.c +++ b/netmenu/NMshowcell.c @@ -235,7 +235,7 @@ nmGetShowCell() nmscShowDef = DBCellLookDef("__SHOW__"); if (nmscShowDef == NULL) { - nmscShowDef = DBCellNewDef("__SHOW__", (char *) NULL); + nmscShowDef = DBCellNewDef("__SHOW__"); ASSERT (nmscShowDef != (CellDef *) NULL, "nmGetShowCell"); DBCellSetAvail(nmscShowDef); nmscShowDef->cd_flags |= CDINTERNAL; diff --git a/resis/ResMain.c b/resis/ResMain.c index 18c03850..30a62d72 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -113,7 +113,7 @@ ResGetReCell() ResDef = DBCellLookDef("__RESIS__"); if (ResDef == NULL) { - ResDef = DBCellNewDef("__RESIS__", (char *) NULL); + ResDef = DBCellNewDef("__RESIS__"); ASSERT (ResDef != (CellDef *) NULL, "ResGetReCell"); DBCellSetAvail(ResDef); ResDef->cd_flags |= CDINTERNAL; diff --git a/router/rtrDcmpose.c b/router/rtrDcmpose.c index fdfcb419..88a8b7cc 100644 --- a/router/rtrDcmpose.c +++ b/router/rtrDcmpose.c @@ -271,7 +271,7 @@ RtrFindChannelDef() /* Create our target cell */ if ((def = DBCellLookDef("__CHANNEL__")) == (CellDef *) NULL) { - def = DBCellNewDef("__CHANNEL__", (char *) NULL); + def = DBCellNewDef("__CHANNEL__"); DBCellSetAvail(def); def->cd_flags |= CDINTERNAL; } diff --git a/select/selCreate.c b/select/selCreate.c index 1aa495cf..47ef8b41 100644 --- a/select/selCreate.c +++ b/select/selCreate.c @@ -108,7 +108,7 @@ SelectInit() SelectDef = DBCellLookDef("__SELECT__"); if (SelectDef == (CellDef *) NULL) { - SelectDef = DBCellNewDef("__SELECT__",(char *) NULL); + SelectDef = DBCellNewDef("__SELECT__"); ASSERT(SelectDef != (CellDef *) NULL, "SelectInit"); DBCellSetAvail(SelectDef); SelectDef->cd_flags |= CDINTERNAL; @@ -122,7 +122,7 @@ SelectInit() Select2Def = DBCellLookDef("__SELECT2__"); if (Select2Def == (CellDef *) NULL) { - Select2Def = DBCellNewDef("__SELECT2__",(char *) NULL); + Select2Def = DBCellNewDef("__SELECT2__"); ASSERT(Select2Def != (CellDef *) NULL, "SelectInit"); DBCellSetAvail(Select2Def); Select2Def->cd_flags |= CDINTERNAL; From ae6b627df725259c01a6a4cce8f5d38d9a2d4ad7 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 21 Mar 2020 15:34:41 -0400 Subject: [PATCH 3/4] One more change to add back the .mag extension when writing the file from the contents of def->cd_file. --- database/DBio.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/database/DBio.c b/database/DBio.c index 2a556a34..37c306e6 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -2721,29 +2721,25 @@ DBCellWrite(cellDef, fileName) /* * Figure out the name of the file we will eventually write. */ - if (fileName) + if (!fileName) { - realname = (char *) mallocMagic(strlen(fileName) + strlen(DBSuffix) + 1); - (void) sprintf(realname, "%s%s", fileName, DBSuffix); + if (cellDef->cd_file) + fileName = cellDef->cd_file; + else if (cellDef->cd_name) + fileName = cellDef->cd_name; + else + return FALSE; + } - /* Bug fix: 7/17/99, Michael D. Godfrey: Forces */ - /* cd_name and cd_file to ALWAYS be the same, otherwise ugly */ - /* surprises can occur after saving a file as a different */ - /* filename. */ + /* Bug fix: 7/17/99, Michael D. Godfrey: Forces */ + /* cd_name and cd_file to ALWAYS be the same, otherwise ugly */ + /* surprises can occur after saving a file as a different */ + /* filename. */ - cellDef->cd_file = StrDup(&cellDef->cd_file, fileName); - } - else if (cellDef->cd_file) - { - realname = StrDup((char **) NULL, cellDef->cd_file); - } - else if (cellDef->cd_name) - { - realname = (char *) mallocMagic((unsigned) (strlen(cellDef->cd_name) - + strlen(DBSuffix) + 1)); - (void) sprintf(realname, "%s%s", cellDef->cd_name, DBSuffix); - } - else return (FALSE); + cellDef->cd_file = StrDup(&cellDef->cd_file, fileName); + + realname = (char *) mallocMagic(strlen(fileName) + strlen(DBSuffix) + 1); + (void) sprintf(realname, "%s%s", fileName, DBSuffix); /* * Expand the filename, removing the leading ~, if any. From c2bf9a8fb42f0e46ee93d66f39bbc053fe0304dd Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 21 Mar 2020 20:57:11 -0400 Subject: [PATCH 4/4] Added new command option "extract do local" to force all .ext files to be written to the local directory instead of the directory where the .mag file is located. --- commands/CmdE.c | 7 ++++++- extract/ExtCell.c | 10 ++++++++-- extract/ExtMain.c | 1 - extract/extract.h | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/commands/CmdE.c b/commands/CmdE.c index 80bb83cf..7cabc1ae 100644 --- a/commands/CmdE.c +++ b/commands/CmdE.c @@ -878,7 +878,8 @@ cmdExpandFunc(use, windowMask) #define DOCAPACITANCE 2 #define DOCOUPLING 3 #define DOLENGTH 4 -#define DORESISTANCE 5 +#define DOLOCAL 5 +#define DORESISTANCE 6 #define LENCLEAR 0 #define LENDRIVER 1 @@ -900,6 +901,7 @@ CmdExtract(w, cmd) CellDef *selectedDef; bool dolist = FALSE; bool doforall = FALSE; + bool doLocal = FALSE; int argc = cmd->tx_argc; char **argv = cmd->tx_argv; @@ -918,6 +920,7 @@ CmdExtract(w, cmd) "capacitance extract substrate capacitance", "coupling extract coupling capacitance", "length compute driver-receiver pathlengths", + "local put all generated files in the current directory", "resistance estimate resistance", NULL }; @@ -1136,6 +1139,7 @@ CmdExtract(w, cmd) TxPrintf("%s capacitance\n", OPTSET(EXT_DOCAPACITANCE)); TxPrintf("%s coupling\n", OPTSET(EXT_DOCOUPLING)); TxPrintf("%s length\n", OPTSET(EXT_DOLENGTH)); + TxPrintf("%s local\n", OPTSET(EXT_DOLOCAL)); TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE)); return; #undef OPTSET @@ -1163,6 +1167,7 @@ CmdExtract(w, cmd) case DOCAPACITANCE: option = EXT_DOCAPACITANCE; break; case DOCOUPLING: option = EXT_DOCOUPLING; break; case DOLENGTH: option = EXT_DOLENGTH; break; + case DOLOCAL: option = EXT_DOLOCAL; break; case DORESISTANCE: option = EXT_DORESISTANCE; break; } if (no) ExtOptions &= ~option; diff --git a/extract/ExtCell.c b/extract/ExtCell.c index a34f27e1..4aa8fb2a 100644 --- a/extract/ExtCell.c +++ b/extract/ExtCell.c @@ -95,8 +95,11 @@ ExtCell(def, outName, doLength) { char *filename; FILE *f; + bool doLocal; - f = extFileOpen(def, outName, "w", &filename); + doLocal = (ExtOptions & EXT_DOLOCAL) ? TRUE : FALSE; + + f = extFileOpen(def, outName, "w", doLocal, &filename); TxPrintf("Extracting %s into %s:\n", def->cd_name, filename); @@ -149,7 +152,7 @@ ExtCell(def, outName, doLength) */ FILE * -extFileOpen(def, file, mode, prealfile) +extFileOpen(def, file, mode, doLocal, prealfile) CellDef *def; /* Cell whose .ext file is to be written */ char *file; /* If non-NULL, open 'name'.ext; otherwise, * derive filename from 'def' as described @@ -158,6 +161,7 @@ extFileOpen(def, file, mode, prealfile) char *mode; /* Either "r" or "w", the mode in which the .ext * file is to be opened. */ + bool doLocal; /* If true, always write to local directory */ char **prealfile; /* If this is non-NULL, it gets set to point to * a string holding the name of the .ext file. */ @@ -167,6 +171,8 @@ extFileOpen(def, file, mode, prealfile) FILE *rfile, *testf; if (file) name = file; + else if (doLocal) + name = def->cd_name; /* No path component, so save locally */ else if (def->cd_file) { name = def->cd_file; diff --git a/extract/ExtMain.c b/extract/ExtMain.c index 2eba659f..65887b5a 100644 --- a/extract/ExtMain.c +++ b/extract/ExtMain.c @@ -632,7 +632,6 @@ closeit: void extExtractStack(stack, doExtract, rootDef) Stack *stack; - bool doExtract; CellDef *rootDef; { int fatal = 0, warnings = 0; diff --git a/extract/extract.h b/extract/extract.h index 82e143d5..57332f89 100644 --- a/extract/extract.h +++ b/extract/extract.h @@ -66,6 +66,7 @@ extern char *extDevTable[]; #define EXT_DORESISTANCE 0x08 /* Extract resistance */ #define EXT_DOLENGTH 0x10 /* Extract pathlengths */ #define EXT_DOALL 0x1f /* ALL OF THE ABOVE */ +#define EXT_DOLOCAL 0x20 /* Write to local directory only */ extern int ExtOptions; /* Bitmask of above */