mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-09-06 17:09:40 +02:00
Several enhancements: (1) Added command option "gds no_duplicates"
to allow a "gds read" command to ignore cells in the GDS which already exist in memory. This allows magic to be "pre-seeded" with specific views of cells in the GDS. Default is false, which is backwards- compatble behavior. (2) Changed the behavior of the the way the use path is written to and read from a .mag file, checking the path prefix against Tcl variables PDK_PATH, PDKPATH, PDK_ROOT, and PDKROOT, and replacing any such leading path component with the variable name. On reading a .mag file, any variable name at the start of the path that matches a Tcl variable will be substituted.
This commit is contained in:
+106
-12
@@ -45,6 +45,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||
#include <paths.h>
|
||||
#endif
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
#include "tiles/tile.h"
|
||||
@@ -1373,7 +1374,7 @@ badTransform:
|
||||
else if (DBIsAncestor(subCellDef, cellDef))
|
||||
{
|
||||
/*
|
||||
* Watchout for attempts to create circular structures.
|
||||
* Watch out for attempts to create circular structures.
|
||||
* If this happens, disregard the subcell.
|
||||
*/
|
||||
TxPrintf("Subcells are used circularly!\n");
|
||||
@@ -1382,6 +1383,33 @@ badTransform:
|
||||
goto nextLine;
|
||||
}
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
/* If path starts with '$' then check for a possible Tcl variable */
|
||||
/* replacement. */
|
||||
|
||||
if (*pathptr == '$')
|
||||
{
|
||||
char *varstart, *varend, savechar, *tvar;
|
||||
|
||||
varstart = pathptr + 1;
|
||||
if (*varstart == '{') varstart++;
|
||||
varend = varstart + 1;
|
||||
while (*varend != '\0' && *varend != '}' && *varend != '/'
|
||||
&& *varend != '\n' && *varend != ' ') varend++;
|
||||
savechar = *varend;
|
||||
*varend = '\0';
|
||||
|
||||
tvar = (char *)Tcl_GetVar(magicinterp, varstart, TCL_GLOBAL_ONLY);
|
||||
*varend = savechar;
|
||||
if (savechar == '}') varend++;
|
||||
if (tvar)
|
||||
{
|
||||
memmove(pathptr + strlen(tvar), varend, strlen(varend) + 1);
|
||||
memmove(pathptr, tvar, strlen(tvar));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Relative path handling: If path does not have a leading "/" */
|
||||
/* or "~" and cellDef->cd_file has path components, then the path */
|
||||
/* should be interpreted relative to the path of the parent cell. */
|
||||
@@ -3146,6 +3174,7 @@ dbWriteCellFunc(cellUse, cdarg)
|
||||
struct writeArg *arg = (struct writeArg *) cdarg;
|
||||
Transform *t;
|
||||
Rect *b;
|
||||
bool subbed = FALSE;
|
||||
char cstring[256], *pathend, *pathstart, *parent;
|
||||
|
||||
t = &(cellUse->cu_transform);
|
||||
@@ -3197,25 +3226,90 @@ dbWriteCellFunc(cellUse, cdarg)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If path starts with home path, then replace with "~" */
|
||||
/* to make IP semi-portable between home directories */
|
||||
/* with the same file structure. */
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *tvar;
|
||||
|
||||
char *homedir = getenv("HOME");
|
||||
/* Check for the leading component of the file path being equal to */
|
||||
/* one of several common variable names for the PDK location, and */
|
||||
/* if there is a match, then substitute the variable name for the */
|
||||
/* matching leading path component. */
|
||||
|
||||
if (!strncmp(cellUse->cu_def->cd_file, homedir, strlen(homedir))
|
||||
&& (*(cellUse->cu_def->cd_file + strlen(homedir)) == '/'))
|
||||
if (subbed == FALSE)
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s ~%s\n", cellUse->cu_def->cd_name,
|
||||
tvar = (char *)Tcl_GetVar(magicinterp, "PDK_PATH", TCL_GLOBAL_ONLY);
|
||||
if (tvar)
|
||||
if (!strncmp(pathstart, tvar, strlen(tvar)))
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s $PDK_PATH%s\n",
|
||||
cellUse->cu_def->cd_name,
|
||||
(cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ',
|
||||
cellUse->cu_id, pathstart + strlen(tvar));
|
||||
subbed = TRUE;
|
||||
}
|
||||
}
|
||||
if (subbed == FALSE)
|
||||
{
|
||||
tvar = (char *)Tcl_GetVar(magicinterp, "PDKPATH", TCL_GLOBAL_ONLY);
|
||||
if (tvar)
|
||||
if (!strncmp(pathstart, tvar, strlen(tvar)))
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s $PDKPATH%s\n",
|
||||
cellUse->cu_def->cd_name,
|
||||
(cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ',
|
||||
cellUse->cu_id, pathstart + strlen(tvar));
|
||||
subbed = TRUE;
|
||||
}
|
||||
}
|
||||
if (subbed == FALSE)
|
||||
{
|
||||
tvar = (char *)Tcl_GetVar(magicinterp, "PDK_ROOT", TCL_GLOBAL_ONLY);
|
||||
if (tvar)
|
||||
if (!strncmp(pathstart, tvar, strlen(tvar)))
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s $PDK_ROOT%s\n",
|
||||
cellUse->cu_def->cd_name,
|
||||
(cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ',
|
||||
cellUse->cu_id, pathstart + strlen(tvar));
|
||||
subbed = TRUE;
|
||||
}
|
||||
}
|
||||
if (subbed == FALSE)
|
||||
{
|
||||
tvar = (char *)Tcl_GetVar(magicinterp, "PDKROOT", TCL_GLOBAL_ONLY);
|
||||
if (tvar)
|
||||
if (!strncmp(pathstart, tvar, strlen(tvar)))
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s $PDKROOT%s\n",
|
||||
cellUse->cu_def->cd_name,
|
||||
(cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ',
|
||||
cellUse->cu_id, pathstart + strlen(tvar));
|
||||
subbed = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (subbed == FALSE)
|
||||
{
|
||||
/* If path starts with home path, then replace with "~" */
|
||||
/* to make IP semi-portable between home directories */
|
||||
/* with the same file structure. */
|
||||
|
||||
char *homedir = getenv("HOME");
|
||||
|
||||
if (!strncmp(cellUse->cu_def->cd_file, homedir, strlen(homedir))
|
||||
&& (*(cellUse->cu_def->cd_file + strlen(homedir)) == '/'))
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s ~%s\n", cellUse->cu_def->cd_name,
|
||||
(cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ',
|
||||
cellUse->cu_id, cellUse->cu_def->cd_file +
|
||||
strlen(homedir));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s %s\n", cellUse->cu_def->cd_name,
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(cstring, "use %s %c%s %s\n", cellUse->cu_def->cd_name,
|
||||
(cellUse->cu_flags & CU_LOCKED) ? CULOCKCHAR : ' ',
|
||||
cellUse->cu_id, pathstart);
|
||||
}
|
||||
}
|
||||
}
|
||||
FPRINTR(arg->wa_file, cstring);
|
||||
|
||||
Reference in New Issue
Block a user