diff --git a/VERSION b/VERSION index 8606ed34..a3437885 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.403 +8.3.404 diff --git a/commands/CmdE.c b/commands/CmdE.c index dcf45b0a..537c1f2f 100644 --- a/commands/CmdE.c +++ b/commands/CmdE.c @@ -862,10 +862,11 @@ cmdExpandFunc(use, windowMask) #define EXTLENGTH 5 #define EXTNO 6 #define EXTPARENTS 7 -#define EXTSHOWPARENTS 8 -#define EXTSTYLE 9 -#define EXTUNIQUE 10 -#define EXTWARN 11 +#define EXTPATH 8 +#define EXTSHOWPARENTS 9 +#define EXTSTYLE 10 +#define EXTUNIQUE 11 +#define EXTWARN 12 #define WARNALL 0 #define WARNDUP 1 @@ -957,6 +958,7 @@ CmdExtract(w, cmd) "length [option] control pathlength extraction information", "no [option] disable extractor option", "parents extract selected cell and all its parents", + "path [path] if set, extract into the indicated path", "showparents show all parents of selected cell", "style [stylename] set current extraction parameter style", "unique [option] generate unique names when different nodes\n\ @@ -1113,6 +1115,13 @@ CmdExtract(w, cmd) ExtShowParents(selectedUse); return; + case EXTPATH: + if (argc == 2) + ExtPrintPath(dolist); + else + ExtSetPath(argv[2]); + return; + case EXTSTYLE: if (argc == 2) ExtPrintStyle(dolist, doforall, !doforall); @@ -1188,7 +1197,6 @@ 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)); TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK)); TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES)); @@ -1218,10 +1226,19 @@ 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; case DOLABELCHECK: option = EXT_DOLABELCHECK; break; case DOALIASES: option = EXT_DOALIASES; break; + case DOLOCAL: + /* "extract do local" and "extract no local" are kept for + * backwards compatibility, but now effectively implement + * "extract path ." and "extract path none", respectively. + */ + if (no) + StrDup(&ExtLocalPath, NULL); + else + StrDup(&ExtLocalPath, "."); + return; } if (no) ExtOptions &= ~option; else ExtOptions |= option; diff --git a/doc/html/ext.html b/doc/html/ext.html deleted file mode 100644 index 262d774f..00000000 --- a/doc/html/ext.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - -Magic-7.3 Command Reference - -

Magic VLSI Layout Tool Version 8.2 - *

- -

ext, extract

-
-Circuit netlist extractor -
- -

Usage:

-
- extract option

-
- where option may be one of the following: -
-
all -
Extract the root cell and all its children. This bypasses - the incremental extraction and ensures that a new .ext - file is written for every cell definition. -
cell name -
Extract the indicated cell into file name -
do|no [option] -
Enable or disable an extractor option, where option - may be one of the following: -
-
-
capacitance -
-
resistance -
-
coupling -
-
length -
-
adjust -
-
all -
-
-
- -
length [option] -
Control pathlength extraction information, where option - may be one of the following: -
-
-
driver termname -
-
receiver termname -
-
clear -
-
-
- -
help -
Print help information -
parents -
Extract the selected cell and all its parents -
showparents -
List the cell and all parents of selected cell. Note that - this is not really an extract option and is superceded by - the cellname command. -
[list|listall] style [stylename] -
Set the current extraction style to stylename. - Without arguments, print the current extraction style. - With keyword list, return the current extraction - style as a Tcl result. With keyword listall, return - all valid extraction styles for the technology as a Tcl - list. -
unique [#] -
Generate unique names when different nodes have the same name -
warn [[no] option] -
Enable/disable reporting of non-fatal errors, where option - may be one of the following: -
-
-
fets -
-
labels -
-
dup -
-
all -
-
-
-
-
-
- -

Summary:

-
- With no options given, the extract command incrementally - extracts the root cell and all its children into separate - .ext files. With options, the effect is as described - in the Usage section above. -
- -

Implementation Notes:

-
- extract is implemented as a built-in magic command.

- ext is an alias for command extract (allowed - abbreviation where the usage would otherwise be ambiguous). -

- -

See Also:

-
- extresist
- ext2spice
- ext2sim
-
- -

- - - -
Return to command index -
-

Last updated: March 7, 2020 at 1:06pm

- - diff --git a/doc/html/ext.html b/doc/html/ext.html new file mode 120000 index 00000000..4742931f --- /dev/null +++ b/doc/html/ext.html @@ -0,0 +1 @@ +extract.html \ No newline at end of file diff --git a/doc/html/extract.html b/doc/html/extract.html index d7c6857d..e71ed0c4 100644 --- a/doc/html/extract.html +++ b/doc/html/extract.html @@ -80,7 +80,11 @@ Circuit netlist extractor same directory as the .mag file from which it is derived, unless the .mag file is in a directory which is not writable. In that case, the .ext file will also - be written to the current working directory. + be written to the current working directory.

+ Note: As of magic version 8.3.404, "extract + do local" effectively implements "extract path ." + and "extract no local" implements " extract + path none".

labelcheck
Check for labels which have zero area and connect to a subcell on the edge; this case is rare but is @@ -124,6 +128,19 @@ Circuit netlist extractor
help
Print help information +
path [pathname|none] +
Extract locally into the directory pathname. If + pathname does not exist, then magic will attempt to + create it. If it cannot be created, then the behavior will + be to save extract files in the current working directory. + If no path is set, or if none is specified as the + path, then the behavior will be to extract files in the + same directory as where the magic database (.mag) + file is located, unless that directory is unwritable by + the user, in which case the file is extracted to the + current working diretory. Note that "extract do local" + is the same as "extract path ." and "extract no local" + is the same as "extract path none".
parents
Extract the selected cell and all its parents
showparents diff --git a/extflat/EFargs.c b/extflat/EFargs.c index 970b07dc..14d92b16 100644 --- a/extflat/EFargs.c +++ b/extflat/EFargs.c @@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include +#include "utils/main.h" #include "utils/magic.h" #include "utils/paths.h" #include "utils/geometry.h" @@ -35,8 +36,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "utils/pathvisit.h" #include "extflat/extflat.h" #include "extflat/EFint.h" - -/* C99 compat */ #include "textio/textio.h" #include "utils/pathvisit.h" @@ -59,13 +58,6 @@ char *EFTech = NULL; char *EFStyle = NULL; /* Start with no extraction style */ bool EFCompat = TRUE; /* Start with backwards compatibility enabled */ -#ifdef MAGIC_WRAPPER -extern char *Path; /* magic's search path---note this should */ - /* be done with #include "utils/main.h" but */ - /* this is easier. */ -#endif - - /* -------------------- Visible only inside extflat ------------------- */ /* Command-line flags */ @@ -203,9 +195,10 @@ EFArgs(argc, argv, err_result, argsProc, cdata) EFCapThreshold = atoCap(cp); /* Femtofarads */ break; case 'p': - EFSearchPath = ArgStr(&argc, &argv, "search path"); - if (EFSearchPath == NULL) + cp = ArgStr(&argc, &argv, "search path"); + if (cp == NULL) goto usage; + StrDup(&EFSearchPath, cp); break; case 'r': if ((cp = ArgStr(&argc, &argv, "resist threshold")) == NULL) @@ -302,13 +295,9 @@ EFArgs(argc, argv, err_result, argsProc, cdata) } } - /* Find the search path if one was not specified */ - if (EFSearchPath == NULL) -#ifdef MAGIC_WRAPPER - /* Set the search path to be the same as magic's search path */ - EFSearchPath = StrDup(NULL, Path); -#else - efLoadSearchPath(&EFSearchPath); +#ifndef MAGIC_WRAPPER + /* This is probably not useful */ + if (EFSearchPath == NULL) efLoadSearchPath(&EFSearchPath); #endif EFLibPath = libpath; diff --git a/extflat/EFdef.c b/extflat/EFdef.c index edf05906..1947c82c 100644 --- a/extflat/EFdef.c +++ b/extflat/EFdef.c @@ -173,6 +173,13 @@ EFDone(func) /* Final cleanup */ HashKill(&efDefHashTable); + + /* EFSearchPath does not persist beyond the command that set it */ + if (EFSearchPath) + { + freeMagic(EFSearchPath); + EFSearchPath = NULL; + } } /* diff --git a/extflat/EFread.c b/extflat/EFread.c index 11287bf0..415757d8 100644 --- a/extflat/EFread.c +++ b/extflat/EFread.c @@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include "tcltk/tclmagic.h" +#include "utils/main.h" #include "utils/magic.h" #include "utils/malloc.h" #include "utils/geometry.h" @@ -201,10 +202,15 @@ efReadDef(def, dosubckt, resist, noscale, toplevel) def->def_flags |= DEF_AVAILABLE; name = def->def_name; - /* If cell is in main database, check if there is a file path set. */ + /* If the search path was specified with the "-p" argument to the calling + * command (e.g., ext2spice or ext2sim), then use that path. + */ + if (EFSearchPath != NULL) + inf = PaOpen(name, "r", ".ext", EFSearchPath, EFLibPath, &efReadFileName); - if ((dbdef = DBCellLookDef(name)) != NULL) + if ((inf == NULL) && (dbdef = DBCellLookDef(name)) != NULL) { + /* If cell is in main database, check if there is a file path set. */ if (dbdef->cd_file != NULL) { char *filepath, *sptr; @@ -218,18 +224,11 @@ efReadDef(def, dosubckt, resist, noscale, toplevel) freeMagic(filepath); } } - if (inf == NULL) - inf = PaOpen(name, "r", ".ext", EFSearchPath, EFLibPath, &efReadFileName); - if (inf == NULL) - { - /* Complementary to .ext file write: If file is in a read-only */ - /* directory, then .ext file is written to CWD. */ - char *proot; - proot = strrchr(name, '/'); - if (proot != NULL) - inf = PaOpen(proot + 1, "r", ".ext", ".", ".", &efReadFileName); - } + /* Try with the standard search path */ + if ((inf == NULL) && (EFSearchPath == NULL)) + inf = PaOpen(name, "r", ".ext", Path, EFLibPath, &efReadFileName); + if (inf == NULL) { #ifdef MAGIC_WRAPPER diff --git a/extract/ExtCell.c b/extract/ExtCell.c index bd94bb26..997eca19 100644 --- a/extract/ExtCell.c +++ b/extract/ExtCell.c @@ -22,6 +22,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #endif /* not lint */ #include +#include +#include +#include #include #include @@ -95,9 +98,6 @@ ExtCell(def, outName, doLength) char *filename; FILE *f = NULL; Plane *savePlane; - bool doLocal; - - doLocal = (ExtOptions & EXT_DOLOCAL) ? TRUE : FALSE; /* Incremental extraction: If the cell is marked for no extraction, * then just prepare the substrate plane and return it to the caller. @@ -105,7 +105,7 @@ ExtCell(def, outName, doLength) if (def->cd_flags & CDNOEXTRACT) return extPrepSubstrate(def); - f = extFileOpen(def, outName, "w", doLocal, &filename); + f = extFileOpen(def, outName, "w", &filename); TxPrintf("Extracting %s into %s:\n", def->cd_name, filename); @@ -159,7 +159,7 @@ ExtCell(def, outName, doLength) */ FILE * -extFileOpen(def, file, mode, doLocal, prealfile) +extFileOpen(def, file, mode, 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 @@ -168,7 +168,6 @@ extFileOpen(def, file, mode, doLocal, 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. */ @@ -178,8 +177,33 @@ extFileOpen(def, file, mode, doLocal, prealfile) FILE *rfile, *testf; if (file) name = file; - else if (doLocal) - name = def->cd_name; /* No path component, so save locally */ + else if (ExtLocalPath != NULL) + { + if (!strcmp(ExtLocalPath, ".")) + name = def->cd_name; /* Save locally */ + else + { + struct stat st = {0}; + + /* Test presence of the directory */ + if (stat(ExtLocalPath, &st) == -1) { + TxError("Path \"%s\" does not exist; attempting to create it.\n", + ExtLocalPath); + mkdir(ExtLocalPath, 0755); + if (stat(ExtLocalPath, &st) == -1) { + TxError("Path \"%s\" does not exist; saving locally.\n", + ExtLocalPath); + name = def->cd_name; /* Save locally */ + } + } + else + { + /* Save locally in specified path, which is assumed to exist */ + name = namebuf; + sprintf(namebuf, "%s/%s", ExtLocalPath, def->cd_name); + } + } + } else if (def->cd_file) { name = def->cd_file; diff --git a/extract/ExtMain.c b/extract/ExtMain.c index 96c1fe71..d05aad4b 100644 --- a/extract/ExtMain.c +++ b/extract/ExtMain.c @@ -58,6 +58,7 @@ extern FILE *extFileOpen(); */ int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS; int ExtOptions = EXT_DOALL|EXT_DOLABELCHECK|EXT_DOALIASES; +char *ExtLocalPath = NULL; /* --------------------------- Global data ---------------------------- */ @@ -908,9 +909,9 @@ extTimestampMisMatch(def) int stamp; bool doLocal; - doLocal = (ExtOptions & EXT_DOLOCAL) ? TRUE : FALSE; + doLocal = (ExtLocalPath == NULL) ? FALSE : TRUE; - extFile = extFileOpen(def, (char *) NULL, "r", doLocal, (char **) NULL); + extFile = extFileOpen(def, (char *) NULL, "r", (char **) NULL); if (extFile == NULL) return (TRUE); diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 5023a8b3..4309e197 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -577,6 +577,87 @@ ExtGetZAxis(tile, height, thick) } #endif /* THREE_D */ +/* + * ---------------------------------------------------------------------------- + * + * ExtPrintPath -- + * + * Print the path where extraction files will be written + * + * Results: + * None. + * + * Side effects: + * Output. + * + * ---------------------------------------------------------------------------- + */ + +void +ExtPrintPath(dolist) + bool dolist; +{ + if (ExtLocalPath == NULL) + { + if (dolist) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewStringObj("(none)", -1)); +#else + TxPrintf("(none)\n"); +#endif + } + else + TxPrintf("(none)\n"); + } + else + { + if (dolist) + { +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(ExtLocalPath, -1)); +#else + TxPrintf("%s\n", ExtLocalPath); +#endif + } + else + TxPrintf("The extraction path is: %s\n", ExtLocalPath); + } +} + +/* + * ---------------------------------------------------------------------------- + * + * ExtSetPath -- + * + * Set the current extraction path to 'path', unless 'path' is "none" or + * "(none)", in which case clear the path and set it to NULL. + * + * Results: + * None. + * + * Side effects: + * Just told you. + * + * ---------------------------------------------------------------------------- + */ + +void +ExtSetPath(path) + char *path; +{ + if (path != NULL) + { + if (!strcasecmp(path, "none") || !strcasecmp(path, "(none)") || + !strcasecmp(path, "null")) + { + StrDup(&ExtLocalPath, NULL); + return; + } + } + StrDup(&ExtLocalPath, path); + return; +} /* * ---------------------------------------------------------------------------- diff --git a/extract/extract.h b/extract/extract.h index 74c16e99..2ace2ae1 100644 --- a/extract/extract.h +++ b/extract/extract.h @@ -69,11 +69,11 @@ extern char *extDevTable[]; #define EXT_DOLENGTH 0x010 /* Extract pathlengths */ #define EXT_DOFRINGEHALO 0x020 /* Distributed fringe capacitance */ #define EXT_DOALL 0x03f /* ALL OF THE ABOVE */ -#define EXT_DOLOCAL 0x040 /* Write to local directory only */ -#define EXT_DOLABELCHECK 0x080 /* Check for connections by label */ -#define EXT_DOALIASES 0x100 /* Output all node aliases */ +#define EXT_DOLABELCHECK 0x040 /* Check for connections by label */ +#define EXT_DOALIASES 0x080 /* Output all node aliases */ extern int ExtOptions; /* Bitmask of above */ +extern char *ExtLocalPath; /* If non-NULL, location to write .ext files */ /* Options for "extract unique" */ #define EXT_UNIQ_ALL 0 @@ -86,6 +86,8 @@ extern void ExtTechInit(); extern void ExtTechFinal(); extern void ExtSetStyle(); extern void ExtPrintStyle(); +extern void ExtSetPath(); +extern void ExtPrintPath(); extern void ExtRevertSubstrate(); extern Plane *ExtCell(); extern void ExtractOneCell();