Merge branch 'master' into bplane
Conflicts: VERSION Merged recent changes from master back into bplane, as the efficiency of bplane for doing extraction on large layouts is unquestionably better. Fixed the implementation of DBMoveCell() for bplane. Corrected an error in the bplane version of dbScaleCell() that enumerates cell uses but does not free the list.
This commit is contained in:
commit
ff0ba7f89d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -3714,14 +3711,6 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx)
|
|||
if ((clen > 4) && !strcmp(cellnameptr + clen - 4, ".mag"))
|
||||
*(cellnameptr + clen - 4) = '\0';
|
||||
|
||||
/* However, if this is a full path, then the full path name must have .mag */
|
||||
if (fullpathname != NULL)
|
||||
{
|
||||
clen = strlen(fullpathname);
|
||||
if ((clen <= 4) || strcmp(fullpathname + clen - 4, ".mag"))
|
||||
strcat(cellnameptr, ".mag");
|
||||
}
|
||||
|
||||
/* Check for illegal characters in the cellname */
|
||||
if (CmdIllegalChars(cellnameptr, "", "Cell name"))
|
||||
{
|
||||
|
|
@ -3731,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)
|
||||
{
|
||||
|
|
@ -3757,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);
|
||||
}
|
||||
|
|
@ -3785,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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1944,7 +1944,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);
|
||||
|
|
|
|||
|
|
@ -480,8 +480,8 @@ keepGoing(use, clientdata)
|
|||
* Implement the "move" command.
|
||||
*
|
||||
* Usage:
|
||||
* move [direction [amount]]
|
||||
* move to x y
|
||||
* move [origin] [direction [amount]]
|
||||
* move [origin] to x y
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -502,12 +502,13 @@ CmdMove(w, cmd)
|
|||
Point rootPoint, editPoint;
|
||||
CellDef *rootDef;
|
||||
int argpos;
|
||||
bool doOrigin = FALSE;
|
||||
|
||||
if (cmd->tx_argc > 4)
|
||||
{
|
||||
badUsage:
|
||||
TxError("Usage: %s [direction [amount]]\n", cmd->tx_argv[0]);
|
||||
TxError(" or: %s to x y\n", cmd->tx_argv[0]);
|
||||
TxError("Usage: %s [origin] [direction [amount]]\n", cmd->tx_argv[0]);
|
||||
TxError(" or: %s [origin] to x y\n", cmd->tx_argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -518,18 +519,26 @@ CmdMove(w, cmd)
|
|||
|
||||
if (!ToolGetEditBox((Rect *)NULL)) return;
|
||||
|
||||
if (strcmp(cmd->tx_argv[1], "to") == 0)
|
||||
argpos = 1;
|
||||
|
||||
if (strcmp(cmd->tx_argv[1], "origin") == 0)
|
||||
{
|
||||
doOrigin = TRUE;
|
||||
argpos++;
|
||||
}
|
||||
|
||||
if (strcmp(cmd->tx_argv[argpos], "to") == 0)
|
||||
{
|
||||
if (cmd->tx_argc != 4)
|
||||
goto badUsage;
|
||||
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
|
||||
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[argpos + 1], FALSE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[argpos + 2], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &editPoint, &rootPoint);
|
||||
goto moveToPoint;
|
||||
}
|
||||
|
||||
indx = GeoNameToPos(cmd->tx_argv[1], FALSE, FALSE);
|
||||
argpos = (indx < 0) ? 1 : 2;
|
||||
indx = GeoNameToPos(cmd->tx_argv[argpos], FALSE, FALSE);
|
||||
if (indx >= 0) argpos++;
|
||||
|
||||
if (cmd->tx_argc >= 3)
|
||||
{
|
||||
|
|
@ -605,8 +614,9 @@ CmdMove(w, cmd)
|
|||
* but is retained for backward compatibility.
|
||||
*/
|
||||
|
||||
if (ToolGetBox(&rootDef, &rootBox) && ((rootDef == SelectRootDef)
|
||||
|| (SelectRootDef == NULL)))
|
||||
if (ToolGetBox(&rootDef, &rootBox) &&
|
||||
((rootDef == SelectRootDef) || (SelectRootDef == NULL))
|
||||
&& (doOrigin == FALSE))
|
||||
{
|
||||
GeoTransRect(&t, &rootBox, &newBox);
|
||||
DBWSetBox(rootDef, &newBox);
|
||||
|
|
@ -640,11 +650,41 @@ moveToPoint:
|
|||
}
|
||||
GeoTransTranslate(rootPoint.p_x - rootBox.r_xbot,
|
||||
rootPoint.p_y - rootBox.r_ybot, &GeoIdentityTransform, &t);
|
||||
GeoTransRect(&t, &rootBox, &newBox);
|
||||
DBWSetBox(rootDef, &newBox);
|
||||
if (doOrigin == FALSE)
|
||||
{
|
||||
GeoTransRect(&t, &rootBox, &newBox);
|
||||
DBWSetBox(rootDef, &newBox);
|
||||
}
|
||||
}
|
||||
|
||||
SelectTransform(&t);
|
||||
if (doOrigin)
|
||||
{
|
||||
DBMoveCell(rootDef, t.t_c, t.t_f);
|
||||
|
||||
/* Adjust box to maintain relative position */
|
||||
|
||||
if (ToolGetBox(&rootDef, &rootBox) &&
|
||||
((rootDef == SelectRootDef) || (SelectRootDef == NULL)))
|
||||
{
|
||||
t.t_c = -t.t_c;
|
||||
t.t_f = -t.t_f;
|
||||
GeoTransRect(&t, &rootBox, &newBox);
|
||||
DBWSetBox(rootDef, &newBox);
|
||||
t.t_c = -t.t_c;
|
||||
t.t_f = -t.t_f;
|
||||
}
|
||||
|
||||
/* Adjust all window viewing positions and redraw */
|
||||
|
||||
WindTranslate(t.t_c, t.t_f);
|
||||
|
||||
/* This is harsh. Might work to change all distance measures */
|
||||
/* in the undo record, but this is simple and direct. */
|
||||
|
||||
UndoFlush();
|
||||
}
|
||||
else
|
||||
SelectTransform(&t);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -153,8 +153,11 @@ CmdSave(w, cmd)
|
|||
DBUpdateStamps();
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
char *fileName;
|
||||
|
||||
if (CmdIllegalChars(cmd->tx_argv[1], "[],", "Cell name"))
|
||||
return;
|
||||
|
||||
cmdSaveCell(locDef, cmd->tx_argv[1], FALSE, TRUE);
|
||||
}
|
||||
else cmdSaveCell(locDef, (char *) NULL, FALSE, TRUE);
|
||||
|
|
@ -842,6 +845,8 @@ CmdSelect(w, cmd)
|
|||
option = SEL_DEFAULT;
|
||||
else
|
||||
{
|
||||
char *fileName;
|
||||
|
||||
option = Lookup(optionArgs[0], cmdSelectOption);
|
||||
if (option < 0 && cmd->tx_argc != 2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "database/database.h"
|
||||
#include "tiles/tile.h"
|
||||
#include "utils/hash.h"
|
||||
#include "utils/malloc.h"
|
||||
#include "windows/windows.h"
|
||||
#include "dbwind/dbwind.h"
|
||||
#include "utils/main.h"
|
||||
|
|
@ -589,6 +590,8 @@ cmdSaveCell(cellDef, newName, noninteractive, tryRename)
|
|||
* place where it was saved.
|
||||
*/
|
||||
{
|
||||
char *fileName = newName;
|
||||
|
||||
/* Eliminate the phony labels added for use by rsim */
|
||||
#ifndef NO_SIM_MODULE
|
||||
SimEraseLabels();
|
||||
|
|
@ -604,41 +607,41 @@ cmdSaveCell(cellDef, newName, noninteractive, tryRename)
|
|||
{
|
||||
if (newName == NULL)
|
||||
TxPrintf("Must specify name for cell %s.\n", UNNAMED);
|
||||
newName = cmdCheckNewName(cellDef, newName, TRUE, noninteractive);
|
||||
if (newName == NULL) return;
|
||||
fileName = cmdCheckNewName(cellDef, newName, TRUE, noninteractive);
|
||||
if (fileName == NULL) return;
|
||||
}
|
||||
else if (newName != NULL)
|
||||
{
|
||||
newName = cmdCheckNewName(cellDef, newName, TRUE, noninteractive);
|
||||
if (newName == NULL) return;
|
||||
fileName = cmdCheckNewName(cellDef, newName, TRUE, noninteractive);
|
||||
if (fileName == NULL) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cellDef->cd_file == NULL)
|
||||
{
|
||||
newName = cmdCheckNewName(cellDef, cellDef->cd_name,
|
||||
fileName = cmdCheckNewName(cellDef, cellDef->cd_name,
|
||||
TRUE, noninteractive);
|
||||
if (newName == NULL) return;
|
||||
if (fileName == NULL) return;
|
||||
}
|
||||
}
|
||||
|
||||
DBUpdateStamps();
|
||||
if (!DBCellWrite(cellDef, newName))
|
||||
if (!DBCellWrite(cellDef, fileName))
|
||||
{
|
||||
TxError("Could not write file. Cell not written.\n");
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!tryRename || (newName == NULL) || (strcmp(cellDef->cd_name, newName) == 0))
|
||||
return;
|
||||
if (!tryRename || (fileName == NULL) || (strcmp(cellDef->cd_name, fileName) == 0))
|
||||
goto cleanup;
|
||||
|
||||
/* Rename the cell */
|
||||
if (!DBCellRenameDef(cellDef, newName))
|
||||
if (!DBCellRenameDef(cellDef, fileName))
|
||||
{
|
||||
/* This should never happen */
|
||||
TxError("Magic error: there is already a cell named \"%s\"\n",
|
||||
newName);
|
||||
return;
|
||||
fileName);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (EditCellUse && (cellDef == EditCellUse->cu_def))
|
||||
|
|
@ -660,6 +663,11 @@ cmdSaveCell(cellDef, newName, noninteractive, tryRename)
|
|||
(void) WindSearch(DBWclientID, (ClientData) NULL, (Rect *) NULL,
|
||||
cmdSaveWindSet, (ClientData) cellDef);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if ((fileName != newName) && (fileName != cellDef->cd_name))
|
||||
freeMagic(fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -694,38 +702,44 @@ cmdCheckNewName(def, newName, tryRename, noninteractive)
|
|||
bool tryRename;
|
||||
bool noninteractive;
|
||||
{
|
||||
static char newname[256];
|
||||
static char *yesno[] = { "no", "yes", 0 };
|
||||
char *filename;
|
||||
char *prompt;
|
||||
char *returnname;
|
||||
int code;
|
||||
FILE *f;
|
||||
|
||||
returnname = newName;
|
||||
|
||||
again:
|
||||
if (newName == NULL)
|
||||
if (returnname == NULL)
|
||||
{
|
||||
if (noninteractive) {
|
||||
TxError("Can't write file named '%s'\n", def->cd_name);
|
||||
return NULL;
|
||||
};
|
||||
TxPrintf("File for cell %s: [hit return to abort save] ", def->cd_name);
|
||||
if (TxGetLine(newname, sizeof newname) == NULL || newname[0] == '\0')
|
||||
returnname = (char *)mallocMagic(1024 * sizeof(char));
|
||||
if (TxGetLine(returnname, sizeof returnname) == NULL || returnname[0] == '\0')
|
||||
{
|
||||
TxPrintf("Cell not saved.\n");
|
||||
freeMagic(returnname);
|
||||
return ((char *) NULL);
|
||||
}
|
||||
if (CmdIllegalChars(newname, "[],", "Cell name"))
|
||||
if (CmdIllegalChars(returnname, "[],", "Cell name"))
|
||||
{
|
||||
freeMagic(returnname);
|
||||
goto again;
|
||||
newName = newname;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove any ".mag" file extension from the name */
|
||||
else if (!strcmp(newName + strlen(newName) - 4, ".mag"))
|
||||
*(newName + strlen(newName) - 4) = '\0';
|
||||
if (!strcmp(returnname + strlen(returnname) - 4, ".mag"))
|
||||
*(returnname + strlen(returnname) - 4) = '\0';
|
||||
|
||||
if (strcmp(newName, def->cd_name) != 0)
|
||||
if (strcmp(returnname, def->cd_name) != 0)
|
||||
{
|
||||
if (f = PaOpen(newName, "r", DBSuffix, ".", (char *) NULL, &filename))
|
||||
if (f = PaOpen(returnname, "r", DBSuffix, ".", (char *) NULL, &filename))
|
||||
{
|
||||
(void) fclose(f);
|
||||
if (noninteractive) {
|
||||
|
|
@ -740,23 +754,24 @@ again:
|
|||
if (code == 0)
|
||||
{
|
||||
/* No -- don't overwrite */
|
||||
newName = NULL;
|
||||
if (returnname != newName) freeMagic(returnname);
|
||||
returnname = NULL;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tryRename && DBCellLookDef(newName) != NULL)
|
||||
if (tryRename && DBCellLookDef(returnname) != NULL)
|
||||
{
|
||||
TxError("Can't rename cell '%s' to '%s' because that cell already exists.\n",
|
||||
def->cd_name, newName);
|
||||
def->cd_name, returnname);
|
||||
if (returnname != newName) freeMagic(returnname);
|
||||
if (noninteractive) return NULL;
|
||||
newName = NULL;
|
||||
returnname = NULL;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
return (newName);
|
||||
return (returnname);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -2083,7 +2083,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;
|
||||
|
|
|
|||
|
|
@ -1361,6 +1361,42 @@ typedef struct LCU1 /* A linked celluse record */
|
|||
struct LCU1 *cu_next; /* Pointer to another linked celluse record */
|
||||
} LinkedCellUse;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBMovePoint ---
|
||||
*
|
||||
* Move a point by a position (origx, origy). Ignore positions which
|
||||
* are marked as (M)INFINITY.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the point was moved (point position was not infinite)
|
||||
*
|
||||
* Side effects:
|
||||
* Point structure pointed to by the first argument is repositioned.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
DBMovePoint(p, origx, origy)
|
||||
Point *p;
|
||||
int origx, origy;
|
||||
{
|
||||
int result = FALSE;
|
||||
if ((p->p_x < (INFINITY - 2)) && (p->p_x > (MINFINITY + 2)))
|
||||
{
|
||||
p->p_x -= origx;
|
||||
result = TRUE;
|
||||
}
|
||||
if ((p->p_y < (INFINITY + 2)) && (p->p_y > (MINFINITY + 2)))
|
||||
{
|
||||
p->p_y -= origy;
|
||||
result = TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1513,6 +1549,14 @@ struct scaleArg {
|
|||
bool modified;
|
||||
};
|
||||
|
||||
struct moveArg {
|
||||
int origx;
|
||||
int origy;
|
||||
int pnum;
|
||||
Plane *ptarget;
|
||||
bool modified;
|
||||
};
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1594,6 +1638,74 @@ dbTileScaleFunc(tile, scvals)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbMovePlane --
|
||||
*
|
||||
* Relocation procedure called on a single plane. Copies paint into the
|
||||
* new plane at a delta position (-origx, -origy)
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
dbMovePlane(oldplane, newplane, pnum, origx, origy)
|
||||
Plane *oldplane, *newplane;
|
||||
int pnum;
|
||||
int origx, origy;
|
||||
{
|
||||
int dbTileMoveFunc(); /* forward declaration */
|
||||
struct moveArg arg;
|
||||
|
||||
arg.origx = origx;
|
||||
arg.origy = origy;
|
||||
arg.ptarget = newplane;
|
||||
arg.pnum = pnum;
|
||||
arg.modified = FALSE;
|
||||
(void) DBSrPaintArea((Tile *) NULL, oldplane, &TiPlaneRect,
|
||||
&DBAllButSpaceBits, dbTileMoveFunc, (ClientData) &arg);
|
||||
|
||||
return arg.modified;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbTileMoveFunc --
|
||||
*
|
||||
* Repositioning procedure called on each tile being copied from one plane
|
||||
* to another. Delta position (-origx, -origy) is stored inside the struct
|
||||
* moveArg before calling.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbTileMoveFunc(tile, mvvals)
|
||||
Tile *tile;
|
||||
struct moveArg *mvvals;
|
||||
{
|
||||
TileType type;
|
||||
Rect targetRect;
|
||||
TileType exact;
|
||||
|
||||
TiToRect(tile, &targetRect);
|
||||
|
||||
mvvals->modified = TRUE;
|
||||
DBMovePoint(&targetRect.r_ll, mvvals->origx, mvvals->origy);
|
||||
DBMovePoint(&targetRect.r_ur, mvvals->origx, mvvals->origy);
|
||||
|
||||
type = TiGetTypeExact(tile);
|
||||
exact = type;
|
||||
if (IsSplit(tile))
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
DBNMPaintPlane(mvvals->ptarget, exact, &targetRect,
|
||||
DBStdPaintTbl(type, mvvals->pnum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1737,14 +1849,6 @@ dbScaleCell(cellDef, scalen, scaled)
|
|||
lu = lu->cu_next;
|
||||
}
|
||||
|
||||
/* Scale the position of all subcell uses. Count all of the cells in the */
|
||||
/* subcell plane, and scale those without reference to the actual cells (so */
|
||||
/* we don't count the cells multiple times). */
|
||||
|
||||
lhead = NULL;
|
||||
(void) DBSrCellPlaneArea(cellDef->cd_cellPlane, &TiPlaneRect,
|
||||
dbCellUseEnumFunc, (ClientData) &lhead);
|
||||
|
||||
/* Scale all of the paint tiles in this cell by creating a new plane */
|
||||
/* and copying all tiles into the new plane at scaled dimensions. */
|
||||
|
||||
|
|
@ -1761,9 +1865,6 @@ dbScaleCell(cellDef, scalen, scaled)
|
|||
cellDef->cd_planes[pNum] = newplane;
|
||||
}
|
||||
|
||||
/* Check consistency of several global pointers */
|
||||
/* WARNING: This list may not be complete! */
|
||||
|
||||
/* Also scale the position of all labels. */
|
||||
/* If labels are the rendered-font type, scale the size as well */
|
||||
|
||||
|
|
@ -1879,3 +1980,150 @@ dbCellUseEnumFunc(cellUse, arg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBMoveCell --
|
||||
*
|
||||
* Reposition a cell to a different origin. This routine is equivalent to
|
||||
* unexpanding all contents of a cell, selecting everything, and issuing a
|
||||
* move command. However, for very large layouts this becomes memory- and
|
||||
* compute- intensive. The process of reorienting an entire layout to a
|
||||
* new position can be done much more efficiently. This routine is
|
||||
* essentially a copy of dbScaleCell() but changes only position and not
|
||||
* scale.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
DBMoveCell(cellDef, origx, origy)
|
||||
CellDef *cellDef; /* Pointer to CellDef to be saved. This def might
|
||||
* be an internal buffer; if so, we ignore it.
|
||||
*/
|
||||
int origx, origy; /* Internal unit coordinates which will become the new origin */
|
||||
{
|
||||
int dbCellTileEnumFunc(), dbCellUseEnumFunc();
|
||||
Label *lab;
|
||||
int pNum;
|
||||
LinkedTile *lhead, *lt;
|
||||
LinkedCellUse *luhead, *lu;
|
||||
Plane *newplane;
|
||||
|
||||
/* Unlike dbScaleCell(), this routine is only run on valid edit defs */
|
||||
|
||||
cellDef->cd_flags |= CDBOXESCHANGED;
|
||||
|
||||
/* Enumerate all unique cell uses, and move their position in the */
|
||||
/* bounding box and transform. */
|
||||
|
||||
luhead = NULL;
|
||||
|
||||
(void) DBCellEnum(cellDef, dbCellUseEnumFunc, (ClientData) &luhead);
|
||||
|
||||
lu = luhead;
|
||||
while (lu != NULL)
|
||||
{
|
||||
CellUse *use;
|
||||
Rect *bbox;
|
||||
|
||||
use = lu->cellUse;
|
||||
bbox = &use->cu_bbox;
|
||||
|
||||
/* TxPrintf("CellUse: BBox is ll (%d, %d), transform [%d %d %d %d %d %d]\n",
|
||||
bbox->r_xbot, bbox->r_ybot,
|
||||
use->cu_transform.t_a, use->cu_transform.t_b, use->cu_transform.t_c,
|
||||
use->cu_transform.t_d, use->cu_transform.t_e, use->cu_transform.t_f); */
|
||||
|
||||
DBMovePoint(&bbox->r_ll, origx, origy);
|
||||
DBMovePoint(&bbox->r_ur, origx, origy);
|
||||
|
||||
bbox = &use->cu_extended;
|
||||
DBMovePoint(&bbox->r_ll, origx, origy);
|
||||
DBMovePoint(&bbox->r_ur, origx, origy);
|
||||
|
||||
use->cu_transform.t_c -= origx;
|
||||
use->cu_transform.t_f -= origy;
|
||||
|
||||
lu = lu->cu_next;
|
||||
}
|
||||
|
||||
/* Free this linked cellUse structure */
|
||||
lu = luhead;
|
||||
while (lu != NULL)
|
||||
{
|
||||
freeMagic((char *)lu);
|
||||
lu = lu->cu_next;
|
||||
}
|
||||
|
||||
/* Move all of the paint tiles in this cell by creating a new plane */
|
||||
/* and copying all tiles into the new plane at the new position. */
|
||||
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
if (cellDef->cd_planes[pNum] == NULL) continue;
|
||||
newplane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(newplane);
|
||||
if (dbMovePlane(cellDef->cd_planes[pNum], newplane, pNum,
|
||||
origx, origy, FALSE))
|
||||
cellDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
|
||||
DBFreePaintPlane(cellDef->cd_planes[pNum]);
|
||||
TiFreePlane(cellDef->cd_planes[pNum]);
|
||||
cellDef->cd_planes[pNum] = newplane;
|
||||
}
|
||||
|
||||
/* Also move the position of all labels. */
|
||||
|
||||
if (cellDef->cd_labels)
|
||||
{
|
||||
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
|
||||
{
|
||||
DBMovePoint(&lab->lab_rect.r_ll, origx, origy);
|
||||
DBMovePoint(&lab->lab_rect.r_ur, origx, origy);
|
||||
|
||||
if (lab->lab_font >= 0)
|
||||
{
|
||||
DBMovePoint(&lab->lab_bbox.r_ll, origx, origy);
|
||||
DBMovePoint(&lab->lab_bbox.r_ur, origx, origy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
donecell:
|
||||
|
||||
/* The cellDef bounding box gets moved to match the new position. */
|
||||
|
||||
DBMovePoint(&cellDef->cd_bbox.r_ll, origx, origy);
|
||||
DBMovePoint(&cellDef->cd_bbox.r_ur, origx, origy);
|
||||
DBMovePoint(&cellDef->cd_extended.r_ll, origx, origy);
|
||||
DBMovePoint(&cellDef->cd_extended.r_ur, origx, origy);
|
||||
|
||||
/* If the cell is an abstract view with a fixed bounding box, then */
|
||||
/* adjust the bounding box property to match the new scale. */
|
||||
|
||||
if ((cellDef->cd_flags & CDFIXEDBBOX) != 0)
|
||||
{
|
||||
Rect r;
|
||||
bool found;
|
||||
char *propval;
|
||||
|
||||
propval = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found);
|
||||
if (found)
|
||||
{
|
||||
if (sscanf(propval, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
{
|
||||
DBMovePoint(&r.r_ll, origx, origy);
|
||||
DBMovePoint(&r.r_ur, origx, origy);
|
||||
|
||||
propval = (char *)mallocMagic(40);
|
||||
sprintf(propval, "%d %d %d %d", r.r_xbot, r.r_ybot,
|
||||
r.r_xtop, r.r_ytop);
|
||||
DBPropPut(cellDef, "FIXED_BBOX", propval);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1133,7 +1132,14 @@ dbReadOpen(cellDef, name, setFileName, errptr)
|
|||
cellDef->cd_flags &= ~CDNOTFOUND;
|
||||
#endif
|
||||
if (setFileName)
|
||||
{
|
||||
/* Remove any ".mag" file extension */
|
||||
char *pptr = strrchr(filename, '.');
|
||||
if (pptr != NULL)
|
||||
if (!strcmp(pptr, DBSuffix)) *pptr = '\0';
|
||||
|
||||
(void) StrDup(&cellDef->cd_file, filename);
|
||||
}
|
||||
cellDef->cd_flags |= CDAVAILABLE;
|
||||
return (f);
|
||||
}
|
||||
|
|
@ -1346,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 */
|
||||
|
|
@ -2715,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, realname);
|
||||
}
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1619,7 +1619,7 @@ esMakePorts(hc, cdata)
|
|||
nn = (EFNodeName *) HashGetValue(he);
|
||||
}
|
||||
|
||||
if (!(nn->efnn_node->efnode_flags & EF_PORT))
|
||||
if (nn->efnn_node && !(nn->efnn_node->efnode_flags & EF_PORT))
|
||||
{
|
||||
nn->efnn_node->efnode_flags |= EF_PORT;
|
||||
nn->efnn_port = -1; // Will be sorted later
|
||||
|
|
|
|||
|
|
@ -1668,7 +1668,7 @@ topVisit(def, doStub)
|
|||
sname = (EFNodeName *) HashGetValue(he);
|
||||
if (sname == NULL) continue;
|
||||
snode = sname->efnn_node;
|
||||
if (!(snode->efnode_flags & EF_PORT)) continue;
|
||||
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
|
||||
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
|
||||
{
|
||||
portorder = nodeName->efnn_port;
|
||||
|
|
@ -1729,7 +1729,7 @@ topVisit(def, doStub)
|
|||
if (sname == NULL) continue; /* Should not happen */
|
||||
snode = sname->efnn_node;
|
||||
|
||||
if (!(snode->efnode_flags & EF_PORT)) continue;
|
||||
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
|
||||
|
||||
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
|
||||
{
|
||||
|
|
@ -1787,7 +1787,7 @@ topVisit(def, doStub)
|
|||
if (sname == NULL) continue;
|
||||
snode = sname->efnn_node;
|
||||
|
||||
if (snode->efnode_flags & EF_SUBS_PORT)
|
||||
if (snode && (snode->efnode_flags & EF_SUBS_PORT))
|
||||
{
|
||||
if (snode->efnode_name->efnn_port < 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -466,6 +466,8 @@ efBuildEquiv(def, nodeName1, nodeName2)
|
|||
if (efWarn)
|
||||
efReadError("Merged nodes %s and %s\n", nodeName1, nodeName2);
|
||||
efNodeMerge(&nn1->efnn_node, &nn2->efnn_node);
|
||||
if (nn1->efnn_port > 0) nn2->efnn_port = nn1->efnn_port;
|
||||
else if (nn2->efnn_port > 0) nn1->efnn_port = nn2->efnn_port;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -626,7 +626,6 @@ closeit:
|
|||
void
|
||||
extExtractStack(stack, doExtract, rootDef)
|
||||
Stack *stack;
|
||||
bool doExtract;
|
||||
CellDef *rootDef;
|
||||
{
|
||||
int fatal = 0, warnings = 0;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -1538,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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -618,6 +618,14 @@ MakeLegalLEFSyntax(text)
|
|||
return rstr;
|
||||
}
|
||||
|
||||
/* Linked list structure for holding PIN PORT geometry areas */
|
||||
|
||||
typedef struct _labelLinkedList {
|
||||
Label *lll_label;
|
||||
Rect lll_area;
|
||||
struct _labelLinkedList *lll_next;
|
||||
} labelLinkedList;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -657,6 +665,7 @@ lefWriteMacro(def, f, scale, hide)
|
|||
char *LEFtext;
|
||||
HashSearch hs;
|
||||
HashEntry *he;
|
||||
labelLinkedList *lll = NULL;
|
||||
|
||||
extern CellDef *SelectDef;
|
||||
|
||||
|
|
@ -666,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;
|
||||
|
||||
|
|
@ -819,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;
|
||||
|
|
@ -959,7 +968,11 @@ lefWriteMacro(def, f, scale, hide)
|
|||
|
||||
if (hide)
|
||||
{
|
||||
SelectChunk(&scx, lab->lab_type, 0, NULL, FALSE);
|
||||
Rect carea;
|
||||
labelLinkedList *newlll;
|
||||
|
||||
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
|
||||
if (GEO_RECTNULL(&carea)) carea = lab->lab_rect;
|
||||
|
||||
/* Note that a sticky label could be placed over multiple */
|
||||
/* tile types, which would cause SelectChunk to fail. So */
|
||||
|
|
@ -967,8 +980,15 @@ lefWriteMacro(def, f, scale, hide)
|
|||
/* SelectDef. */
|
||||
|
||||
pNum = DBPlane(lab->lab_type);
|
||||
DBPaintPlane(SelectDef->cd_planes[pNum], &lab->lab_rect,
|
||||
DBPaintPlane(SelectDef->cd_planes[pNum], &carea,
|
||||
DBStdPaintTbl(lab->lab_type, pNum), (PaintUndoInfo *) NULL);
|
||||
|
||||
/* Remember this area since it's going to get erased */
|
||||
newlll = (labelLinkedList *)mallocMagic(sizeof(labelLinkedList));
|
||||
newlll->lll_label = lab;
|
||||
newlll->lll_area = carea;
|
||||
newlll->lll_next = lll;
|
||||
lll = newlll;
|
||||
}
|
||||
else
|
||||
SelectNet(&scx, lab->lab_type, 0, NULL, FALSE);
|
||||
|
|
@ -1064,6 +1084,7 @@ lefWriteMacro(def, f, scale, hide)
|
|||
/* cell. Otherwise, this routine can block internal pins. */
|
||||
|
||||
Rect layerBound;
|
||||
labelLinkedList *thislll;
|
||||
|
||||
for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++)
|
||||
if (TTMaskHasType(&lmask, ttype))
|
||||
|
|
@ -1080,39 +1101,20 @@ lefWriteMacro(def, f, scale, hide)
|
|||
DBPaint(lc.lefYank, &layerBound, ttype);
|
||||
}
|
||||
|
||||
scx.scx_use = &lefSourceUse;
|
||||
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
|
||||
for (thislll = lll; thislll; thislll = thislll->lll_next)
|
||||
{
|
||||
Rect carea;
|
||||
int lspace;
|
||||
|
||||
labr = lab->lab_rect;
|
||||
lab = thislll->lll_label;
|
||||
|
||||
/* Force label area to be non-degenerate */
|
||||
if (labr.r_xbot >= labr.r_xtop)
|
||||
{
|
||||
labr.r_xbot--;
|
||||
labr.r_xtop++;
|
||||
}
|
||||
if (labr.r_ybot >= labr.r_ytop)
|
||||
{
|
||||
labr.r_ybot--;
|
||||
labr.r_ytop++;
|
||||
}
|
||||
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
{
|
||||
scx.scx_area = labr;
|
||||
SelectClear();
|
||||
SelectChunk(&scx, lab->lab_type, 0, &carea, FALSE);
|
||||
if (GEO_RECTNULL(&carea)) carea = lab->lab_rect;
|
||||
lspace = DRCGetDefaultLayerSpacing(lab->lab_type, lab->lab_type);
|
||||
carea.r_xbot -= lspace;
|
||||
carea.r_ybot -= lspace;
|
||||
carea.r_xtop += lspace;
|
||||
carea.r_ytop += lspace;
|
||||
DBErase(lc.lefYank, &carea, lab->lab_type);
|
||||
}
|
||||
lspace = DRCGetDefaultLayerSpacing(lab->lab_type, lab->lab_type);
|
||||
thislll->lll_area.r_xbot -= lspace;
|
||||
thislll->lll_area.r_ybot -= lspace;
|
||||
thislll->lll_area.r_xtop += lspace;
|
||||
thislll->lll_area.r_ytop += lspace;
|
||||
DBErase(lc.lefYank, &thislll->lll_area, lab->lab_type);
|
||||
|
||||
freeMagic(thislll);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -273,7 +273,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ for i in $@; do
|
|||
esac
|
||||
done
|
||||
#
|
||||
eval /usr/local/lib/magic/tcl/magicdnull -dnull -noconsole -nowrapper $mgargs <<EOF
|
||||
eval /home/tim/cad/lib/magic/tcl/magicdnull -dnull -noconsole -nowrapper $mgargs <<EOF
|
||||
drc off
|
||||
box 0 0 0 0
|
||||
ext2sim $esargs
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ for i in $@; do
|
|||
esac
|
||||
done
|
||||
#
|
||||
eval /usr/local/lib/magic/tcl/magicdnull -dnull -noconsole -nowrapper $mgargs <<EOF
|
||||
eval /home/tim/cad/lib/magic/tcl/magicdnull -dnull -noconsole -nowrapper $mgargs <<EOF
|
||||
drc off
|
||||
box 0 0 0 0
|
||||
ext2spice $esargs
|
||||
|
|
|
|||
|
|
@ -289,6 +289,47 @@ WindScale(scalen, scaled)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* WindTranslate --
|
||||
*
|
||||
* Move the viewing windows by the given delta position. Because
|
||||
* this is done in conjunction with repositioning the geometry
|
||||
* ("move origin" command), we don't preserve the center position
|
||||
* like WindZoom() does. The net effect is that the image in the
|
||||
* window doesn't appear to change.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* All windows will be now view a different portion of the client's area.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
WindTranslate(origx, origy)
|
||||
int origx, origy;
|
||||
{
|
||||
extern void DBMovePoint();
|
||||
MagWindow *w2;
|
||||
Rect newArea;
|
||||
|
||||
for (w2 = windTopWindow; w2 != NULL; w2 = w2->w_nextWindow)
|
||||
{
|
||||
newArea.r_xbot = w2->w_surfaceArea.r_xbot;
|
||||
newArea.r_xtop = w2->w_surfaceArea.r_xtop;
|
||||
newArea.r_ybot = w2->w_surfaceArea.r_ybot;
|
||||
newArea.r_ytop = w2->w_surfaceArea.r_ytop;
|
||||
DBMovePoint(&newArea.r_ll, origx, origy);
|
||||
DBMovePoint(&newArea.r_ur, origx, origy);
|
||||
WindMove(w2, &newArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue