Reimplemented the "extract do local" option as "extract path <name>"

with "extract do local" now being equivalent to "extract path .".
This allows extraction files to be put in a subdirectory and not
clog up the current working directory.  Also:  Fixed some behavior
around the use of "ext2spice -p <path>" so that it (1) works, and
(2) is compatible with the new "extract path".  Since the ext2spice
and ext2sim commands are effectively independent of the primary
extraction, the "-p" option is needed to correspond to the use of
"extract path".  Hopefully this is seen as only a minor inconvenience.
This commit is contained in:
Tim Edwards 2023-06-14 13:55:59 -04:00
parent 9b131fa96c
commit 482d7534a2
11 changed files with 190 additions and 190 deletions

View File

@ -1 +1 @@
8.3.403 8.3.404

View File

@ -862,10 +862,11 @@ cmdExpandFunc(use, windowMask)
#define EXTLENGTH 5 #define EXTLENGTH 5
#define EXTNO 6 #define EXTNO 6
#define EXTPARENTS 7 #define EXTPARENTS 7
#define EXTSHOWPARENTS 8 #define EXTPATH 8
#define EXTSTYLE 9 #define EXTSHOWPARENTS 9
#define EXTUNIQUE 10 #define EXTSTYLE 10
#define EXTWARN 11 #define EXTUNIQUE 11
#define EXTWARN 12
#define WARNALL 0 #define WARNALL 0
#define WARNDUP 1 #define WARNDUP 1
@ -957,6 +958,7 @@ CmdExtract(w, cmd)
"length [option] control pathlength extraction information", "length [option] control pathlength extraction information",
"no [option] disable extractor option", "no [option] disable extractor option",
"parents extract selected cell and all its parents", "parents extract selected cell and all its parents",
"path [path] if set, extract into the indicated path",
"showparents show all parents of selected cell", "showparents show all parents of selected cell",
"style [stylename] set current extraction parameter style", "style [stylename] set current extraction parameter style",
"unique [option] generate unique names when different nodes\n\ "unique [option] generate unique names when different nodes\n\
@ -1113,6 +1115,13 @@ CmdExtract(w, cmd)
ExtShowParents(selectedUse); ExtShowParents(selectedUse);
return; return;
case EXTPATH:
if (argc == 2)
ExtPrintPath(dolist);
else
ExtSetPath(argv[2]);
return;
case EXTSTYLE: case EXTSTYLE:
if (argc == 2) if (argc == 2)
ExtPrintStyle(dolist, doforall, !doforall); ExtPrintStyle(dolist, doforall, !doforall);
@ -1188,7 +1197,6 @@ CmdExtract(w, cmd)
TxPrintf("%s capacitance\n", OPTSET(EXT_DOCAPACITANCE)); TxPrintf("%s capacitance\n", OPTSET(EXT_DOCAPACITANCE));
TxPrintf("%s coupling\n", OPTSET(EXT_DOCOUPLING)); TxPrintf("%s coupling\n", OPTSET(EXT_DOCOUPLING));
TxPrintf("%s length\n", OPTSET(EXT_DOLENGTH)); TxPrintf("%s length\n", OPTSET(EXT_DOLENGTH));
TxPrintf("%s local\n", OPTSET(EXT_DOLOCAL));
TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE)); TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE));
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK)); TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES)); TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
@ -1218,10 +1226,19 @@ CmdExtract(w, cmd)
case DOCAPACITANCE: option = EXT_DOCAPACITANCE; break; case DOCAPACITANCE: option = EXT_DOCAPACITANCE; break;
case DOCOUPLING: option = EXT_DOCOUPLING; break; case DOCOUPLING: option = EXT_DOCOUPLING; break;
case DOLENGTH: option = EXT_DOLENGTH; break; case DOLENGTH: option = EXT_DOLENGTH; break;
case DOLOCAL: option = EXT_DOLOCAL; break;
case DORESISTANCE: option = EXT_DORESISTANCE; break; case DORESISTANCE: option = EXT_DORESISTANCE; break;
case DOLABELCHECK: option = EXT_DOLABELCHECK; break; case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
case DOALIASES: option = EXT_DOALIASES; 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; if (no) ExtOptions &= ~option;
else ExtOptions |= option; else ExtOptions |= option;

View File

@ -1,138 +0,0 @@
<HTML>
<HEAD>
<STYLE type="text/css">
H1 {color: black }
H2 {color: maroon }
H3 {color: #007090 }
A.head:link {color: #0060a0 }
A.head:visited {color: #3040c0 }
A.head:active {color: white }
A.head:hover {color: yellow }
A.red:link {color: red }
A.red:visited {color: maroon }
A.red:active {color: yellow }
</STYLE>
</HEAD>
<TITLE>Magic-7.3 Command Reference</TITLE>
<BODY BACKGROUND=graphics/blpaper.gif>
<H1> <IMG SRC=graphics/magic_title8_2.png ALT="Magic VLSI Layout Tool Version 8.2">
<IMG SRC=graphics/magic_OGL_sm.gif ALIGN="top" ALT="*"> </H1>
<H2>ext, extract</H2>
<HR>
Circuit netlist extractor
<HR>
<H3>Usage:</H3>
<BLOCKQUOTE>
<B>extract</B> <I>option</I> <BR><BR>
<BLOCKQUOTE>
where <I>option</I> may be one of the following:
<DL>
<DT> <B>all</B>
<DD> Extract the root cell and all its children. This bypasses
the incremental extraction and ensures that a new <TT>.ext</TT>
file is written for every cell definition.
<DT> <B>cell</B> <I>name</I>
<DD> Extract the indicated cell into file <I>name</I>
<DT> <B>do</B>|<B>no</B> [<I>option</I>]
<DD> Enable or disable an extractor option, where <I>option</I>
may be one of the following:
<BLOCKQUOTE>
<DL>
<DT> <B>capacitance</B>
<DD>
<DT> <B>resistance</B>
<DD>
<DT> <B>coupling</B>
<DD>
<DT> <B>length</B>
<DD>
<DT> <B>adjust</B>
<DD>
<DT> <B>all</B>
<DD>
</DL>
</BLOCKQUOTE>
<DT> <B>length</B> [<I>option</I>]
<DD> Control pathlength extraction information, where <I>option</I>
may be one of the following:
<BLOCKQUOTE>
<DL>
<DT> <B>driver</B> <I>termname</I>
<DD>
<DT> <B>receiver</B> <I>termname</I>
<DD>
<DT> <B>clear</B>
<DD>
</DL>
</BLOCKQUOTE>
<DT> <B>help</B>
<DD> Print help information
<DT> <B>parents</B>
<DD> Extract the selected cell and all its parents
<DT> <B>showparents</B>
<DD> List the cell and all parents of selected cell. Note that
this is not really an extract option and is superceded by
the <B>cellname</B> command.
<DT> [<B>list</B>|<B>listall</B>] <B>style</B> [<I>stylename</I>]
<DD> Set the current extraction style to <I>stylename</I>.
Without arguments, print the current extraction style.
With keyword <B>list</B>, return the current extraction
style as a Tcl result. With keyword <B>listall</B>, return
all valid extraction styles for the technology as a Tcl
list.
<DT> <B>unique</B> [<I>#</I>]
<DD> Generate unique names when different nodes have the same name
<DT> <B>warn</B> [[<B>no</B>] <I>option</I>]
<DD> Enable/disable reporting of non-fatal errors, where <I>option</I>
may be one of the following:
<BLOCKQUOTE>
<DL>
<DT> <B>fets</B>
<DD>
<DT> <B>labels</B>
<DD>
<DT> <B>dup</B>
<DD>
<DT> <B>all</B>
<DD>
</DL>
</BLOCKQUOTE>
</DL>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H3>Summary:</H3>
<BLOCKQUOTE>
With no options given, the <B>extract</B> command incrementally
extracts the root cell and all its children into separate
<TT>.ext</TT> files. With options, the effect is as described
in the Usage section above.
</BLOCKQUOTE>
<H3>Implementation Notes:</H3>
<BLOCKQUOTE>
<B>extract</B> is implemented as a built-in <B>magic</B> command. <P>
<B>ext</B> is an alias for command <B>extract</B> (allowed
abbreviation where the usage would otherwise be ambiguous).
</BLOCKQUOTE>
<H3>See Also:</H3>
<BLOCKQUOTE>
<A HREF=extresist.html><B>extresist</B></A> <BR>
<A HREF=ext2spice.html><B>ext2spice</B></A> <BR>
<A HREF=ext2sim.html><B>ext2sim</B></A> <BR>
</BLOCKQUOTE>
<P><IMG SRC=graphics/line1.gif><P>
<TABLE BORDER=0>
<TR>
<TD> <A HREF=commands.html>Return to command index</A>
</TR>
</TABLE>
<P><I>Last updated:</I> March 7, 2020 at 1:06pm <P>
</BODY>
</HTML>

1
doc/html/ext.html Symbolic link
View File

@ -0,0 +1 @@
extract.html

View File

@ -80,7 +80,11 @@ Circuit netlist extractor
same directory as the .mag file from which it is same directory as the .mag file from which it is
derived, unless the .mag file is in a directory which derived, unless the .mag file is in a directory which
is not writable. In that case, the .ext file will also 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. <P>
<I>Note:</I> As of magic version 8.3.404, "<B>extract
do local</B>" effectively implements "<B>extract path .</B>"
and "<B>extract no local</B>" implements "<B> extract
path none</B>".
<DT> <B>labelcheck</B> <DT> <B>labelcheck</B>
<DD> Check for labels which have zero area and connect <DD> Check for labels which have zero area and connect
to a subcell on the edge; this case is rare but is to a subcell on the edge; this case is rare but is
@ -124,6 +128,19 @@ Circuit netlist extractor
<DT> <B>help</B> <DT> <B>help</B>
<DD> Print help information <DD> Print help information
<DT> <B>path</B> [<I>pathname</I>|<B>none</B>]
<DD> Extract locally into the directory <I>pathname</I>. If
<I>pathname</I> 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 <B>none</B> is specified as the
path, then the behavior will be to extract files in the
same directory as where the magic database (<B>.mag</B>)
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 "<B>extract do local</B>"
is the same as "<B>extract path .</B>" and "<B>extract no local</B>"
is the same as "<B>extract path none</B>".
<DT> <B>parents</B> <DT> <B>parents</B>
<DD> Extract the selected cell and all its parents <DD> Extract the selected cell and all its parents
<DT> <B>showparents</B> <DT> <B>showparents</B>

View File

@ -26,6 +26,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "utils/main.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/paths.h" #include "utils/paths.h"
#include "utils/geometry.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 "utils/pathvisit.h"
#include "extflat/extflat.h" #include "extflat/extflat.h"
#include "extflat/EFint.h" #include "extflat/EFint.h"
/* C99 compat */
#include "textio/textio.h" #include "textio/textio.h"
#include "utils/pathvisit.h" #include "utils/pathvisit.h"
@ -59,13 +58,6 @@ char *EFTech = NULL;
char *EFStyle = NULL; /* Start with no extraction style */ char *EFStyle = NULL; /* Start with no extraction style */
bool EFCompat = TRUE; /* Start with backwards compatibility enabled */ 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 ------------------- */ /* -------------------- Visible only inside extflat ------------------- */
/* Command-line flags */ /* Command-line flags */
@ -203,9 +195,10 @@ EFArgs(argc, argv, err_result, argsProc, cdata)
EFCapThreshold = atoCap(cp); /* Femtofarads */ EFCapThreshold = atoCap(cp); /* Femtofarads */
break; break;
case 'p': case 'p':
EFSearchPath = ArgStr(&argc, &argv, "search path"); cp = ArgStr(&argc, &argv, "search path");
if (EFSearchPath == NULL) if (cp == NULL)
goto usage; goto usage;
StrDup(&EFSearchPath, cp);
break; break;
case 'r': case 'r':
if ((cp = ArgStr(&argc, &argv, "resist threshold")) == NULL) 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 */ #ifndef MAGIC_WRAPPER
if (EFSearchPath == NULL) /* This is probably not useful */
#ifdef MAGIC_WRAPPER if (EFSearchPath == NULL) efLoadSearchPath(&EFSearchPath);
/* Set the search path to be the same as magic's search path */
EFSearchPath = StrDup(NULL, Path);
#else
efLoadSearchPath(&EFSearchPath);
#endif #endif
EFLibPath = libpath; EFLibPath = libpath;

View File

@ -173,6 +173,13 @@ EFDone(func)
/* Final cleanup */ /* Final cleanup */
HashKill(&efDefHashTable); HashKill(&efDefHashTable);
/* EFSearchPath does not persist beyond the command that set it */
if (EFSearchPath)
{
freeMagic(EFSearchPath);
EFSearchPath = NULL;
}
} }
/* /*

View File

@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include <ctype.h> #include <ctype.h>
#include "tcltk/tclmagic.h" #include "tcltk/tclmagic.h"
#include "utils/main.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/malloc.h" #include "utils/malloc.h"
#include "utils/geometry.h" #include "utils/geometry.h"
@ -201,10 +202,15 @@ efReadDef(def, dosubckt, resist, noscale, toplevel)
def->def_flags |= DEF_AVAILABLE; def->def_flags |= DEF_AVAILABLE;
name = def->def_name; 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) if (dbdef->cd_file != NULL)
{ {
char *filepath, *sptr; char *filepath, *sptr;
@ -218,18 +224,11 @@ efReadDef(def, dosubckt, resist, noscale, toplevel)
freeMagic(filepath); freeMagic(filepath);
} }
} }
if (inf == NULL)
inf = PaOpen(name, "r", ".ext", EFSearchPath, EFLibPath, &efReadFileName);
if (inf == NULL) /* Try with the standard search path */
{ if ((inf == NULL) && (EFSearchPath == NULL))
/* Complementary to .ext file write: If file is in a read-only */ inf = PaOpen(name, "r", ".ext", Path, EFLibPath, &efReadFileName);
/* directory, then .ext file is written to CWD. */
char *proot;
proot = strrchr(name, '/');
if (proot != NULL)
inf = PaOpen(proot + 1, "r", ".ext", ".", ".", &efReadFileName);
}
if (inf == NULL) if (inf == NULL)
{ {
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER

View File

@ -22,6 +22,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
@ -95,9 +98,6 @@ ExtCell(def, outName, doLength)
char *filename; char *filename;
FILE *f = NULL; FILE *f = NULL;
Plane *savePlane; Plane *savePlane;
bool doLocal;
doLocal = (ExtOptions & EXT_DOLOCAL) ? TRUE : FALSE;
/* Incremental extraction: If the cell is marked for no extraction, /* Incremental extraction: If the cell is marked for no extraction,
* then just prepare the substrate plane and return it to the caller. * 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) if (def->cd_flags & CDNOEXTRACT)
return extPrepSubstrate(def); 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); TxPrintf("Extracting %s into %s:\n", def->cd_name, filename);
@ -159,7 +159,7 @@ ExtCell(def, outName, doLength)
*/ */
FILE * FILE *
extFileOpen(def, file, mode, doLocal, prealfile) extFileOpen(def, file, mode, prealfile)
CellDef *def; /* Cell whose .ext file is to be written */ CellDef *def; /* Cell whose .ext file is to be written */
char *file; /* If non-NULL, open 'name'.ext; otherwise, char *file; /* If non-NULL, open 'name'.ext; otherwise,
* derive filename from 'def' as described * 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 char *mode; /* Either "r" or "w", the mode in which the .ext
* file is to be opened. * 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 char **prealfile; /* If this is non-NULL, it gets set to point to
* a string holding the name of the .ext file. * a string holding the name of the .ext file.
*/ */
@ -178,8 +177,33 @@ extFileOpen(def, file, mode, doLocal, prealfile)
FILE *rfile, *testf; FILE *rfile, *testf;
if (file) name = file; if (file) name = file;
else if (doLocal) else if (ExtLocalPath != NULL)
name = def->cd_name; /* No path component, so save locally */ {
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) else if (def->cd_file)
{ {
name = def->cd_file; name = def->cd_file;

View File

@ -58,6 +58,7 @@ extern FILE *extFileOpen();
*/ */
int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS; int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS;
int ExtOptions = EXT_DOALL|EXT_DOLABELCHECK|EXT_DOALIASES; int ExtOptions = EXT_DOALL|EXT_DOLABELCHECK|EXT_DOALIASES;
char *ExtLocalPath = NULL;
/* --------------------------- Global data ---------------------------- */ /* --------------------------- Global data ---------------------------- */
@ -908,9 +909,9 @@ extTimestampMisMatch(def)
int stamp; int stamp;
bool doLocal; 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) if (extFile == NULL)
return (TRUE); return (TRUE);

View File

@ -577,6 +577,87 @@ ExtGetZAxis(tile, height, thick)
} }
#endif /* THREE_D */ #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;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------

View File

@ -69,11 +69,11 @@ extern char *extDevTable[];
#define EXT_DOLENGTH 0x010 /* Extract pathlengths */ #define EXT_DOLENGTH 0x010 /* Extract pathlengths */
#define EXT_DOFRINGEHALO 0x020 /* Distributed fringe capacitance */ #define EXT_DOFRINGEHALO 0x020 /* Distributed fringe capacitance */
#define EXT_DOALL 0x03f /* ALL OF THE ABOVE */ #define EXT_DOALL 0x03f /* ALL OF THE ABOVE */
#define EXT_DOLOCAL 0x040 /* Write to local directory only */ #define EXT_DOLABELCHECK 0x040 /* Check for connections by label */
#define EXT_DOLABELCHECK 0x080 /* Check for connections by label */ #define EXT_DOALIASES 0x080 /* Output all node aliases */
#define EXT_DOALIASES 0x100 /* Output all node aliases */
extern int ExtOptions; /* Bitmask of above */ extern int ExtOptions; /* Bitmask of above */
extern char *ExtLocalPath; /* If non-NULL, location to write .ext files */
/* Options for "extract unique" */ /* Options for "extract unique" */
#define EXT_UNIQ_ALL 0 #define EXT_UNIQ_ALL 0
@ -86,6 +86,8 @@ extern void ExtTechInit();
extern void ExtTechFinal(); extern void ExtTechFinal();
extern void ExtSetStyle(); extern void ExtSetStyle();
extern void ExtPrintStyle(); extern void ExtPrintStyle();
extern void ExtSetPath();
extern void ExtPrintPath();
extern void ExtRevertSubstrate(); extern void ExtRevertSubstrate();
extern Plane *ExtCell(); extern Plane *ExtCell();
extern void ExtractOneCell(); extern void ExtractOneCell();